Empathy Is Making You Worse at Helping People
About This Sketch
Thirty particles drift across the canvas. One is lit: glowing, labeled, drawing all attention toward it. The other twenty-nine are barely visible — same size, same motion, indistinguishable except that no spotlight has found them.
The focus shifts every few seconds. Each newly lit particle looks no different from the ones that went before it, and no different from the twenty-nine that remain unseen. The selection is arbitrary. The attention is total.
Accompanies the post on why empathy — the felt spotlight of moral attention — reliably directs care toward the most visible rather than the most needy.
Algorithm
Thirty particles drift freely across the canvas, each following simple
Brownian-like motion with boundary reflection. At any moment, one particle
is designated the "identified victim": it glows with concentric halos and
has attention rays (animated lines) converging on it from all directions.
The remaining 29 particles are rendered as dim, barely visible dots.
Every 210 frames (~7 seconds at 30fps) the focus shifts to the next particle,
showing how arbitrary the spotlight is — each particle looks identical when
unlit, but becomes the center of all attention when selected.
The annotation "29 others — unseen" remains constant, naming what the
empathy spotlight renders invisible.
Pseudocode
SETUP:
Initialize 30 particles at random positions with random drift velocities
Assign random starting focus index
DRAW (every frame):
Get theme colors
Clear background
Increment focus timer; if >= 210 frames, advance focus to next particle
FOR each of 10 attention rays around focused particle:
Compute ray start point at animated distance from focus center
Animate alpha with sine wave for pulsing effect
Draw line from ray start to focus center
FOR each particle:
Update position by velocity; bounce off walls
IF focused:
Draw two outer glow halos at decreasing opacity
Draw bright core circle
Draw "identified victim" label above
ELSE:
Draw dim small circle at low opacity
Draw "29 others — unseen" annotation at bottom left
Source Code
let sketch = function(p) {
let particles = [];
let focusIndex = 0;
let focusTimer = 0;
const FOCUS_DURATION = 210;
const NUM = 30;
p.setup = function() {
p.createCanvas(400, 300);
p.frameRate(30);
for (let i = 0; i < NUM; i++) {
particles.push({
x: p.random(15, p.width - 15),
y: p.random(20, p.height - 20),
vx: p.random(-0.35, 0.35),
vy: p.random(-0.35, 0.35),
size: p.random(2.5, 5)
});
}
focusIndex = p.floor(p.random(NUM));
};
p.draw = function() {
const colors = getThemeColors();
p.background(...colors.bg);
focusTimer++;
if (focusTimer >= FOCUS_DURATION) {
focusTimer = 0;
focusIndex = (focusIndex + 1) % NUM;
}
let fp = particles[focusIndex];
let numRays = 10;
for (let i = 0; i < numRays; i++) {
let angle = (i / numRays) * p.TWO_PI + p.frameCount * 0.002;
let dist = 65 + p.sin(p.frameCount * 0.04 + i) * 12;
let sx = fp.x + p.cos(angle) * dist;
let sy = fp.y + p.sin(angle) * dist;
let alpha = p.map(p.sin(p.frameCount * 0.07 + i * 0.9), -1, 1, 12, 65);
p.stroke(...colors.accent1, alpha);
p.strokeWeight(0.7);
p.line(sx, sy, fp.x, fp.y);
}
for (let i = 0; i < particles.length; i++) {
let part = particles[i];
part.x += part.vx;
part.y += part.vy;
if (part.x < 5 || part.x > p.width - 5) part.vx *= -1;
if (part.y < 5 || part.y > p.height - 5) part.vy *= -1;
if (i === focusIndex) {
let pulse = p.sin(p.frameCount * 0.07) * 2;
p.noStroke();
p.fill(...colors.accent2, 18);
p.circle(part.x, part.y, (part.size + pulse) * 6);
p.fill(...colors.accent2, 32);
p.circle(part.x, part.y, (part.size + pulse) * 3.8);
p.fill(...colors.accent1, 220);
p.circle(part.x, part.y, part.size + pulse + 1);
p.fill(...colors.accent3, 150);
p.noStroke();
p.textFont('Georgia');
p.textSize(8);
p.textAlign(p.CENTER);
p.text('identified victim', part.x, part.y - part.size - 12);
} else {
p.noStroke();
p.fill(...colors.accent3, 42);
p.circle(part.x, part.y, part.size);
}
}
p.noStroke();
p.fill(...colors.text, 65);
p.textFont('Georgia');
p.textSize(8);
p.textAlign(p.LEFT);
p.text((NUM - 1) + ' others — unseen', 8, p.height - 8);
};
};