Visualizations
032 / 500

032 · Math

Voronoi Mosaic

Drifting seeds divide the plane into a living stained-glass mosaic.

Every point on the canvas belongs to whichever seed is closest to it, and those regions are Voronoi cells. Seeds drift and bounce, and every frame each pixel of a low resolution buffer finds its nearest and second nearest seed. Those two give the exact distance to the cell border, which draws the dark lead between panes and a beveled, lit edge on each one, like stained glass.

Try it. Click to add a seed. Move the pointer to drag a seed that follows you.

  • Voronoi diagrams
  • Nearest neighbor search
  • Distance-field shading

View the source · one module, plus a small shared runtime for sizing, the animation loop and input

Build your own

Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.

Build an animated stained-glass Voronoi mosaic with JavaScript and the HTML canvas element. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.

Start simple:
- Make a canvas that fills the window and resizes with it.
- Scatter about 40 seeds at random positions, each with a slow random velocity and a rich jewel-tone color (ruby, sapphire, emerald, amber, violet). Bounce them off the edges.
- Each frame, render into a small offscreen canvas about 300 pixels wide using ImageData. For every pixel, loop over all seeds and find the nearest and the second nearest by squared distance. Color the pixel with the nearest seed's color. Then drawImage the small canvas scaled up to fill the window.
- Draw dark lead lines between cells: the exact distance from a pixel to the border between its two nearest seeds A and B is (dB² - dA²) / (2 * |A - B|). If that is under about 1.5 pixels, paint the pixel near-black instead.

Once that works, make it beautiful:
- Bevel each pane: within about 8 pixels of the border, brighten pixels whose border faces an imaginary light in the top left and darken the opposite side, using the direction from seed B to seed A.
- Make each pane slightly brighter toward its seed, and let a soft patch of "sunlight" drift across the window.
- Click to add a seed, and let a golden pane follow the pointer.
- If it runs slowly, test only the seeds that can matter for each 8x8 block of pixels instead of every seed for every pixel.

Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as Lloyd relaxation for even cells, jump flooding for thousands of seeds, or sampling pane colors from a photo.
PreviousRace Condition RailwayThreads as trains, locks as single-line tokens: deadlock and data races you can crash. NextFloral OrnamentScrolls, acanthus leaves and flowers grow to fill any frame, like an engraver's panel.

Related visualizations

  • Roman MosaicGenerative art Thousands of tesserae laid in rows that follow every outline, as a Roman mosaicist would.
  • Basalt ColumnsNature Cooling lava cracks into columns that drift toward hexagons, on an isometric causeway.
  • One Line PortraitType and image Thousands of stipple dots become one unbroken pen line, untangled by 2-opt.
  • ReLU Stained GlassMachine learning A ReLU network's exact linear regions, drawn as a stained glass window.
  • Wythoff Kaleidoscope3D One draggable seed in a mirror triangle generates every convex uniform polyhedron.
  • Op ArtGenerative art Riley and Vasarely style compositions that ripple, bulge and vibrate.
  • Hyperbolic TilingMath An endless koi garden of {p,q} ponds tiling the Poincare disk, with fish circling.
  • Penrose PentagridMath Five grids of parallel lines dualize into a living Penrose tiling of stained glass.
  • Zen GardenGenerative art Raked gravel in low morning sun, its furrows flowing around mossy stones.

Use ← and → to move between demos. While the canvas has focus, keys go to the demo instead.

← More from Emergent Mind Labs