AI CSS Animations

Voronoi Cells

A stained-slide colony of plump Voronoi cells grows from one cell to 256: chromatin lines up and splits, new walls pinch in, the packing relaxes into even polygons as the camera pulls back, and a faint shimmer runs along the pink cell walls.

Written and rendered by AI CSS Animations Oct 18, 2026

Type
prompt
Made with
Claude Opus 5.5 in Claude Code
Built in
Canvas
Topics
Shapes · Particles
What Claude made from the prompt below in Claude Code: one HTML file rendered frame by frame to video. Silent preview.

About this style

A Voronoi diagram splits a plane into cells, each holding every point closer to its seed than to any other seed. Georgy Voronoy formalized it in 1908, and Peter Gustav Lejeune Dirichlet had used the idea decades earlier. Moving each seed toward the center of its cell, as Lloyd's algorithm does, relaxes a random diagram into the even, polygonal packing also seen in crowded tissue, and histology slides give that structure its familiar colors, since the standard hematoxylin and eosin stain turns nuclei purple and cytoplasm pink. Generative artists, architects and biotech brands use the form for its sense of living order.

The prompt

Make a 10-second generative film: Voronoi cells grow, divide and relax like living tissue on a stained microscope slide, from one cell to 256.

<inputs>
If I don't give you something, use the default and don't ask.
- Title: "Every cell from a cell."
- Line: "A Voronoi colony, one cell to 256"
- Slide label: "Specimen 14 · H&E · 40×"
- Generations: 8 (one cell becomes 256).
- Length: 10 seconds.
</inputs>

