Canvas · no library
Cursor-reactive flow field
A particle flow field on canvas that bends its streamlines around the pointer. No library.
Yours to take. No sign-up, no email, no attribution needed.
The code
const c = document.getElementById('flow');
const x = c.getContext('2d');
const BG = '#22405E';
const SWIRL = 260; // how far the cursor bends the field
let W, H, particles = [];
const m = { x: -1e4, y: -1e4 };
function size() {
W = c.width = c.clientWidth;
H = c.height = c.clientHeight;
x.fillStyle = BG;
x.fillRect(0, 0, W, H);
}
// The field itself: any (x, y) maps to an angle.
// Change this one line and you get a different picture.
const flow = (px, py) =>
(Math.sin(px * 0.0032) + Math.cos(py * 0.0041)) * Math.PI;
function reset(p) {
p.x = Math.random() * W;
p.y = Math.random() * H;
p.life = 40 + Math.random() * 160;
}
function step() {
// Trails: paint the background back over the canvas, faintly,
// on every frame. No array of past positions to keep.
x.globalAlpha = 0.035;
x.fillStyle = BG;
x.fillRect(0, 0, W, H);
x.globalAlpha = 1;
x.strokeStyle = 'rgba(246,245,241,.55)';
x.lineWidth = 1;
x.beginPath();
for (const p of particles) {
const a = flow(p.x, p.y);
let vx = Math.cos(a);
let vy = Math.sin(a);
// Near the cursor the field bends into a swirl.
const d = Math.hypot(p.x - m.x, p.y - m.y);
if (d < SWIRL) {
const n = 1 - d / SWIRL;
const t = Math.atan2(p.y - m.y, p.x - m.x) + Math.PI / 2;
vx += Math.cos(t) * n * 2.4;
vy += Math.sin(t) * n * 2.4;
}
x.moveTo(p.x, p.y);
p.x += vx;
p.y += vy;
x.lineTo(p.x, p.y);
if (--p.life < 0 || p.x < 0 || p.x > W || p.y < 0 || p.y > H) reset(p);
}
x.stroke();
requestAnimationFrame(step);
}
addEventListener('resize', size);
addEventListener('pointermove', (e) => { m.x = e.clientX; m.y = e.clientY; });
size();
particles = Array.from({ length: 900 }, () => {
const p = {};
reset(p);
return p;
});
step();We do this for a living, on bigger things.
Tomoe builds operations software for businesses running real money through spreadsheets and WhatsApp threads. The same care that went into this effect goes into an order portal that a warehouse depends on.