Do One Thing
About This Sketch
A visual meditation on ruthless prioritization. Watch as dozens of competing tasks fade away, leaving only the one thing that mattersโgrowing larger, clearer, and more vibrant as distractions disappear into the background.
Algorithm
This sketch visualizes the core argument of "Do One Thing": that true productivity comes from ruthless focus on a single priority while ignoring everything else.
The animation shows two distinct phases. First, dozens of tasks compete for attention, creating visual chaos and cognitive overhead. Then, focus narrows to just one task, which grows larger and clearer while all distractions fade away and disappear.
The primary task pulses with energy and remains centered, while competing priorities are shown as smaller, dimmer circles that eventually vanish. Connections between distraction tasks represent the mental overhead of trying to manage multiple priorities simultaneously.
Pseudocode
SETUP:
Create one primary task at center (larger, brighter)
Create 35 distraction tasks in orbit around it
Set initial phase to "managing everything"
DRAW (looping animation):
Phase 0 - Managing Everything (0-3 seconds):
All tasks jostle and compete for attention
Show connections between nearby distractions
Display chaos of multiple priorities
Label: "Managing everything: constant distraction"
Phase 1 - Focus (3-7 seconds):
Primary task grows larger (reaching 80px)
Primary task pulses with energy
All distraction tasks fade out (alpha decreases)
Remove dead tasks from scene
Label: "Ignore everything else: pure focus"
Phase 2 - Reset:
Return to initial state
Recreate all tasks
Loop the cycle
INTERACTION:
Tasks move towards target positions smoothly
Distraction tasks fade at constant rate
Primary task grows and pulses continuously
Visual metaphor for letting go of distractions
Source Code
let sketch = function(p) {
let tasks = [];
let focusTask = null;
let time = 0;
let phase = 0; // 0: many tasks, 1: focusing on one
class Task {
constructor(x, y, isPrimary) {
this.x = x;
this.y = y;
this.targetX = x;
this.targetY = y;
this.isPrimary = isPrimary;
this.size = isPrimary ? 30 : 12;
this.alpha = isPrimary ? 255 : 150;
this.fadeSpeed = 3;
this.dead = false;
}
update() {
// Move towards target
this.x += (this.targetX - this.x) * 0.05;
this.y += (this.targetY - this.y) * 0.05;
// Fade out non-primary tasks in phase 1
if (phase === 1 && !this.isPrimary) {
this.alpha -= this.fadeSpeed;
if (this.alpha <= 0) {
this.alpha = 0;
this.dead = true;
}
}
// Grow primary task in phase 1
if (phase === 1 && this.isPrimary && this.size < 80) {
this.size += 0.8;
}
}
display(colors) {
if (this.isPrimary) {
// Primary task - bold and clear
p.noStroke();
p.fill(...colors.accent2, this.alpha);
p.circle(this.x, this.y, this.size);
// Pulsing glow
let pulseSize = this.size + p.sin(time * 0.05) * 8;
p.fill(...colors.accent2, this.alpha * 0.2);
p.circle(this.x, this.y, pulseSize);
// Inner highlight
p.fill(...colors.bg, this.alpha * 0.3);
p.circle(this.x, this.y, this.size * 0.4);
} else {
// Distraction tasks - fading away
p.noStroke();
p.fill(...colors.accent3, this.alpha * 0.6);
p.circle(this.x, this.y, this.size);
}
}
}
p.setup = function() {
p.createCanvas(400, 300);
p.colorMode(p.RGB);
// Create the primary task at center
focusTask = new Task(200, 150, true);
tasks.push(focusTask);
// Create many distraction tasks scattered around
for (let i = 0; i < 35; i++) {
let angle = (i / 35) * p.TWO_PI;
let radius = p.random(80, 140);
let x = 200 + p.cos(angle) * radius;
let y = 150 + p.sin(angle) * radius;
tasks.push(new Task(x, y, false));
}
};
p.draw = function() {
const colors = getThemeColors();
p.background(...colors.bg);
time++;
// Phase 0: All tasks competing for attention (first 180 frames)
if (time < 180) {
phase = 0;
// Tasks orbit and jostle
for (let task of tasks) {
if (!task.isPrimary) {
task.targetX = task.x + p.random(-2, 2);
task.targetY = task.y + p.random(-2, 2);
}
}
}
// Phase 1: Focus on one, let others fade (180-420 frames)
else if (time < 420) {
if (phase === 0) {
// Just entered phase 1 - set targets
phase = 1;
focusTask.targetX = 200;
focusTask.targetY = 150;
}
}
// Reset cycle
else if (time > 480) {
time = 0;
phase = 0;
tasks = [];
focusTask = new Task(200, 150, true);
tasks.push(focusTask);
for (let i = 0; i < 35; i++) {
let angle = (i / 35) * p.TWO_PI;
let radius = p.random(80, 140);
let x = 200 + p.cos(angle) * radius;
let y = 150 + p.sin(angle) * radius;
tasks.push(new Task(x, y, false));
}
}
// Update and display all tasks
for (let task of tasks) {
task.update();
task.display(colors);
}
// Remove dead tasks
tasks = tasks.filter(t => !t.dead);
// Draw connections between nearby distraction tasks in phase 0
if (phase === 0) {
p.stroke(...colors.accent3, 30);
p.strokeWeight(1);
for (let i = 0; i < tasks.length; i++) {
for (let j = i + 1; j < tasks.length; j++) {
let d = p.dist(tasks[i].x, tasks[i].y, tasks[j].x, tasks[j].y);
if (d < 60 && !tasks[i].isPrimary && !tasks[j].isPrimary) {
p.line(tasks[i].x, tasks[i].y, tasks[j].x, tasks[j].y);
}
}
}
}
// Labels
p.noStroke();
p.fill(...colors.accent3, 180);
p.textAlign(p.CENTER);
p.textSize(11);
if (phase === 0) {
p.text('Managing everything: constant distraction', 200, 280);
p.textSize(9);
let nonPrimaryCount = tasks.filter(t => !t.isPrimary).length;
p.text(`(${nonPrimaryCount} competing priorities)`, 200, 20);
} else {
p.text('Ignore everything else: pure focus', 200, 280);
p.textSize(9);
let remaining = tasks.filter(t => !t.isPrimary && t.alpha > 0).length;
if (remaining > 0) {
p.text(`(${remaining} distractions fading...)`, 200, 20);
} else {
p.text('(one thing)', 200, 20);
}
}
// Task count
p.textAlign(p.RIGHT);
p.textSize(10);
p.fill(...colors.accent2, 150);
p.text(`Active: ${tasks.length}`, 390, 290);
};
};