Variables & Animation
Use variables to store state and create motion — bouncing balls, growing shapes, drifting particles.
Variables in JavaScript
A variable is a named container for a value. In JavaScript, declare variables with let or const:
let x = 100; // can be reassigned later
const speed = 2; // cannot be reassigned (constant)
In creative coding, let is more common because most values change over time.
Where to declare variables
Variables used across both setup() and draw() must be declared outside both functions, at the top level:
let x = 0; // accessible everywhere
function setup() {
createCanvas(600, 400);
}
function draw() {
background(20);
circle(x, 200, 40);
x = x + 2; // or: x += 2
}
If you declare let x inside draw(), it resets to its initial value every single frame — usually not what you want.
A bouncing ball
Classic first animation — a ball that bounces off the walls:
let x, y; // position
let vx, vy; // velocity (speed + direction)
function setup() {
createCanvas(600, 400);
x = width / 2;
y = height / 2;
vx = 3;
vy = 2;
}
function draw() {
background(20);
// Move
x += vx;
y += vy;
// Bounce off left/right walls
if (x < 20 || x > width - 20) {
vx *= -1;
}
// Bounce off top/bottom
if (y < 20 || y > height - 20) {
vy *= -1;
}
// Draw
fill(100, 200, 255);
noStroke();
circle(x, y, 40);
}
The key idea: vx and vy are the velocity. Every frame, position is updated by velocity. When the ball hits a wall, velocity in that direction is flipped (multiplied by -1).
Using frameCount for time
frameCount increments by 1 every frame. Use it to drive animations that repeat or evolve:
function draw() {
background(20);
// Oscillate with sin() — value bounces smoothly between -1 and +1
let t = frameCount * 0.02; // slow time
let osc = sin(t); // -1 to 1
let size = map(osc, -1, 1, 20, 150); // 20 to 150
fill(200, 100, 255);
noStroke();
circle(width / 2, height / 2, size);
}
sin() and cos() are your best friends in animation — they produce smooth, cyclical values. The pattern sin(frameCount * speed) is everywhere in creative coding.
Multiple variables — a spiral
let angle = 0;
let radius = 0;
function setup() {
createCanvas(600, 600);
background(20);
noLoop();
stroke(100, 200, 255, 180);
strokeWeight(1.5);
noFill();
beginShape();
for (let i = 0; i < 600; i++) {
let x = width / 2 + cos(angle) * radius;
let y = height / 2 + sin(angle) * radius;
vertex(x, y);
angle += 0.15;
radius += 0.4;
}
endShape();
}
Easing — smooth follow
Instead of snapping directly to a target, interpolate toward it:
let x = 300;
let y = 200;
function draw() {
background(20);
// Ease toward mouse — move 10% of the remaining distance each frame
x += (mouseX - x) * 0.1;
y += (mouseY - y) * 0.1;
fill(255, 150, 50);
noStroke();
circle(x, y, 40);
}
The factor (0.1 here) controls the lag. 0.05 = very sluggish, 0.5 = almost instant.
lerp() — linear interpolation
lerp(start, stop, amount) returns a value between start and stop:
let x = 0;
function draw() {
x = lerp(x, mouseX, 0.1); // same easing as above, cleaner
// ...
}
Multiple animated objects with arrays
Managing many objects with individual variables becomes unworkable. Taste of what’s coming in the Beginner level:
let circles = [];
function setup() {
createCanvas(600, 400);
for (let i = 0; i < 20; i++) {
circles.push({
x: random(width),
y: random(height),
vx: random(-2, 2),
vy: random(-2, 2),
r: random(10, 30)
});
}
}
function draw() {
background(20);
noStroke();
for (let c of circles) {
c.x += c.vx;
c.y += c.vy;
if (c.x < 0 || c.x > width) c.vx *= -1;
if (c.y < 0 || c.y > height) c.vy *= -1;
fill(100 + c.r * 3, 150, 255, 180);
circle(c.x, c.y, c.r * 2);
}
}
Key takeaways
- Declare variables outside
setup()anddraw()if they need to persist between frames - Update position by adding velocity each frame:
x += vx - Reverse velocity to bounce:
vx *= -1 sin(frameCount * speed)creates smooth oscillation- Easing (
x += (target - x) * 0.1) gives smooth, organic motion lerp(start, stop, t)interpolates linearly between two values