diff options
| author | LalleSX | 2026-10-24 14:58:21 +0200 |
|---|---|---|
| committer | LalleSX | 2026-10-24 14:58:21 +0200 |
| commit | 73b09270c54acab810c10a80bed1d77c1a7bb2ab (patch) | |
| tree | e5bae1180c9a76345cc7779a24988875542d2dd9 /src/scene/lab.ts | |
| parent | Add tests for math rendering and interactive scenes; update navigation and viewport handling (diff) | |
| download | 3D-Electrophysics-main.tar.gz 3D-Electrophysics-main.zip | |
Diffstat (limited to 'src/scene/lab.ts')
| -rw-r--r-- | src/scene/lab.ts | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/scene/lab.ts b/src/scene/lab.ts index 782f300..e00c234 100644 --- a/src/scene/lab.ts +++ b/src/scene/lab.ts @@ -2,6 +2,7 @@ import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; import { CSS2DRenderer } from 'three/addons/renderers/CSS2DRenderer.js'; import type { ExperimentId, Parameters } from '../experiments'; +import { onLanguageChange, t } from '../i18n'; import { buildExperiment, type Animate } from './experiments'; import { disposeGroup } from './primitives'; @@ -13,12 +14,13 @@ export function createLab(viewport: HTMLElement) { const error = document.createElement('div'); error.className = 'webgl-error'; error.setAttribute('role', 'alert'); - error.textContent = 'WebGL could not start. Enable browser hardware acceleration and reload to see the 3D scenes. Lessons, controls and measurements still work.'; + error.textContent = t('webglStart'); viewport.append(error); - return { update: () => {}, resetCamera: (_id?: ExperimentId) => {}, setPaused: () => {}, dispose: () => {} }; + const stop = onLanguageChange(() => { error.textContent = t('webglStart'); }); + return { update: () => {}, resetCamera: (_id?: ExperimentId) => {}, setPaused: () => {}, dispose: () => stop() }; } renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); - renderer.domElement.setAttribute('aria-label', '3D experiment: drag to orbit, scroll to zoom, right-drag to pan'); + renderer.domElement.setAttribute('aria-label', t('canvas')); renderer.domElement.setAttribute('tabindex', '0'); viewport.append(renderer.domElement); const labels = new CSS2DRenderer(); @@ -55,6 +57,11 @@ export function createLab(viewport: HTMLElement) { let paused = window.matchMedia('(prefers-reduced-motion: reduce)').matches; let lastTime = 0; let pending: { id: ExperimentId; parameters: Parameters } | undefined; + let lostWarning: HTMLElement | undefined; + const stopLanguage = onLanguageChange(() => { + renderer.domElement.setAttribute('aria-label', t('canvas')); + if (lostWarning) lostWarning.textContent = t('webglLost'); + }); function update(id: ExperimentId, parameters: Parameters) { // Coalesce range events to one rebuild per animation frame. pending = { id, parameters: { ...parameters } }; @@ -78,7 +85,8 @@ export function createLab(viewport: HTMLElement) { const warning = document.createElement('p'); warning.setAttribute('role', 'alert'); warning.className = 'webgl-error'; - warning.textContent = 'WebGL context lost. Reload to restore the 3D view. Numeric experiments still work.'; + warning.textContent = t('webglLost'); + lostWarning = warning; viewport.append(warning); } }); @@ -103,6 +111,7 @@ export function createLab(viewport: HTMLElement) { resetCamera, setPaused: (value: boolean) => { paused = value; }, dispose: () => { + stopLanguage(); renderer.setAnimationLoop(null); observer.disconnect(); controls.dispose(); |