BONEYARD · part · corridor
Switch
src/30-switch.js · one module, no third-party code
ParametersFactory
How it works
Every play() also dispatches a window event 'boneyard:switch' with detail { dir: 'on' | 'off', slug, dial, flash } so the sound module can clunk; nothing here listens for it. The white-hot line and dot are the room's flash layer (a phosphor-core div inside the tube) brought to full opacity only while the tube is a sliver, so their light is a line, never a frame. The one full-frame flash is the first 34 ms of a switch-off, only when the core grants it (Full, rate-limited by the core to one each half second and here to one a second, because a bright bay arriving is a luminance rise too: measured under WCAG 2.3.1's three a second), and only for a room that was on for flashDwellMs. A room is two nested wrappers around its canvas. The outer carries the 1/z approach scale the core writes each frame (anchored on the vanishing point). This module animates the inner one. Switching off: three keyframe segments on one transform animation, so the browser composites the whole thing without touching the main thread: scale(1, 1) -> scale(1, .004) (the line) -> scale(.004, .004) (the dot) -> translate to the vanishing point at scale 0. A short dot dwell makes the beam read as a physical collapse before depth takes over. Switching on runs the same shape backward while the outer scale eases from the far-frame size to 1, so the small frame on the horizon rushes up, flattens into a bright line, and opens. If that travel reverses, play() reads the live transform before cancelling and uses it as the next animation's first keyframe. Under Still both directions are a 200 ms opacity crossfade. play() resolves true on finish and false if cancelled by a faster scroll.
Provenance
- technique
- the CRT switch-off as compositor-only transforms on a room's wrapper: an accelerating vertical collapse to a white-hot line, a horizontal pinch to a briefly held dot, then a measured recede to the shared vanishing point; switch-on reverses the physical sequence with a small deflection settle in Full
- lineage
- every CRT television's power-off, formalised by 1980s title sequences
- original
- driven by the Web Animations API on the room's inner wrapper (no per-frame JavaScript, no layout, no paint); the recede targets the SAME vanishing point every room shares; one flash frame at most and only in Full, rate-limited by the core to one per bay and never more than two a second; interrupted transitions sample their current compositor transform before reversal, so a fast scroll continues from the visible shape instead of snapping; Still is a 200 ms opacity crossfade
- not
- a shader, a fade-to-black cut, a flicker
- deps
- none · WAAPI (element.animate) · 2026-09
- budget
- 0.0 ms/frame of JavaScript during the transition (compositor animations); measured in docs/BUILD-LOG.md, desktop Chromium, 2026-09-29
- api
- mount(container, params, ctx) -> { play(room, 'on'|'off', opts) -> Promise<boolean>, cancel(room), busy(room), anyBusy(), tick, resize, still, destroy }
- license
- MIT, Desert Data Labs LLC
Budget: 0.0 ms/frame of JavaScript during the transition (compositor animations); measured in docs/BUILD-LOG.md, desktop Chromium, 2026-09-29