RESONANCE ← Back to site
Build guide · Site 14 of 25

A studio that sounds before it speaks.

RESONANCE is one of 25 sites designed and built by Formwork to demonstrate web craft, motion, and taste. This one is about listening — the hero is a colour field that breathes to sound the browser makes itself. Here is exactly how it works.

The idea

The brief was "deep, warm, sonic." Instead of a video loop or a static gradient, the hero is a living mesh-gradient — five soft colour blobs drifting through a teal-black field — that pulses to audio. Because browsers rightly block autoplay, the page can't assume sound. So it runs in two modes: silent-but-alive by default, and reactive once you press play. Same visual code path, two spectrum sources.

The stack

The signature technique: sound you can see

Press play and the site builds an ambient pad from scratch — a detuned Cmaj7 chord (C, E, G, B over a low C) where every note is two slightly-detuned oscillators, plus slow LFOs on the master gain and filter so the chord breathes and evolves. It routes through an AnalyserNode, and every frame we read the spectrum and let it move the blobs:

// one shared buffer — the analyser OR a synthetic sine fills it
if (!audio.sample()) { synthSpectrum(t); synthWave(t); }

// each blob grows and brightens with its own frequency band
const band = bandEnergy(b.band[0], b.band[1]);
const r = min * (b.base + band * b.react + energy * 0.08);
const g = ctx.createRadialGradient(px, py, 0, px, py, r);
g.addColorStop(0, `rgba(${c},${a})`);
ctx.globalCompositeOperation = 'lighter';   // blobs add into a glow

Before any click, synthSpectrum() fabricates a gentle, moving spectrum from a few sine LFOs, so the hero is never dead — it just happens to be silent. Muting fades the pad out and drops straight back to that synthetic source. The two modes are indistinguishable to the render loop.

Details that matter

Ship it on GitHub Pages

The whole site is static, so hosting is three commands:

git init -b main && git add -A && git commit -m "ship"
gh repo create formwork-resonance --public --source=. --push
gh api --method POST /repos/OWNER/formwork-resonance/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 recipe: two canvases, a chord the browser plays to itself, and a synthetic understudy so the page is alive even in silence. The other 24 sites each swap the central technique — shaders, particles, kinetic type — but the discipline is the same.