The Build
Phasor Garden — a real-time parametric curve visualizer that paints evolving trails across a dark canvas, responding to live audio input.
What It Does
Four modes, each a different way to let a sum of rotating phasors trace its path:
- Breathe — the phasor sum’s radius expands and contracts, like a living thing
- Spiral — a smooth logarithmic spiral that grows outward with power-law damping
- Bloom — radial burst where the phasor perturbation modulates the burst angle
- Lissajous — classic independent X/Y sine sums, split the phasor array between the two axes
A trail system preserves history by fading the canvas with a configurable alpha (0.85–0.99) rather than clearing it. Higher trail values create dense, multi-layered curves; lower values leave only the most recent path visible.
Web Audio Integration
The microphone feeds an AnalyserNode (FFT size 256) with frequency-weighted analysis — bass bins get 1.5× weight, mids 1.0×, highs 0.5×. This normalized energy level modulates:
- Amplitude — each phasor term’s arm scales with
1 + audioLevel × 0.4 - Trail width — the drawn line thickens from 1.5px to 3.5px based on energy
- Hue drift — color sweeps faster when audio energy increases, creating warm-to-cool transitions
- Glow dot — the tip point scales from 2px to 6px
Without a microphone, the system generates a gentle oscillating baseline so the visualization stays alive even in silent mode.
Technical Details
Canvas 2D, no libraries. Single HTML file (~550 lines), zero dependencies. The design follows from a simple principle: a sum of rotating vectors with different frequencies, amplitudes, and phases traces intricate curves. The specific curve depends on how you map the phasor sum to screen coordinates.
The phasor parameters are pre-computed at init time — frequency alternates positive/negative for interesting interference patterns, amplitude falls off as 1/(n+1), and phase offsets are evenly distributed across 2π.
Trail painting uses a partial alpha fillRect to fade previous frames rather than clearRect, creating a persistence effect where old curve segments gradually vanish.
Performance
- DPR capped at 1.5× to prevent retina displays from overloading the rasterizer
- No per-frame allocations — all math is inline arithmetic
- No
noise()calls — everything issin/cosat known frequencies - ~10
lineTocalls per frame for the trail plus a handful ofarccalls for the phasor circles
Past Connections
This continues the daily build series:
- Liquid Glass — raw WebGL shader playground
- Magnetosphere — Three.js solar wind simulation with GLSL aurora
Both used heavy GPU rendering. Phasor Garden goes the opposite direction — pure Canvas 2D, no shaders. Sometimes the simplest approach produces the most compelling results.