ALGORITHM ← Back to site
Build guide · Site 12 of 25

A studio that draws itself, from one number.

ALGORITHM is one of 25 sites designed and built by Formwork to demonstrate web design, motion, and generative craft. Here is exactly how this one was made — a hero that repaints on every visit, yet stays perfectly reproducible.

The idea

The brief was "code-drawn art that renders unique every visit." So the site's entire identity is a seed: a single 32-bit integer that fixes the palette, the noise field, and every mark on screen. Reload with the same seed and you get the same drawing to the pixel; change one digit and the whole composition reorganises. The seed rides in the URL, so a visit is a shareable original.

The stack

The signature technique: a seeded flow field

Each frame, every particle reads the noise field beneath it, turns that value into an angle, steps forward, and draws the tiny segment it just travelled. A near-transparent black rectangle painted over the canvas each frame lets old trails fade, so the field breathes like ink in water. This is the actual loop that runs the hero:

function advance(fadeOn) {
  if (fadeOn) { ctx.fillStyle = 'rgba(12,13,15,0.024)'; ctx.fillRect(0,0,w,h); }
  ctx.lineWidth = 1.15; ctx.lineCap = 'round';
  for (let i = 0; i < particles.length; i++) {
    const pt = particles[i];
    const ang = fbm(noise, pt.x*cfg.scale, pt.y*cfg.scale) * TAU * cfg.turns;
    const nx = pt.x + Math.cos(ang)*cfg.speed;
    const ny = pt.y + Math.sin(ang)*cfg.speed;
    ctx.strokeStyle = pt.col;
    ctx.beginPath(); ctx.moveTo(pt.x, pt.y); ctx.lineTo(nx, ny); ctx.stroke();
    pt.x = nx; pt.y = ny; pt.life++;
    if (pt.life > pt.max || nx < -12 || nx > w+12) spawn(Math.random, pt);
  }
}

The noise function is a seeded Perlin generator (its permutation table is shuffled by the same PRNG), wrapped in four octaves of fractal Brownian motion so the field has both broad currents and fine detail. Because the field, palette, and initial particle positions are all drawn from the seed in a fixed order, the opening frame is identical every time — after that the particles wander freely.

Details that matter

Ship it on GitHub Pages

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-algorithm --public --source=. --push
gh api --method POST /repos/OWNER/formwork-algorithm/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: one PRNG, one noise field, a canvas, and strong type. The other 24 sites each swap the central technique — shaders, kinetic type, 3D — but the discipline is the same.