STRATA. ← Back to the exhibition

The Guide  ·  A room behind the gallery

How a seed becomes a wall.

Everything hanging in STRATA is procedure, not pigment. This room explains the five procedures in plain language, with the actual arithmetic on display. Nothing is hidden; the whole gallery is one HTML file you can read.

Working model · No. / ∞

The concept

01

STRATA is a fictional gallery representing five fictional algorithmic artists. The conceit: instead of shipping images, the gallery ships five seeded algorithms, and your browser performs each one the moment you arrive. Every visit hangs a new show; every seed number on a label plate is a complete, reproducible provenance.

Aesthetically it is the light counterpoint in a showcase full of dark sites — warm gallery minimalism in the school of Kettle's Yard and small Scandinavian kunsthalles: off-white walls, ink text, generous margins, and the artworks as the only real color. Typography does the curating: Syne for display, a quiet grotesque for the label plates, small caps and tabular numbers doing the museum-label work.

The techniques

02

Seeds — mulberry32, the whole gallery's honesty

All five works draw their randomness from mulberry32, a tiny seeded pseudo-random generator. Given the same five-digit seed, it emits exactly the same stream of numbers — which is why a shared link reproduces a hanging stroke for stroke. Math.random() is only used once: to pick your seeds when you arrive without any.

function mulberry32(seed){
  let a = seed >>> 0;
  return () => {
    a |= 0; a = a + 0x6D2B79F5 | 0;
    let t = Math.imul(a ^ a >>> 15, 1 | a);
    t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
    return ((t ^ t >>> 14) >>> 0) / 4294967296;
  };
}

Adhami — sediment bands with flow distortion

Slow Sediment IV stacks 13–19 horizontal boundaries, each displaced by three seeded sine harmonics plus a band of value noise. A large-scale "flow" term — two slow sines scaled by sin(depth · π) — makes the middle strata swell and pinch while the outer edges stay calm. Bands are filled with vertical gradients, then laminae (thin inner lines) and grain are laid on top so it reads as material, not vector.

y  = h * band / n;                      // resting depth
y += amp * Math.sin(x/w * TAU * k + ph); // x3 harmonics
y += Math.sin(band/n * Math.PI) * flowAmp
   * (Math.sin(x/w*TAU*ka + p1) + 0.6*Math.sin(x/w*TAU*kb + p2));
y += (fbm(x * 0.008, band * 5.7) - 0.5) * (h/n) * 0.9;

Okabe — flow-field particle walks

Wind Ledger 27 drops ~1,500 walkers onto the paper. At every step, a walker samples a seeded value-noise field, converts the sample to an angle, and takes a short step in that direction. Line weight follows rand()2.4 so most strokes are hairlines and a few are heavy — the distribution is the composition.

for (let s = 0; s < steps; s++){
  const a = fbm(x * scale, y * scale) * TAU * turns + rotation;
  x += Math.cos(a) * 2.4;
  y += Math.sin(a) * 2.4;
  ctx.lineTo(x, y);
}

Solberg — greedy circle packing

The Politeness of Circles throws ~2,600 darts at the canvas. Each dart measures its distance to every existing circle and to the walls, and becomes a circle exactly as large as politeness allows — or is discarded. Drawing large-to-small, with a style roll per circle (flat fill, ring, concentric rings, filled-with-dot), turns pure geometry into a print.

let rmax = Math.min(x - m, w - m - x, y - m, h - m - y, maxR);
for (const c of circles){
  const d = Math.hypot(x - c.x, y - c.y) - c.r - gap;
  if (d < minR) { rmax = -1; break; }  // too rude, discard
  if (d < rmax) rmax = d;              // grow only this far
}
if (rmax >= minR) circles.push({ x, y, r: rmax });

Riera — recursive subdivision

Partition Study 9 splits the canvas into two rooms with a gutter between them, then splits the rooms, and so on — stopping at depth 5, at minimum size, or by a 20% coin flip so the composition keeps a few large fields. Leaves take colors from a weighted palette (mostly paper tones, occasionally terracotta, ochre, indigo, ink) and roll for a detail: hatching, a circle, a corner arc, a double rule.

function split(x, y, w, h, depth){
  if (depth > 5 || tooSmall || (depth >= 2 && R.chance(0.2)))
    return leaves.push({ x, y, w, h });
  const t = R.r(0.38, 0.62);          // never split dead-centre
  // carve a gutter, recurse into both halves…
}

Keïta — decaying particle trails

Falling Ledger is the one dark room in the show. ~1,400 particles orbit a slightly off-centre point; each step the angle advances, the radius decays by ~0.3%, and value noise wobbles the orbit. Trails are drawn at 4–10% opacity with globalCompositeOperation = 'lighter', so where paths agree, light accumulates — the image is literally a histogram of consensus.

ctx.globalCompositeOperation = 'lighter';
for (let s = 0; s < steps; s++){
  a += spin;  r *= decay;
  const wob = (fbm(Math.cos(a)*1.7 + 7, Math.sin(a)*1.7 + p*0.13) - 0.5) * r * 0.16;
  ctx.lineTo(cx + Math.cos(a)*(r + wob), cy + Math.sin(a)*(r + wob)*ecc);
}

The room itself — crossfades, DPR, lifted frames

Pressing Regenerate snapshots the old canvas into a ghost <canvas> layered on top, renders the new seed underneath, then fades the ghost out — a 700ms crossfade with no double-rendering. Canvases render at devicePixelRatio (capped at 2) and re-render on resize, so the work stays crisp on any screen. The "lifted frame" hover is two layered box-shadows animated on a single spring-like cubic-bezier — the frame rises, the shadow falls behind it.

const ghost = document.createElement('canvas');
ghost.getContext('2d').drawImage(oldCanvas, 0, 0);
wrap.appendChild(ghost);          // old art on top
piece.seed = randSeed(); render(piece);   // new art below
requestAnimationFrame(() => ghost.style.opacity = '0');

How it was made

03

STRATA was built by Claude (Fable 5) writing vanilla HTML, CSS and JavaScript by hand — no frameworks, no build step, no canvas libraries. The five algorithms, the seeded PRNG, the value-noise implementation and the gallery chrome live in a single script tag on the index page. It is one of 25 wildly different demo sites in the Fable Showcase, an experiment in how far hand-written, dependency-free web design can go.

Steal this

04