LISSAJOUS

Build note · Type 99 bench scope

How the bench was wired

LISSAJOUS is an XY oscilloscope with no signal generator inside it — you are the signal. Your cursor's horizontal and vertical position are the two channels; the beam plots one against the other on a phosphor screen that holds the light, and the panel measures the frequency ratio and phase of your motion and names the figure you draw.

The concept

An instrument pointed at your hand

Wave 4 is Second Person: the page is inert until you drive it. Here the bench sits dark and still with a resting dot until you move — then it becomes a measuring instrument reading you back. Move slowly in a circle and you trace a clean ellipse; oscillate twice sideways for every rise and you draw a figure-eight; scribble and the panel calls it what it is: noise. It is built for anyone who has ever watched a scope in XY mode and wanted to be the waveform.

Palette · argued from the tube

Phosphor green on scope black

Every colour comes from a real cathode-ray tube, not a mood board. Bright green is reserved for the beam, marks, and rules; small body text uses a softer phosphor-grey ink so nothing bright sits on the busy screen.

Scope black
#07100C
The unlit tube — a green-tinged black, not neutral.
Phosphor
#6FE05A
P31 green — the beam, headings, and every mark.
Graticule
#1E5A3A
The etched 10×8 grid — present but never loud.
Readout amber
#E0B84C
The measured numbers — a second lamp colour, like a real dual-readout scope.

Type

A display face and a lab face

ArchivoDisplay · UI
A grotesque with real presence at heavy weights — the wordmark, headline, and figure name. Set tight and dark for the second-person address.
JetBrains MonoInstrument
Every measured quantity, label, and readout. A monospace makes the tabular numbers line up like a real front panel and never jitters as values change.

Techniques

What draws the glow

The signature is honest phosphor. There is no video and no pre-baked path: sixty times a second the beam eases toward your pointer, its position is pushed into two ring buffers, the whole screen dims a fraction, and only the newest bright segment is painted back additively. Turn up persistence and the fade shrinks, so your loop stays lit longer; leave the mouse and the light decays to the resting dot and the readout drops to No signal.

Iteration log

Three passes, each driving the beam

01 Craft

  • Set a deliberate type scale and reserved bright phosphor for marks only — body copy moved to a #CFE6D6 ink and mute labels lifted to #7C9C88 to clear 4.5:1 on scope black.
  • Rebuilt the graticule to a true 10×8 division grid with brighter centre axes and 0.2-division tick marks, plus corner instrument tags (XY, P31, 1 V/DIV) on the static layer.
  • Tightened the readout panel to tabular-nums so the amber values stop jittering as they update, and gave the CRT a curved-glass vignette and reflection.

02 Depth

  • Enriched the signature: additive layered strokes (soft halo + bright core) and a velocity-scaled head glow, so slow moves lay a clean bright loop and fast moves streak — the built-in "scribble = noise" feel.
  • Added the persistence knob as the one working control — a genuine micro-interaction that changes the phosphor decay rate live.
  • Second-read details: a procedural Lissajous atlas (six figures drawn from the real equations in SVG, with a subtle hover-lift) and a LOCK lamp that lights only when your motion is clean and low-ratio. Credited Bowditch, 1815, in the atlas note.
  • One tasteful micro-interaction: the figure cell throws a single amber glow-pulse the instant your motion locks onto a figure — fired only on the unlocked→locked transition, never repeating.

03 Hardening

  • 375 px: hero stacks, readout reflows to a 2-column grid with the figure cell spanning full width, atlas drops to two columns. Caught the model sub-line shoving the nav off the right edge of the fixed masthead (a false pass for a scroll-width probe) and hid it below 480 px — verified no element crosses the viewport box.
  • Driving the beam in headless Chrome ten times over exposed an intermittent misread — a clean circle occasionally naming itself 5:4 because the frequency came from raw integer crossing-counts that wobble ±1 at the window edges. Rebuilt it to read frequency from the median interval between sub-frame-interpolated crossings, smoothed over time, and biased the ratio fit toward the simplest whole numbers. Ten further runs: a stable 1 : 1 every time.
  • Reduced-motion path: no bloom, no idle breathing; the loop settles the readout to Standing dot then freezes when still, and resumes only on movement. DPR capped at 2, canvases resize, loop pauses on document.hidden. Removed one excess ornament (the redundant in-screen DC tag).

Colophon

Self-contained: one HTML file, inline CSS and JS, canvas 2D, no build step, no raster images, no third-party libraries. Fonts from Google Fonts. Every glow is computed live from your cursor.