Functions & Code Organisation
Write your own functions to break sketches into manageable, reusable parts.
Why functions matter
As your sketches grow beyond 50 lines, you’ll start noticing problems: draw() becomes a wall of code, the same calculations appear in multiple places, and changing anything feels risky. Functions solve all of this.
A function is a named, reusable block of code. You define it once and call it whenever you need it.
Defining and calling a function
// Definition
function drawStar(x, y) {
// draws a simple 4-pointed star
push();
translate(x, y);
fill(255, 220, 50);
noStroke();
rect(-5, -20, 10, 40);
rect(-20, -5, 40, 10);
pop();
}
function draw() {
background(20);
// Call it as many times as you like
drawStar(100, 200);
drawStar(300, 150);
drawStar(500, 250);
}
drawStar(x, y) is called with two arguments (100 and 200). Inside the function, these arrive as parameters x and y.
Parameters and default values
You can give parameters default values — the caller can then omit them:
function drawCircleRing(x, y, radius = 80, count = 8, dotSize = 12) {
for (let i = 0; i < count; i++) {
let angle = TWO_PI / count * i;
let px = x + cos(angle) * radius;
let py = y + sin(angle) * radius;
circle(px, py, dotSize);
}
}
function draw() {
background(20);
fill(200, 100, 255);
noStroke();
drawCircleRing(200, 200); // uses all defaults
drawCircleRing(450, 200, 60, 12); // custom radius and count
}
Return values
Functions can compute something and return it:
function hexToRgb(hex) {
let r = unhex(hex.slice(1, 3));
let g = unhex(hex.slice(3, 5));
let b = unhex(hex.slice(5, 7));
return color(r, g, b);
}
// Or simpler examples:
function clamp(val, lo, hi) {
return max(lo, min(hi, val));
}
function randomFrom(arr) {
return arr[floor(random(arr.length))];
}
Use return to send a value back to the caller:
let palette = ['#ff6432', '#3b82f6', '#22c55e', '#f59e0b'];
let c = randomFrom(palette);
fill(c);
Organising a complex sketch
Here is how you’d break a sketch into logical functions:
// ── State ──────────────────────────────────
let particles = [];
const NUM_PARTICLES = 80;
// ── Lifecycle ──────────────────────────────
function setup() {
createCanvas(700, 500);
initParticles();
}
function draw() {
drawBackground();
updateParticles();
drawParticles();
drawHUD();
}
// ── Initialisation ─────────────────────────
function initParticles() {
for (let i = 0; i < NUM_PARTICLES; i++) {
particles.push(createParticle());
}
}
function createParticle() {
return {
x: random(width),
y: random(height),
vx: random(-1.5, 1.5),
vy: random(-1.5, 1.5),
r: random(4, 14),
hue: random(180, 280)
};
}
// ── Update ─────────────────────────────────
function updateParticles() {
for (let p of particles) {
p.x += p.vx;
p.y += p.vy;
if (p.x < 0 || p.x > width) p.vx *= -1;
if (p.y < 0 || p.y > height) p.vy *= -1;
}
}
// ── Drawing ────────────────────────────────
function drawBackground() {
background(15, 15, 25, 30);
}
function drawParticles() {
colorMode(HSB, 360, 100, 100, 100);
noStroke();
for (let p of particles) {
fill(p.hue, 70, 90, 80);
circle(p.x, p.y, p.r * 2);
}
}
function drawHUD() {
colorMode(RGB);
fill(255);
noStroke();
textSize(12);
text(`${particles.length} particles`, 10, 20);
}
This separation — state, lifecycle, init, update, draw — makes each section easy to reason about independently.
Pure functions
A pure function has no side effects: it only reads its inputs and returns a value. Strive for pure functions wherever possible — they’re easier to test and reuse:
// Pure — returns a new object, doesn't modify anything
function stepParticle(p) {
return {
...p,
x: p.x + p.vx,
y: p.y + p.vy
};
}
// Impure — modifies the particle in place
function stepParticle(p) {
p.x += p.vx; // modifies input
p.y += p.vy;
}
Both approaches work; the pure version is safer in complex sketches.
Key takeaways
- Functions break your sketch into named, reusable blocks
- Parameters let you customise behaviour at call time; default values make parameters optional
returnsends a computed value back to the caller- Split your sketch into setup, update, and draw functions — your future self will thank you
- Aim for small functions that do one thing well