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.
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.