Draw My Canvas / studio

Quantum Fibonacci

Golden-angle phyllotaxis: 320 seeds turning slowly and breathing, packed like a sunflower head.

Plate 01golden-ratio

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. For a big file that is sharp, use Save as wallpaper: it draws the plate again from scratch at exactly 1179×2556 or 1290×2796 (phones), 1920×1080, 2560×1440 or 3840×2160 (4K), so every line is rasterised at that size and the shape is the screen’s, never stretched. Because the plate restarts, a wallpaper is a fresh run of it rather than the exact frame on screen; it is given as long as the stage has been running, up to 20 seconds, to develop. 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. Stills are PNG only — no JPEG, no WebP. On browsers that can record video, Record a clip saves 5, 10 or 20 seconds of the running animation as MP4 or WebM (whichever this browser can encode) at the same width, with the mark in every frame. A clip is not a seamless loop, it has no audio, and a width bigger than the stage is resampled rather than sharper — only the wallpaper is redrawn at its size. Where a browser cannot record video the button never appears and a PNG is the only export. And nothing is uploaded: the frame or clip 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

Quantum Fibonacci draws a sunflower head of 320 seeds, one soft dot per seed, and nothing else. Seed number n is placed by two rules. Its direction is the previous seed’s direction turned by the golden angle, 137.5078° (π(3 − √5) radians), and its distance from the centre is 0.031 of the frame’s short edge times the square root of n. That is the whole recipe; every dot is recomputed from those two rules on every frame, so there is no trail and no randomness, and the head looks the same on every visit.

Three slow motions sit on top of it. The whole head turns clockwise, 0.25 radians per unit of animation time; the clock advances 0.03 per frame, so one full turn takes about 838 frames, about 14 seconds on a 60 Hz screen. Each dot breathes: its size is multiplied by 0.6 + 0.4 sin(1.5t + 0.28n), which swings between a fifth of full size and full size about every 2.3 seconds and never reaches zero, so no seed ever disappears. Because each seed is 0.28 radians out of step with the one placed before it, the swelling ripples through the head instead of the whole disc beating at once. And the dots grow toward the rim, the outermost about 3.2 times the size of the innermost. Every 9th seed (36 of the 320) takes the site’s coral ink; the rest are cobalt, and both inks switch with the light or dark theme.

“Quantum Fibonacci” is the piece’s title and nothing more: nothing quantum is simulated here, and the motion is plain trigonometry. The name is kept because it is how the catalogue has always listed this plate.

Why this is the sunflower model

These two rules are H. Vogel’s 1979 model of a sunflower head, published as “A better way to construct the sunflower head” in Mathematical Biosciences (vol. 44, pp. 179–189). In Vogel’s form, floret n sits at

r = c √n,  θ = n × 137.508°

where c is a scaling constant; here c is 0.031 of the short edge. The square root is what keeps the head evenly dense. The area inside radius c√n is πc²n, so it grows by exactly the same amount, πc², for every seed added: each seed gets an equal share of area, and the curve through successive seeds (Fermat’s spiral) crosses equal-area rings in equal turns. A worked case: the first 80 seeds fill the circle of half the head’s radius, and that circle holds a quarter of the head’s area and a quarter of its 320 seeds. With a short edge of 600 pixels, each seed’s share is about 1,090 square pixels, a patch roughly 33 pixels across, at the centre and at the rim alike.

The angle is what keeps the seeds from lining up. Turn by a simple fraction of a circle instead and the seeds fall into straight spokes: at 135°, which is exactly 3/8 of a turn, seed 8 lands in seed 0’s direction, seed 9 in seed 1’s, and all 320 seeds end up on just 8 rays with bare wedges between them. The golden angle is 1/φ² of a turn, where φ is the golden ratio, and φ is the extreme case of a number that fractions approximate badly: the best fractions for it are ratios of consecutive Fibonacci numbers, and they close in on it unusually slowly. So no seed ever sits exactly behind an earlier one, and the gaps keep being filled. Analysis of the pattern shows it is highly sensitive to this angle, with the Fibonacci angle giving the best packing density.

What to look for

Look for the parastichies — the word botanists use for the spiral rows of florets in a sunflower head, or of scales on a pine cone. Here they are the clockwise and counter-clockwise arcs your eye traces from each dot to its nearest neighbours. Their counts are not folklore; they can be read off the plate’s own geometry. For each of the outer 40 seeds (numbers 280 to 319), the nearest neighbours are always seeds 34 and 55 numbers away. Seeds 34 apart lie on one shared arc, so the rim shows 34 arcs winding one way and 55 the other: 34 steps of 137.5078° come to 4.7° short of a whole number of turns, and 55 steps overshoot by 2.9°, so the two families lean in opposite directions.

