Hundreds of dots scattered across space converge to spell a word as you scroll, then disperse back into chaos. Canvas2D + a target-position interpolation.
A field of particles (dots, sparks, fireflies) starts randomly scattered. As you scroll, each particle interpolates toward a target position that together spell out a word, a logo, or a shape. At the bottom of the scroll, they scatter again. The visual moment when randomness becomes order (and back) is hypnotic — used by brand launches, AI product reveals, music album sites, conference openers.
(1) Pre-compute target positions: render the target word onto an offscreen canvas, sample every Nth opaque pixel — that gives you an array of (x, y) points that form the word's shape. (2) Create a particle for each target point: assign it a random start position. (3) On scroll: for each particle, lerp its current x/y between its random position and its target position by --p (with a tiny per-particle jitter so they don't move in perfect sync). (4) Draw every particle on a main canvas every frame. The whole word "assembles" out of chaos as you scroll.
Scroll inside. Watch ~800 sparks coalesce into "AURORA", hold, then scatter back.
Build a canvas particle-assembly scroll animation. Sticky pin (top:0 height:100vh) inside a 2400px-tall section. Inside the pin, a full-bleed <canvas> element (900×600 logical size; CSS makes it 100%/100%). On load: (1) create an OFFSCREEN canvas, draw your target word ("AURORA") at large display-serif font in white; (2) walk the pixel data and every 4th opaque pixel adds an {x, y} target to an array; (3) create a Particle object for each target with random startX/Y (off-screen), targetX/Y, jitter factor, color, size, and an alpha fade. JS scroll listener computes scroll progress 0→1 and maps to a peak-at-middle curve (1 - |p - 0.5| × 2) — that's the "assembly progress" --p. Then each animation frame: clear the main canvas; for each particle compute x = startX + (targetX - startX) * --p * particle.jitter; y similar; draw a small accent-colored circle at that position with arc(). Optionally connect nearby particles with thin lines when close together for a constellation feel. Show "Particles: NNN · Assembly: NN%" readout and a progress bar. Result: hundreds of sparks coalesce into the word, hold at middle scroll, then disperse back into chaos.