webdevpuneet.com

Scroll Canvas Generative Flow Field — Procedural Vector-Field Particles

Scroll Canvas Generative Flow Field · Scroll · Plain HTML, CSS & JS · Live preview

Copy & paste

Source Code

<section class="gff-stage" id="gffStage">
  <div class="gff-intro-overlay"><p>Scroll ↓ to stir the current</p></div>
  <canvas id="gffCanvas"></canvas>
  <div class="gff-hud"><span id="gffPct">0</span>% turbulence</div>
</section>
<section class="gff-bottom"><p>Hundreds of particles tracing a procedural vector field, no noise library involved.</p></section>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Procedural vector field from layered sine/cosine terms — no external noise library
Fading motion trails via a translucent overlay rect instead of clearRect
Flat Float32Array particle state allocated once — zero per-frame allocation in the render loop
Lifespan-based particle recycling keeps the field visually replenished indefinitely
Single turbulence value drives field scale, angle amplitude, and particle speed together
GSAP ScrollTrigger pins the stage and scrubs turbulence from calm to chaotic
Independent time term keeps the field itself slowly evolving even without scrolling
Fully reversible — scrolling up calms the current back to its resting drift

About this UI Snippet

How to Build a Scroll-Driven Generative Flow Field With Canvas2D

Screenshot of the Scroll Canvas Generative Flow Field snippet rendered live

The Scroll Canvas Generative Flow Field snippet moves hundreds of particles through a procedurally computed vector field, leaving soft fading trails, with the field's turbulence and particle speed both increasing as the visitor scrolls through a pinned stage — no Perlin or simplex noise library, no Three.js, just Canvas2D and a handful of trigonometric functions.

A vector field from layered sine and cosine, not a noise texture

fieldAngle(x, y, t, turbulence) computes a single angle at any point in the plane by summing three offset sine/cosine terms at different spatial scales and phase speeds. This is a cheap, hand-rolled substitute for true Perlin noise — it doesn't have noise's statistical properties, but it produces the same essential quality a flow field needs: a direction that varies smoothly across space and drifts slowly over time, with zero external dependency.

Trails from a translucent overlay, not clearRect

Instead of calling ctx.clearRect every frame (which would erase everything back to a blank canvas), the draw loop paints a translucent rgba(5, 8, 10, 0.12) rectangle over the entire canvas each frame. Because it doesn't fully erase, every particle's previous few positions remain faintly visible underneath the newest frame, producing the classic flow-field streak-trail look for free — the same technique behind Scroll Canvas Starfield Warp Speed's motion streaks.

Zero per-frame allocation

All 900 particles' positions, remaining lifespans, and hue seeds live in flat Float32Arrays allocated once at resize() time. The animation loop only reads and writes indices into those arrays — never creates a new object or array per frame — which matters more here than in a lower-particle-count effect, since this loop also calls two trigonometric functions per particle per frame for the field itself.

Lifespan-based recycling instead of a fixed particle pool boundary check

Each particle carries a life counter that ticks down every frame; when it reaches zero (or the particle drifts off-canvas), seedParticle(i) respawns it at a fresh random position. This keeps the flow field visually replenished indefinitely without ever growing or shrinking the particle arrays.

Turbulence as one interpolated variable

A single turbulence value (0 to 1, driven by scroll) is fed into the field's spatial scale, its angle amplitude, and the particles' base speed simultaneously — so scrolling doesn't just move particles faster, it also makes the field itself spatially "tighter" and more chaotic, a richer effect than scaling speed alone.

Customizing it

Adjust the three sine/cosine terms' scale and phase-speed constants in fieldAngle for a different flow character, change the particle COUNT for a denser or sparser field, or swap the hue range for a different color story. Pair it with Scroll Canvas Starfield Warp Speed for a related Canvas2D particle technique.

Step by step

How to Use

  1. 1
    Load the CDN scriptsAdd gsap.min.js and ScrollTrigger.min.js from the CDN panel, in that order.
  2. 2
    Paste HTML, CSS, and JSA calm drifting particle field renders inside a pinned canvas stage with a live "% turbulence" read-out.
  3. 3
    Scroll downThe field grows more turbulent and particles speed up and streak, driven by a single turbulence value.
  4. 4
    Scroll back upThe field calms back to a slow, gentle drift exactly in reverse.
  5. 5
    Retune the flowAdjust the scale and phase-speed constants inside fieldAngle for a different current pattern.
  6. 6
    Change particle densityIncrease or decrease COUNT for a denser or sparser field (watch frame rate on lower-end devices).

Real-world uses

Common Use Cases

🎨
Generative art portfolios
Demonstrate procedural motion with hundreds of particles following a sine and cosine vector field, becoming more turbulent as the reader scrolls.
🌬️
Weather and fluid visualisations
Suggest wind or fluid movement behind a data page, using fading trails produced by a translucent overlay instead of clearRect.
🌌
Ambient section backgrounds
Provide a living, low-key backdrop, with a flat Float32Array allocated once so no memory is created per frame.
🎓
Procedural motion teaching
Teach field-driven animation without a noise library, with lifespan-based recycling keeping the field replenished indefinitely over a long scroll.
📈
Data platform landing pages
Suggest continuous flow of information, with scroll controlling both turbulence and particle speed through GSAP ScrollTrigger.
Related: Scroll Canvas Starfield Warp Speed
See Scroll Canvas Starfield Warp Speed for a related Canvas2D scroll-driven particle technique.

Got questions?

Frequently Asked Questions

fieldAngle sums three sine/cosine terms at different spatial scales and phase speeds to compute a direction at any point. It lacks true noise’s statistical guarantees, but produces the same essential quality a flow field needs — a direction that varies smoothly in space and drifts slowly over time — with no external library dependency.

Each frame paints a translucent dark rectangle (rgba with a low alpha) over the whole canvas instead of fully clearing it. Because previous frames are only partially erased, particles’ recent past positions remain faintly visible, producing streak-like trails for free rather than requiring a separate trail-drawing pass.

A fixed lifespan counter that ticks down each frame, combined with an off-canvas check, lets particles respawn at fresh random positions periodically even if they never leave the visible area — keeping the field looking continuously replenished rather than settling into a static repeating pattern.

A single 0-to-1 turbulence value (driven by scroll) is fed into three places at once: the field’s spatial scale (making the pattern spatially tighter), the field’s angle amplitude (making direction changes more extreme), and the particles’ base speed — so higher turbulence looks qualitatively more chaotic, not just faster.

With 900 particles updated every frame, an array of plain JS objects would mean 900 property lookups and potential hidden-class deoptimization per frame. Flat typed arrays indexed numerically avoid per-particle object overhead and never trigger garbage collection from the render loop itself.