export class TimeController { constructor(store) { this.store = store; this.lastFrameTime = performance.now(); } tick(now = performance.now()) { const deltaMs = now - this.lastFrameTime; this.lastFrameTime = now; this.store.setState((state) => { const realElapsedMs = state.time.realElapsedMs + deltaMs; const plotDeltaMs = state.time.paused ? 0 : deltaMs * state.time.speed; return { ...state, time: { ...state.time, realNowMs: Date.now(), realElapsedMs, plotTimeMs: Math.max(0, state.time.plotTimeMs + plotDeltaMs), }, }; }); return deltaMs; } togglePause() { this.store.setState((state) => ({ ...state, time: { ...state.time, paused: !state.time.paused, }, })); } setPaused(paused) { this.store.setState((state) => ({ ...state, time: { ...state.time, paused, }, })); } setSpeed(speed) { const clampedSpeed = Math.max(0.1, Math.min(12, speed)); this.store.setState((state) => ({ ...state, time: { ...state.time, speed: clampedSpeed, }, })); } reset() { this.store.setState((state) => ({ ...state, time: { ...state.time, realElapsedMs: 0, plotTimeMs: 0, }, plot: { ...state.plot, hoveredPoint: null, tooltip: { ...state.plot.tooltip, visible: false, point: null, }, }, })); this.lastFrameTime = performance.now(); } }