aboutsummaryrefslogtreecommitdiff
path: root/src/scene/primitives.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/scene/primitives.ts')
-rw-r--r--src/scene/primitives.ts21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/scene/primitives.ts b/src/scene/primitives.ts
index bce9113..384ea1d 100644
--- a/src/scene/primitives.ts
+++ b/src/scene/primitives.ts
@@ -1,4 +1,6 @@
import * as THREE from 'three';
+import { CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
+import { renderProse } from '../math';
import type { Point } from '../physics/electricField';
export const colours = { positive: '#ff967b', negative: '#73d7ff', field: '#91e2cb', gold: '#f5d58b', muted: '#8294a8' };
@@ -25,7 +27,20 @@ export function arrow(group: THREE.Group, origin: Point, direction: Point, lengt
if (dir.lengthSq() < 1e-24) return;
group.add(new THREE.ArrowHelper(dir.normalize(), vector(origin), length, colour, Math.min(0.16, length * 0.3), Math.min(0.1, length * 0.2)));
}
-export function label(group: THREE.Group, text: string, position: Point, colour: string = '#dbe7f0', width = 2): THREE.Sprite {
+export function label(group: THREE.Group, text: string, position: Point, colour: string = '#dbe7f0', width = 2, minViewportWidth = 0): THREE.Sprite | CSS2DObject {
+ if (text.includes('$')) {
+ const element = document.createElement('div');
+ element.className = 'scene-math-label';
+ element.style.color = colour;
+ renderProse(element, text);
+ const annotation = new CSS2DObject(element);
+ annotation.position.copy(vector(position));
+ annotation.onBeforeRender = () => {
+ element.style.visibility = (element.parentElement?.clientWidth ?? Infinity) < minViewportWidth ? 'hidden' : 'visible';
+ };
+ group.add(annotation);
+ return annotation;
+ }
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d')!;
context.font = '500 44px system-ui, sans-serif';
@@ -52,7 +67,9 @@ export function label(group: THREE.Group, text: string, position: Point, colour:
if (!(camera instanceof THREE.PerspectiveCamera)) return;
sprite.getWorldPosition(cameraPosition).applyMatrix4(camera.matrixWorldInverse);
renderer.getSize(viewportSize);
- const worldHeight = 2 * Math.abs(cameraPosition.z) * Math.tan(THREE.MathUtils.degToRad(camera.getEffectiveFOV()) / 2) * screenHeight / Math.max(1, viewportSize.y);
+ sprite.material.opacity = viewportSize.x < minViewportWidth ? 0 : 1;
+ const responsiveHeight = viewportSize.x < 600 ? screenHeight * 0.78 : screenHeight;
+ const worldHeight = 2 * Math.abs(cameraPosition.z) * Math.tan(THREE.MathUtils.degToRad(camera.getEffectiveFOV()) / 2) * responsiveHeight / Math.max(1, viewportSize.y);
sprite.scale.set(worldHeight * aspect, worldHeight, 1);
sprite.updateMatrixWorld();
};