11Object 11 · Displays & signs
Phosphor Scope
A cathode-ray tube behind smoked glass. The beam leaves light behind it: a radar sweep lights your contacts and they fade, a trace glows where the signal lingers. Real afterglow, not a blur.
- Version
- 0.1.0
- Size
- 13.6 KB gzipped
- Access
- With a Pass
- Needs
- phosphor-scope.mjs + phosphor-scope.css
- Tests
- 6 tests · 11 states
Use it
A live display for software that watches something. A radar of services, regions or agents in the field (each contact painted and labelled as the sweep passes); an oscilloscope for a health check's pulse, a service's load, or any stream you push to it; a Lissajous figure for a hero or a loading screen; a status or a 404 written by the beam: SIGNAL LOST, NO CARRIER, DEPLOYING.
Copy the phosphor-scope folder from its package next to your page, link its stylesheet and construct it on an element. Every option has a default; the lab’s Code tab writes the same example at any settings, and for React, Vue, Svelte or a custom element (Using a framework).
<link rel="stylesheet" href="phosphor-scope/phosphor-scope.css">
<div id="phosphor-scope" style="width: min(88vw, 520px)"></div>
<script type="module">
import PhosphorScope from './phosphor-scope/phosphor-scope.mjs';
const phosphorScope = new PhosphorScope(document.getElementById('phosphor-scope'), {
mode: 'radar',
phosphor: 'p1',
persistence: 1,
});
// phosphorScope.update({ … }); change any option in place
// phosphorScope.destroy(); and take it away again
</script>Options
| Option | Type | Default | What it does |
|---|---|---|---|
| mode | radar · scope · xy · text | 'radar' | A radar that lights its contacts, a scope trace, a Lissajous figure, or words drawn by the beam. |
| phosphor | p1 · p3 · p7 | 'p1' | P1 green, P3 amber, or P7: a blue-white flash that leaves a yellow-green glow. |
| persistence | number, 0.2 to 4 | 1 | How long the light stays after the beam has gone. |
| intensity | number, 0.2 to 1.4 | 0.8 | Intensity |
| focus | number, 0 to 1 | 0.55 | Soft to sharp: the width of the beam. |
| sweep | number, 2 to 30 | 10 | Radar only. |
| contacts | number, 0 to 5 | 5 | Radar only: sample services, each labelled by the beam as it is painted. |
| signal | sine · square · saw · pulse · load | 'pulse' | Scope only: a health-check pulse, a service load, or a test waveform. In code, push() draws your own. |
| timebase | number, 0.5 to 6 | 2 | Scope only. |
| ratio | 1:1 · 1:2 · 2:3 · 3:2 · 3:4 · 5:4 | '3:2' | Lissajous only. |
| text | text | 'SIGNAL LOST' | Text only. A new line with /. |
| on | boolean | true | Power |
| finish | auto · aluminium · graphite | 'auto' | Auto follows the page. |
Methods
new PhosphorScope(element, options)- Builds it inside the element with these options.
update(opts = {})- Change options in place.
setTargets(targets)- Radar: replace the contacts.
push(...values)- Scope: feed samples (−1 … 1) for
signal: 'stream'; they are drawn as they arrive. setText(text)- Text: write something new on the screen.
power(on)destroy()- Stops it and cleans up after it.
States
- RadarThe sweep turns at the set rate; its painting edge flashes and leaves the slow afterglow behind it over ground clutter; each contact flares when the sweep crosses its bearing, its label written beside it by the beam, and fades until the next pass.
- ScopeThe trace runs across the graticule over the timebase; it glows brighter where the signal is slow and fainter where it races; the retrace is dark. With signal 'stream', push() draws your samples as they arrive.
- LissajousA figure of the set ratio, its phase drifting so it slowly turns; the moving spot is the brightest point.
- TextThe words are redrawn by the beam every frame with a hair of jitter; a new line with a newline.
- PhosphorsP1 green; P3 amber; P7 flashes blue-white and leaves a yellow-green glow that lasts seconds. Persistence scales every decay.
- AluminiumA bead-blasted aluminium plate with a machined ring and four slotted screws; the glass stays smoked.
- GraphiteA soft-touch black plate, the ring and screws in dark steel; the tube is the same.
- Offpower(false): the screen goes dark, the plate's lamp goes out, no frame is requested.
- Off screen or hiddenNo frame runs; a returning tab advances one clamped step, so nothing flashes.
- Reduced motionOne still frame, a long exposure of the scene (a full radar turn, a timebase of trace), and no frames after it.
- No WebGL2The same scene drawn once on a 2D canvas with a soft glow.
How it works
Made of: Phosphor persistence buffer, Two decay phosphor, Gaussian beam segments, Dwell weighted energy, Radar sweep fan, Ground clutter speckle, Vector stroke font, Mip chain halo, Barrel curve, Room fixed glass, Sleeping loop, Long exposure still.
Original. Three WebGL2 passes on a texture capped at 768 px: decay (per-channel exp(-dt/τ)), beam (additive gaussian quads), show (barrel, tone map, mip-chain halo, vignette). The plate, ring, graticule and glass are CSS and SVG, lit by the room's lamp, never by the beam.