β 10 Β· PROCESS GUIDE Β· WAVE 2 β THE DUEL
One HTML file, no photographs, no libraries. Everything on the site β the enlarger, the wash line, the rain in the window β is drawn as SVG and racked through a computed plane of focus. This page is the negative sleeve: the brief, the trick, and what four hostile passes found.
Three full-viewport SVG scenes hang at different depths β the wash line at 0.45 m, the enlarger at 1.2 m, the monsoon window at infinity. One value, focus β [0,1], drives everything: per-plane blur grows with the square of the distance error, scale breathes Β±4.5%, captions only sharpen when their plane is within the depth of field, the brass ring rotates, the distance scale slides, and the contact sheet highlights whichever exposure you are nearest to.
The afterimage is the honest part. Every plane is mounted twice β a live print and a ghost. The ghost chases focus at less than half speed, tinted toward safelight red, its opacity proportional to how far it lags. Rack hard and you drag a red echo through the room; hold still and the room forgives you. This is the loop, verbatim from the source:
focus = RM ? target : lerp(focus, target, Math.min(1, dt*5));
ghost = lerp(ghost, focus, Math.min(1, dt*2.1)); // the afterimage lags
for (const p of planes) {
const err = Math.abs(focus - p.d);
const blur = Math.min(17, err*err*38 + err*3.5); // optics: errorΒ², not error
p.m.style.filter = blur > .25 ? `blur(${blur.toFixed(2)}px)` : "none";
...
const gerr = Math.abs(ghost - p.d);
p.g.style.filter = `blur(...) sepia(.6) hue-rotate(-28deg) saturate(2.4)`;
p.g.style.opacity = Math.min(.55, Math.abs(focus - ghost)*5);
}
Supporting cast, all derived from the same state: film grain regenerated on a 144px canvas tile every 90 ms whose opacity breathes and thickens with rack velocity; an idle drift that keeps the room breathing at Β±0.045 focus after six seconds of stillness; a safelight toggle that relights the entire page through a multiply overlay β with a real lamp-startup stutter; and one secret: hold the ring at infinity for a few seconds and the monsoon steps aside.
Upgrade: safelight mode went page-wide β a multiply overlay relights every section red, and the contact sheet and wash line re-tint under it.
Upgrade: the safelight now switches on like a real lamp β a six-step startup stutter before it holds, page-wide.
Upgrade: film-edge marginalia β faint vertical darkroom notation (ILFORD HP5 PLUS Β· SAFETY FILM, D-76 Β· 1+1 Β· 20Β°C, FIX 5:00 Β· WASH 20:00) running down the left margin of each section past 1280px, the way edge print runs down a negative.
Upgrade: the afterimage now lives on the instrument too β rack the ring and the distance scale drops fading red ghost ticks where focus just was, so the tool demonstrates the concept the room is named for.