webdevpuneet.com

Canvas Boids Flocking Simulation — Free Emergent Behavior Snippet

Canvas Boids Flocking Simulation · Animations · Plain HTML, CSS & JS · Live preview

CategoryAnimations

Copy & paste

Source Code

<div class="bf-wrap">
  <canvas id="bfCanvas" class="bf-canvas"></canvas>
  <div class="bf-panel">
    <span class="bf-tag">separation · alignment · cohesion</span>
    <p>Move your cursor into the flock — it acts as a predator the boids scatter from.</p>
    <div class="bf-row">
      <label>Boids <span id="bfCountVal">120</span></label>
      <input type="range" id="bfCount" min="30" max="240" value="120" step="10" />
    </div>
  </div>
</div>

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

Classic three-rule boids
Separation, alignment, and cohesion, each computed independently.
Local perception only
Every boid reacts only to neighbors within a fixed radius.
Weighted force blending
Separation, alignment, and cohesion combined with tuned weights.
Force and speed limiting
Caps steering and velocity for smooth, readable motion.
Cursor predator
The pointer repels nearby boids as a fourth steering force.
Live boid-count control
Add or remove boids on the fly via a slider.
Edge wraparound
Boids leaving one edge reappear on the opposite side.
Speed-tinted rendering
Boid color hue shifts subtly with current speed.

About this UI Snippet

Canvas Boids Flocking Simulation — Craig Reynolds' Three Rules From Scratch

Screenshot of the Canvas Boids Flocking Simulation snippet rendered live

Boids, introduced by Craig Reynolds in 1986, remains one of the clearest demonstrations that complex, convincing group behavior doesn't require central coordination — just three simple local rules, applied identically and independently to every individual. This snippet implements all three from scratch on canvas, with a cursor predator layered on top.

Three rules, computed per-boid from local neighbors only

Every frame, flock() looks only at neighbors within a fixed PERCEPTION radius (55px) and computes three separate steering vectors: separation (steer away from nearby neighbors, weighted more strongly the closer they are, via a 1/d falloff), alignment (steer toward the average heading of nearby neighbors), and cohesion (steer toward the average position of nearby neighbors). No boid has any awareness of the flock as a whole — it only ever sees whoever happens to be within its own perception radius, exactly like Reynolds' original model.

Weighted force blending, not equal votes

The three steering vectors aren't averaged equally — separation is weighted roughly 1.6x, alignment 1.0x, and cohesion 0.9x before being summed into a single acceleration. This weighting is what keeps the flock cohesive (birds stay in a visible group) while still preventing them from colliding (separation dominates at close range) — tuning these weights is the single biggest lever over how "flocky" versus "swarmy" versus "scattered" the simulation looks.

Force and speed limiting keep motion boid-like

Both the individual steering vectors and the boid's final velocity are passed through limit(), which caps a vector's magnitude while preserving its direction. Without this, cohesion or alignment forces from a dense cluster could produce a huge instantaneous acceleration; capping keeps every boid's turning and speed changes gradual and readable rather than jittery.

A cursor predator layered on top of the three core rules

The pointer contributes a fourth, independent force: any boid within 120px of the pointer steers directly away from it. This isn't part of classical Reynolds boids, but composes naturally with the existing acceleration-summing structure — it's just one more vector added before the final speed clamp.

Naive O(n²) neighbor search, by design

Every boid scans every other boid to find its neighbors each frame. That's quadratic in boid count, but for the few hundred boids this demo supports it's comfortably fast at 60fps — a spatial grid or quadtree would only be worth the added complexity at boid counts in the thousands.

Compare with canvas particle text formation for a different flavor of large-particle-count canvas motion built around a target shape instead of emergent local rules.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JS120 boids spawn and immediately begin flocking.
  2. 2
    Observe emergent groupingBoids align, cluster, and avoid collisions with no leader.
  3. 3
    Move the cursor into the flockNearby boids scatter away from the pointer as a predator.
  4. 4
    Move the cursor outThe flock re-coalesces into cohesive groups.
  5. 5
    Adjust the Boids sliderAdd or remove boids live; the flock rebalances instantly.
  6. 6
    Resize the windowThe simulation bounds adapt to the new canvas size.

Real-world uses

Common Use Cases

Emergent behaviour teaching
Demonstrate that convincing group movement needs only separation, alignment and cohesion, with no leader or central coordination.
Nature-themed landing pages
Add an organic, living ambient layer, with each boid reacting only to neighbours within a fixed perception radius.
Algorithm portfolio pieces
Show command of simulation and canvas rendering, with tuned force weights and capped speed for smooth, readable motion.
Schooling-fish and flocking visuals
Present a science or biology product with a believable flock that scatters when it senses the cursor predator.
Game NPC swarm prototypes
Use as a starting point for crowds, flocks or creature swarms, adjusting count and rules with the live control panel.
Related: Canvas Noise Texture Background
See the Canvas Noise Texture Background for a related animations pattern worth pairing with this one.
Related: Cursor-Follow Underline Draw
See the Cursor-Follow Underline Draw for a related animations pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

Boids is a 1986 artificial-life program by Craig Reynolds that simulates flocking behavior — birds, fish schools, herds — using three simple local steering rules applied to every individual: separation (avoid crowding neighbors), alignment (match neighbors' average heading), and cohesion (move toward neighbors' average position). No individual boid is aware of the group as a whole; the convincing group behavior emerges purely from many individuals following the same local rules.

The three steering forces are summed with different weights before being applied — separation is weighted more heavily than alignment or cohesion. That weighting means avoidance dominates at close range (preventing collisions) while cohesion and alignment still pull the group together at slightly longer range, producing a flock that stays visually grouped without individuals overlapping.

Only nearby boids. Every frame, flock() checks the distance from a boid to every other boid and only includes ones within the fixed PERCEPTION radius (55px) in its separation/alignment/cohesion calculations. This locality is the whole point of the algorithm — realistic group behavior emerges from purely local awareness, with no boid ever consulting global flock state.

It is an independent fourth steering force added on top of the three core boid rules: any boid within 120px of the pointer gets an acceleration pointing directly away from the pointer, scaled by a fixed strength. Because it is just one more vector summed into the boid's total acceleration before the final speed-limiting step, it composes naturally with the existing flocking behavior rather than overriding it.

Each frame currently does an O(n^2) neighbor scan — every boid checks the distance to every other boid — which is fast enough for the few hundred boids this demo supports but would start to degrade into the thousands. At that scale, you'd want to bucket boids into a spatial grid or quadtree first and only check distances against boids in nearby cells, which is the standard optimization for larger flocks.