Files
the-nexus/modules/core/ticker.js
Perplexity Computer 675b61d65e
All checks were successful
CI / validate (pull_request) Successful in 14s
CI / auto-merge (pull_request) Successful in 0s
refactor: modularize app.js into ES module architecture
Split the monolithic 5393-line app.js into 32 focused ES modules under
modules/ with a thin ~330-line orchestrator. No bundler required — runs
in-browser via import maps.

Module structure:
  core/     — scene, ticker, state, theme, audio
  data/     — gitea, weather, bitcoin, loaders
  terrain/  — stars, clouds, island
  effects/  — matrix-rain, energy-beam, lightning, shockwave, rune-ring, gravity-zones
  panels/   — heatmap, sigil, sovereignty, dual-brain, batcave, earth, agent-board, lora-panel
  portals/  — portal-system, commit-banners
  narrative/ — bookshelves, oath, chat
  utils/    — perlin

All files pass node --check. No new dependencies.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 18:12:53 +00:00

54 lines
1.2 KiB
JavaScript

// modules/core/ticker.js — Single animation clock
// Every module subscribes here instead of calling requestAnimationFrame directly.
const subscribers = [];
let running = false;
let _renderer, _scene, _camera, _composer;
export function subscribe(fn) {
if (!subscribers.includes(fn)) subscribers.push(fn);
}
export function unsubscribe(fn) {
const i = subscribers.indexOf(fn);
if (i >= 0) subscribers.splice(i, 1);
}
export function setRenderTarget(renderer, scene, camera, composer) {
_renderer = renderer;
_scene = scene;
_camera = camera;
_composer = composer;
}
export function start() {
if (running) return;
running = true;
let lastTime = performance.now();
function tick() {
if (!running) return;
requestAnimationFrame(tick);
const now = performance.now();
const elapsed = now / 1000;
const delta = (now - lastTime) / 1000;
lastTime = now;
for (const fn of subscribers) {
fn(elapsed, delta);
}
if (_composer) {
_composer.render();
} else if (_renderer && _scene && _camera) {
_renderer.render(_scene, _camera);
}
}
tick();
}
export function stop() {
running = false;
}