<direction>
- Palette: slide #F8F1F3 with a faint warm vignette to #EFE2E7 at the corners; cytoplasm in eosin pinks, #F6C9D8 at a cell's center deepening to #E7A0BD toward its wall, each cell shifted ±6% in lightness by seed; cell walls #B5487F with a 1px inner highlight #FBE3EC; nuclei hematoxylin violet #5A3A8F with chromatin flecks #3C2370, a 1px rim #7B5CB0 and one nucleolus #2B1650; dividing chromatin #2E1B5E; type #3A1F4D, secondary #7A5A80.
- Drawing the cells, per pixel in a fragment shader: find the nearest seed a, then the wall distance w = the minimum over every other seed b of (|p − b|² − |p − a|²) ÷ (2·|a − b|), the exact distance to their shared bisector. Blend the two smallest of those values with a smooth minimum (k = 6px) so corners round off and cells look plump, not like a flat mosaic. The wall is where w < 1.25px (anti-aliased with fwidth); cytoplasm darkens toward the wall over 18px; the inner highlight sits 2px inside it. Outside the colony: where |p − a| exceeds 1.15 × that cell's radius, show slide with a soft 5px edge, so the colony's rim bulges cell by cell.
- The colony, simulated once at load at a fixed 1/60 s step from a seeded PRNG (sizes at the final 1.0× view): cells are soft discs with a target radius of 40px that push apart with a linear spring when closer than the sum of their radii (stiffness 40, velocity damping 0.85 per step) and feel a weak pull toward the colony center (0.6), so the packing keeps relaxing toward even, honeycomb-like polygons. A cell grows from 0.71× to 1× its target radius over its cycle (its area doubles before it splits), then divides: two daughters start ±0.3r apart along a seeded axis and move apart over 0.5 s. Cycles last 0.85–1.0 s with seeded jitter, so divisions ripple through the colony a few at a time instead of firing together. The first division is at 0.7 s; the colony reaches 256 cells by about 7.1 s, and nothing divides after that.
- A division you can follow: 0.3 s before the split, the nucleus loses its rim and its chromatin gathers into a dense bar across the division axis (26 × 6px at final scale); at the split the bar parts into two clumps that slide apart; the new wall grows inward from both sides like a pinching furrow (between sister cells, the wall's opacity ramps from the old walls toward the middle over 0.35 s); each clump rounds back into a nucleus.
- Nuclei: ellipses 22 × 17px at final scale, aligned with each cell's long axis, offset from the seed by a small seeded drift, with 6–10 chromatin flecks and a nucleolus.
- Shimmer: the wall highlight brightens by up to 35% where slow 2D value noise of position, drifting at 40px/s, peaks, so short stretches of wall glint and fade over about a second each. Nothing blinks.
- Camera: one cell about 340px across at (1320, 540) at t = 0; the view pulls back from 5.0× to 1.0× on easeInOutSine over 0.4–7.4 s, so cells shrink on screen as they multiply. Final cells are about 80px across; the colony fills the right of the frame, cropped by the top, right and bottom edges, with its left rim right of x 680 in every frame (adjust the pull-back curve if needed).
- Type (HTML over the canvas): title in Fraunces 400 (opsz 144, SOFT 100), 76px, leading 1.0, #3A1F4D, two lines from (120, 150); line in Fraunces 400 italic, 28px, #7A5A80, beneath. At the bottom left, the slide label in Spline Sans Mono 400, 20px, tracked 0.08em, uppercase; under it a counter "Cells 1" → "Cells 256" in Spline Sans Mono 500, 30px, tabular figures, changing on the exact frame each split happens; and a 2px #3A1F4D scale bar labeled in µm that steps between 200, 100 and 50 µm to stay 100–240px long as the camera pulls back.
- Easing: text rises 12px as it fades in over 0.6 s on cubic-bezier(0.22, 1, 0.36, 1). Nothing bounces.
- Premium: plump cells with real walls, divisions you can watch from start to finish, a packing that visibly settles, a palette that feels like a stained slide. Cheap: a flat random Voronoi mosaic in rainbow colors, cells popping into existence, lines that never move.
Banned: rainbow fills, black outlines, neon or glowing edges, cells that appear without a division, gaps or overlaps inside the colony, blinking, dark backgrounds, anything flashing more than 3 times per second.
</direction>

<structure>
- 0.0–0.7s: the empty slide, then one plump cell at (1320, 540), its nucleus at rest; the title and line rise in.
- 0.7–2.6s: the first divisions, 1 → 2 → 4 → 8, each with its chromatin bar and pinching wall; the daughters jostle and settle.
- 2.6–5.0s: 8 → 64 as the camera pulls back; divisions ripple through the colony a few at a time; the label, counter and scale bar rise in at 2.8 s.
- 5.0–7.1s: 64 → 256; the colony fills the right of the frame; the shimmer travels along the walls.
- 7.1–8.6s: no more divisions; the packing relaxes into even polygons and the camera comes to rest.
- 8.6–10.0s: hold; only the slow shimmer moves.
For other lengths, keep eight generations and stretch the cycle time; keep at least 1 s of hold.
</structure>

<build>
- One self-contained index.html (inline CSS and JS), a 1920×1080 (16:9) stage scaled to fit the window, designed for 60fps. No image, video, texture or model files: every shape and texture is generated in code.
- window.seek(t), t in seconds, computes every visual from t alone: no CSS transitions or CSS animations, no setTimeout/setInterval, no state carried between frames, randomness only from a seeded PRNG. Anything cumulative is solved analytically from t or precomputed once at load at a fixed step. Past the end, seek clamps to the last frame.
- Without ?render in the URL, drive seek from requestAnimationFrame so it plays in a browser (loop after a 1s end hold); with ?render, don't start that loop.
- Google Fonts via <link> are fine; await document.fonts.load() for each face before defining window.seek.
- Engine: Canvas: one WebGL canvas (preserveDrawingBuffer: true, drawn once per seek), its backing store sized from CSS size × devicePixelRatio, whose fragment shader draws the cells from the current frame's cell data (position, radius, nucleus state, sister id), uploaded each seek as a small float texture. Type is HTML over it.
- The colony is simulated once at load into Float32Arrays (keep load under 10 s); seek(t) interpolates the stored steps and never steps the simulation.
</build>

<check>
Before showing me, step through one frame per second (t = 0…10): screenshot each and look at it. Fix overlaps, clipped or cramped text, and anything off-style or Banned. Check every new cell comes from a visible division, walls are continuous with no gaps or overlaps inside the colony, the counter matches the cells on screen, the type stays on clear slide, and the 6 s frame and the final frame are both complete compositions. Confirm seek(10) and seek(11) match, so the final frame holds.
</check>

Ours, and free to use under CC0: copy it, change it, ship it. No credit needed.

Similar prompts

More like this on the motion design inspiration board: Motion graphics inspirationParticle animation inspiration