Skip to content

Zen Bloom

What you’re looking at

The background behind this text is alive. Each dot is an idea — born with a size, a speed, and a lifespan. Small ideas move fast. Large ones drift slowly, attracting connections. When two ideas pass close enough, a line forms between them. Click the dark space and watch what happens.

Why I built this

I’ve been thinking about how creativity actually works. Not the TED talk version — the real thing. Ideas don’t arrive on schedule. They show up at different scales, move at different speeds, and most of them fade before they connect to anything. But sometimes two unrelated thoughts drift close enough to link, and that link changes both of them.

I wanted to see that. Not read about it. See it.

The bloom is the part I care about most. You click, and a burst of new ideas radiates outward — bright, energetic, temporary. They scatter into the existing field and start forming their own connections. Some of them stick. Most of them fade. That’s how it actually works.

How it works

Simplex noise generates the flow field — a 2D vector at every point that evolves over time. Particles follow these vectors, tracing curving paths rather than straight lines.

Connections form between any two particles within 200 pixels, capped at five per particle. Lines between larger particles are brighter — the bigger the idea, the stronger its connections read.

Variable speed creates depth. Small particles move at 1.3x, large ones at 0.7x. This makes the flat canvas feel three-dimensional.

Bloom spawns 15-30 particles with radial velocity, 2.5x normal size, 5x initial brightness. They decelerate slowly (0.97 per frame) and a glow pulse marks the origin for two seconds. Auto-bloom fires every 8-12 seconds so the field breathes on its own.

Scroll fade dims the canvas to black over the first 50% of scroll depth.

The numbers

  • 400 particle slots, struct-of-arrays with Float32Array (zero GC pressure)
  • 30fps target with frame-skipping
  • DPI-aware, capped at 2x devicePixelRatio
  • Pauses on tab switch, removes itself on prefers-reduced-motion
  • ~500 lines of vanilla JS, single Astro component, zero dependencies

Keyboard Shortcuts