The numbers drop as you move in. Seeds k apart in the sequence differ in radius by about ck/(2√n), so near the centre only seeds a few steps back are close enough in radius to be neighbours, while further out a seed 34 or 55 steps back is still close, and whichever of those also lands closest in direction wins. Seeds 80 to 139 meet their neighbours 21 or 34 apart, seeds 40 to 79 meet them 13 or 21 apart, and seeds 20 to 39 meet them 8 or 13 apart. So the familiar “8 one way, 13 the other” is true only near the centre of this head; at the rim, where the eye mostly looks, it is 34 and 55.

Honest limits

The head is bigger than the frame’s short side. The last seed sits 0.031 × √319, about 0.55 of the short edge, from the centre, so on a landscape stage the outer seeds from about number 260 onward are cut off at the top and bottom, and on a phone held upright they are cut off at the sides.

The motion is counted in frames, not seconds. The 14-second turn and the 2.3-second breath hold on a 60 Hz screen; a 120 Hz display runs twice as fast, and a busy machine that drops frames runs slower. Under prefers-reduced-motion the plate draws one still frame and does not turn or breathe.

This is the ideal sunflower, not a botanical simulation. The spirals of a mature head take this shape ideally, when all the florets are the same size; Vogel’s model assumes that and an exact angle, and this plate adds nothing about how a real head grows. Its dots also vary in size for looks while their spacing stays the model’s.

Draw your own

Vogel’s model is two lines of arithmetic: seed n is turned n × 137.508° from the first and set c √n from the centre. The golden angle exactly is 360(2 − φ) ≈ 137.50776°, with φ = (1 + √5)/2. Why it packs without gaps: the square root hands every seed the same patch of area, and because no number of golden-angle steps ever adds up to a whole number of turns, no seed lands behind an earlier one, so the seeds never stack into spokes with bare wedges between them.

The snippet below is that model in 24 lines of HTML and plain JavaScript, with no library. With c = 12 px, the last of 320 seeds sits 12 × √319 ≈ 214 px out, inside a 480 px canvas, and each seed’s share of the disc is π × 12² ≈ 452 square pixels, a patch about 21 px across. The dots grow from a 3 px radius at the centre to about 8 px at the rim, so roughly 4 px of ground stays visible between neighbours everywhere. Every 9th seed takes the coral ink, as on the plate, and the cobalt, coral and ground are the ones this page’s animation reads from the site palette, light or dark to match your device. Save it as an .html file and open it.

<canvas id="sunflower" width="480" height="480"></canvas>
<script>
const dark = matchMedia('(prefers-color-scheme: dark)').matches;  // follow the OS theme
const [bg, cobalt, coral] = dark ? ['#0B0D12', '150,180,255', '255,120,84']
                                 : ['#E7E2D5', '40,72,205', '190,68,28'];
document.body.style.background = bg;
const ctx = document.getElementById('sunflower').getContext('2d');
const golden = 137.50776405;  // degrees: 360 * (2 - phi), with phi = (1 + sqrt(5)) / 2
const c = 12, N = 320;  // r = c * sqrt(n): each new seed adds PI*c*c = 452 px^2 of disc
const still = matchMedia('(prefers-reduced-motion: reduce)').matches;
let shown = still ? N : 0;
function frame() {
  ctx.clearRect(0, 0, 480, 480);
  for (let n = 0; n < shown && n < N; n++) {
    const a = n * golden * Math.PI / 180, r = c * Math.sqrt(n);  // Vogel 1979
    ctx.fillStyle = 'rgba(' + (n % 9 ? cobalt : coral) + ',0.9)';  // every 9th seed coral
    ctx.beginPath(); ctx.arc(240 + r * Math.cos(a), 240 + r * Math.sin(a), 3 + r / 40, 0, 2 * Math.PI);
    ctx.fill();
  }
  shown = shown > N + 90 ? 0 : shown + 1;  // one new seed a frame, hold 1.5 s, start over
  if (!still) requestAnimationFrame(frame);
}
frame();
</script>
Paste it into an empty .html file.

The motion is the model run forward: one new seed per frame, so the head fills in 320 frames, about 5.3 seconds at 60 frames a second, holds for 90 frames (1.5 seconds) and starts again. Under prefers-reduced-motion it draws all 320 seeds at once and stops.

Where to take it: set golden to 137.0, half a degree off, and the seeds bunch into curved arms with bare ground between them; at 135, exactly 3/8 of a turn, they fall onto the 8 straight spokes described above. Raise N to 1000 and lower c to 6.8 and three times as many seeds fit in the same disc, the last one about 215 px out; shrink the dot radius to 1.5 + r / 60 as well, or the rim dots, now only about 12 px apart, overlap. What the snippet does not do: its speed is counted in frames, so it runs twice as fast on a 120 Hz screen; it reads your light or dark setting once, when the page loads; and it draws at 480 CSS pixels without scaling for high-density screens, so the dots are slightly soft on a phone or a Retina display.

Sources: Fermat’s spiral (Vogel’s model and its 1979 citation), Golden angle (its exact value, 360(2 − φ), used in the snippet), Golden ratio and Parastichy on Wikipedia, read 2026-10-01. Every count and size above is computed from the animation’s own code.

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

More from the gallery

All 32 animations in the gallery →