Some checks failed
Deploy Nexus / deploy (push) Failing after 4s
Co-authored-by: Claude (Opus 4.6) <claude@hermes.local> Co-committed-by: Claude (Opus 4.6) <claude@hermes.local>
47 lines
1.1 KiB
JavaScript
47 lines
1.1 KiB
JavaScript
// modules/core/ticker.js — Global Animation Clock
|
|
// Single requestAnimationFrame loop. All modules subscribe here.
|
|
// No module may call requestAnimationFrame directly.
|
|
|
|
import * as THREE from 'three';
|
|
|
|
const _clock = new THREE.Clock();
|
|
const _subscribers = [];
|
|
|
|
let _running = false;
|
|
let _elapsed = 0;
|
|
|
|
/**
|
|
* Subscribe a callback to the animation loop.
|
|
* @param {(elapsed: number, delta: number) => void} fn
|
|
*/
|
|
export function subscribe(fn) {
|
|
_subscribers.push(fn);
|
|
}
|
|
|
|
/**
|
|
* Unsubscribe a callback from the animation loop.
|
|
* @param {(elapsed: number, delta: number) => void} fn
|
|
*/
|
|
export function unsubscribe(fn) {
|
|
const idx = _subscribers.indexOf(fn);
|
|
if (idx !== -1) _subscribers.splice(idx, 1);
|
|
}
|
|
|
|
/** Start the animation loop. Called once by app.js after all modules are init'd. */
|
|
export function start() {
|
|
if (_running) return;
|
|
_running = true;
|
|
_tick();
|
|
}
|
|
|
|
function _tick() {
|
|
if (!_running) return;
|
|
requestAnimationFrame(_tick);
|
|
const delta = _clock.getDelta();
|
|
_elapsed += delta;
|
|
for (const fn of _subscribers) fn(_elapsed, delta);
|
|
}
|
|
|
|
/** Current elapsed time in seconds (read-only). */
|
|
export function elapsed() { return _elapsed; }
|