How-to2 min read

[demo] How the tiles on this site work

500+ coloured tiles route from noise into lanes and then into a monogram as you scroll. Here is how that works, and how it falls back when there is no GPU.

Last verified

The hero of this site is a field of small tiles. There are 500+ of them, one for each data pipeline I look after, and each has the colour of one of 16 source systems.

One function per tile

Every tile is a pure function of scroll progress. Given a progress between 0 and 1, it returns where the tile is, how it is turned and how big it is:

tileState(tile, progress, time, out)
// 0    to 0.15: drifting noise
// 0.15 to 0.55: routing into its system's lane
// 0.55 to 0.95: leaving the lane for its place in the monogram

Because nothing is stored between frames, scrolling back up simply runs the story backwards.

Where the monogram comes from

The letters are drawn once, off screen, in the display font. The tiles then take evenly spread points from the inked pixels. That happens only after the font has loaded, or the tiles would form the fallback font's shape.

Two renderers, one story

The same function drives two renderers:

  • three.js with WebGPU, which falls back to WebGL2 by itself when WebGPU is missing.
  • Canvas2D, for devices without a usable GPU and for reduced motion, where it draws the finished monogram once.

If a GPU device is lost mid-session, the scene swaps to Canvas2D on a fresh canvas.

Try it

Scroll this block through the screen, or move your pointer over it:

What I would do differently

The first version rotated each tile in the 0 to 1 scene space. On a wide canvas that shears squares into thin dashes, so the rotation now happens in pixels before the tile is placed.