REVOLVER is one of 25 sites designed and built by Formwork to show off web design, motion, and sound. Here's exactly how the turntable was made — and how you can build the same.
The brief was a tactile, warm-neon record shop. So the hero is a turntable: a vinyl record
drawn in pure CSS & SVG, a tonearm that swings onto the groove, and a play button that starts a
generative loop synthesised live in the browser. There are no audio files. Every note,
kick and hat is oscillators and gain envelopes, and the ring around the record is that same audio,
read back through an AnalyserNode and drawn as a circular waveform.
repeating-radial-gradient grooves, a conic sheen, and an SVG label with textPath lettering.AnalyserNode's time-domain data mapped onto a circle, rendered on a <canvas>.Sound is scheduled with a look-ahead clock: a timer wakes every 25 ms and queues any notes due in the next tenth of a second against the audio clock, so timing never drifts even if the main thread stutters. The same master bus feeds an analyser, and each frame the waveform is wrapped around the record:
// queue 16th-notes a little ahead of the audio clock
while (nextT < ctx.currentTime + 0.12) {
scheduleStep(step, nextT);
nextT += (60 / tempo) / 4;
step = (step + 1) % 16;
}
// read the live signal and bend it around a circle
analyser.getByteTimeDomainData(time);
for (let i = 0; i <= N; i++) {
const a = (i / N) * TAU - Math.PI / 2;
const v = (time[(i / N * time.length) | 0] - 128) / 128;
const r = base + v * R * 0.11; // waveform → radius
ctx.lineTo(cx + Math.cos(a) * r, cy + Math.sin(a) * r);
}
Picking a different record in the crate retunes the running engine in place — new root note, scale,
waveform and tempo — with setTargetAtTime glides so the change is smooth, never a click.
AudioContext is created inside the click handler, and feature-detected — if the browser has no Web Audio, the deck still spins and a note explains why.Every site here is static, so hosting is three commands:
git init -b main && git add -A && git commit -m "ship"
gh repo create formwork-revolver --public --source=. --push
gh api --method POST /repos/OWNER/formwork-revolver/pages \
-f 'source[branch]=main' -f 'source[path]=/'
Use relative paths (./main.js, not /main.js) because project
Pages live under /repo-name/. Add an empty .nojekyll file so every asset serves verbatim.
That's the whole recipe: a record built from gradients, a groove built from oscillators, and one analyser tying picture to sound. The other 24 sites each swap the central technique — but the discipline is the same.