Draw My Canvas / studio

Frost Dendrites

Release a particle far away. Let it wander at random. Freeze it where it first touches. Repeat, and branches appear that nobody wrote.

Plate 14diffusion-limited

Waiting for the animation above to load…

What lands in the file, and what the width does

One click writes whatever the animation is drawing at that moment to a PNG, with the drawmycanvas.com mark drawn into the picture rather than laid over it. Leave the width box empty and you get the stage exactly as your browser rasterised it — your window’s width times its device pixel ratio, which is about 1,600 px across from a 1280‑px window on a HiDPI laptop and about 353 px from a 390‑px phone.

Type a width instead, or take a preset, and the frame is redrawn into a canvas that wide: the height follows the stage’s own shape and the mark scales with it. The stage is 16:9 on a wide window and 4:3 below 560 px, so a width of 1200 saves 1200×675 on a laptop and 1200×900 on a phone. 1200 px is the width Open Graph and X link cards are cut from — the canonical card is 1200×630, and a card crops the extra height rather than letterboxing it.

Honest limits. Asking for more pixels than the stage was drawn at resamples pixels that were never drawn: a 1920‑px file exported from a 353‑px phone stage is bigger, not sharper. A very large width is a real memory allocation and a browser is allowed to refuse it; when that happens the line above says so plainly and nothing else on the page changes. PNG only — no JPEG, no WebP, no animated export. And nothing is uploaded: the picture is assembled in your own browser, so no frame of this plate ever reaches us.

Live on an HTML canvas · vanilla JavaScript · no dependencies Open fullscreen

About this piece

The whole rule is four lines long. One cell at the centre is frozen. A particle is released on a circle just outside the crystal and takes a random walk — one cell at a time, no preferred direction. The moment it lands next to something frozen, it freezes there too, and the next particle is released. This is diffusion-limited aggregation, published by Thomas Witten and Leonard Sander in 1981 as a model of how soot, electrodeposits and mineral dendrites actually grow.

Nothing in that rule mentions branches, tips or symmetry. You get all three anyway, and the reason is worth stating plainly: a wanderer has to survive the entire approach. Tips stick out into open space and meet arrivals first; the fjords between them are shielded, and a particle that would have to thread one almost always touches a tip on the way in. So tips capture nearly everything, gaps stay gaps, and arms thin as they lengthen instead of filling out.

How thin, exactly

Thin enough to measure. A DLA cluster's mass grows roughly as r1.71, not as the r² a solid disc would give. So doubling the radius costs about 3.3× the particles rather than 4×, and the gap widens without limit — at ten times the radius a disc would be 100× heavier and this is only about 51×. That exponent, 1.71 in two dimensions, has never been derived from the rule; it is a measured number, and reproducing it is the standard way people check a DLA implementation. The one on this page holds to it. Grown out to the frame of a 1280×900 window it settles at 4,615 frozen cells inside a radius of 141, and log 4615 ÷ log 141 = 1.70. Across the five frame sizes it was measured at — a phone, two gallery-tile sizes, the social card and that desktop window — the exponent lands between 1.67 and 1.75.

The stick test here uses four neighbours, not eight — a particle has to share an edge with the crystal, not just a corner. On a square lattice that biases growth very slightly along the two axes, which is precisely why this reads as frost on a window rather than as soot. That anisotropy is a known artefact of lattice DLA, and it is kept here because it is the more beautiful of the two failures.

The one optimisation, and why it is not a cheat

Naive DLA is brutally slow: a particle released far away takes on the order of the square of its distance to arrive anywhere. The trick is exact rather than approximate. A wanderer sitting a distance d beyond the crystal’s outer radius r cannot possibly touch anything before it first leaves the circle of radius dr − 1 drawn around itself — and by symmetry, a two-dimensional random walk leaves such a circle at a point uniformly distributed around it. So the walk teleports straight there in one step. Only inside the last two cells does it fall back to honest single hops, where the geometry actually matters. Counted honestly, that is worth about : the 1280×900 crystal above costs 7.9 million walker steps where the unit-step walk would have cost 45 million. Six, not six hundred — because most of the remaining cost is the last stretch inside the cluster’s own radius, where the walker has to take real steps through the gaps. That is not waste; that shielding is the thing making the branches, and there is no shortcut through it that does not change the picture.

What to look for

Freezing is permanent, so the canvas is never cleared while the crystal grows — each frame paints only the handful of cells that froze during it. That is what makes a piece this detailed cheap enough to leave running in a background tab. When the crystal reaches the frame it holds for a few seconds, then thaws with a destination-out wash (an alpha erase, so the paper colour behind the canvas stays itself instead of walking toward black) and a new seed nucleates. Click the canvas to skip straight to a fresh crystal.

Honest limits: this is lattice DLA at one particle at a time, not a physical simulation of ice. Real window frost also grows from vapour along existing scratches and follows the humidity gradient, which is why it has a preferred direction and this does not. Every run is genuinely different, and there is no seed you could quote to get a particular crystal back. And the lattice cell is a fixed three CSS pixels at every size, so a 390×844 phone grows a genuinely smaller crystal — about 980 cells at radius 62 against the desktop’s 4,615 at 141 — rather than the same crystal scaled down. Reduced-motion visitors get the growth run to completion in one burst and then held still.

Curious how the loop and canvas fit together? Read how it works →

More from the gallery

All 22 animations in the gallery →