The Creative Coder’s Field Guide

Everything You Need to Survive and Thrive with p5.js

Creative Coding · Week 1

First-Sketch

Everything the first week of p5.js stands on: the canvas, the grid it draws on, functions, draw() running again and again, and how color works. Keep it next to the editor.

JavaScript + p5.js · editor.p5js.org · Understand → Know → Do
01The setup

JavaScript, p5, and a canvas

Three things are in play, and it helps to keep them straight.

  • JavaScript is the language you write. It has its own grammar and rules.
  • p5 is a library: a big pile of pre-written JavaScript that other people made so you don't have to. It hands you ready-made commands for drawing and animation.
  • The canvas is where p5 draws: a rectangle made of pixels, sitting on a web page. You create it once and everything appears there.

So the full picture: you write JavaScript, you lean on p5's commands, and the result shows up on the canvas.

02Tools

The p5 web editor

  • Log in so your work saves to your account instead of vanishing.
  • Name each sketch, then Save. Use Open to get back to old ones.
  • Duplicate makes a copy you can experiment on without losing the original.
  • Share gives you a link: present, edit, or embed.
  • Tidy Code (Cmd/Ctrl - Shift - F) auto-fixes your indentation and spacing. Do it often.

Recommended settings

Find these under the gear icon / Preferences. Set them once and forget about them.

SettingSet it toWhy
AutosaveOnSaves periodically in the background, but it only kicks in after you've saved the sketch manually once, and it isn't perfect. Keep hitting Save yourself too.
ThemeDarkThe editor only offers Dark while you're logged in. Set it once, and if the editor ever looks light again, that's your sign you got logged out.
Auto-RefreshOffOtherwise the sketch reruns on every keystroke, restarting your animation mid-thought. Refresh manually when you want to see the change.
03The grid

The Cartesian Coordinate Plane (CCP)

Every position on the canvas is a pair of numbers, (x, y), that maps to a horizontal and vertical spot.

  • x: how many pixels from the left edge. Bigger x moves right.
  • y: how many pixels from the top edge. Bigger y moves down. (Not like math class, because the plane is flipped vertically.)
  • width: the total number of pixels across.
  • height: the total number of pixels from top to bottom.

The origin (0, 0) is the top-left corner.

x → pixels from the left edge y → pixels from the top edge (grows downward) (0, 0) (width, 0) (0, height) (width, height) ( width / 2 , height / 2 )
The canvas is one quadrant with the origin pinned to the top-left. Both axes count away from that corner, so y runs the opposite direction from the graphs you've seen before.

Corners & center, given width and height

PointCoordinate
Top-left (origin)(0, 0)
Top-right(width, 0)
Bottom-left(0, height)
Bottom-right(width, height)
Center(width / 2, height / 2)

Be able to do

For a canvas created with createCanvas(400, 300): the corners are (0,0), (400,0), (0,300), (400,300), and the center is (200, 150). Practice this until it's instant for any width and height.

04Commands

Functions

A function is a command: a named bundle of instructions. Two different things happen with functions, and mixing them up is the classic first-week confusion:

  • Defining a function means writing out what it does. function setup() { … } means “here is what setup means.” Nothing runs yet.
  • Calling a function means saying its name to make it run now. createCanvas(400, 400) is a call.

This week you only call functions. Writing your own from scratch comes in Week 5. The one thing that looks like defining, function setup() and function draw(), is really you filling in a body that p5 already asked for (see section 06).

Parameters

The values inside the parentheses are parameters (also called arguments): the specifics a function needs to do its job. circle(x, y, d) can't draw anything until it knows where and how big. Parameters are what let one function handle every case instead of just one.

createCanvas(400, 400) the function's name (a p5 command) the parameters width, then height parentheses always follow the name even when empty
Reading a call left to right: name, then parentheses, then the parameters inside them. createCanvas() with nothing in the parentheses is still a valid call, because the parentheses are non-negotiable.

p5 ships with a long list of prefab functions, including createCanvas, background, fill, stroke, circle, ellipse, rect, line, and text, plus a few prefab values like width and height. Two special functions, setup and draw, are ones p5 expects you to write the body of.

05Preview

Variables (we'll dig in next week)

A variable is a labeled container that holds a piece of data: a number, some text, a color. The data might change over time, or it might not.

p5 keeps a handful of these filled in for you automatically, so you can use them right away without ever writing one yourself:

VariableHolds
widthThe canvas's width, in pixels
heightThe canvas's height, in pixels
mouseXThe mouse's current x position
mouseYThe mouse's current y position

Notice you never had to set any of these: p5 updates them for you, every frame. Making your own variables, and using them to move things around, is next week.

06Program Flow

setup() and draw()

These are the two functions whose bodies you write and p5 calls. You never call them yourself: you fill them in, and p5 runs them on a schedule. (Writing functions of your own, from nothing, is Week 5.)

  • setup() runs once, first. It's for one-time jobs, above all createCanvas().
  • draw() runs right after, then again and again, about 60 times per second, forever.
  • Each single run of draw() is one frame.
setup() runs once createCanvas(), starting values draw() draw() draw() draw() frame 1 frame 2 frame 3 frame 4 ≈ 60 frames every second, forever p5 calls it again
You supply the bodies of setup() and draw(); p5 owns the clock. That's why the starting state goes in setup() and anything that should update goes in draw().
07Order

Order of operations inside a frame

Within one draw(), lines run top to bottom, and two habits matter.

background() wipes the canvas

background(...) paints over the entire canvas in one color. Put it at the top of draw() to erase the previous frame before drawing the new one. It takes a color in the same formats as fill(), e.g. background(220) for light grey.

fill() and stroke() are not attached to shapes

They set the “current” fill and outline color, like picking up a colored pen. Every shape drawn after uses that color until you pick up a different one.

fill(230, 60, 90) circle(120, 110, 44) circle(180, 110, 44) fill(12, 124, 140) circle(240, 110, 44) runs top → bottom current fill rose teal ← rose ← still rose ← teal
The second circle is rose even though no color was set right before it, because it inherits whatever fill() was last called. Change the pen once and it stays changed.

Rule of thumb: set fill() / stroke() before the shape you want them to affect, not after.

08Shapes

Drawing 2D shapes

Each shape is a function call. The parameters are coordinates and sizes, in pixels, so knowing the coordinate plane (section 03) is what makes these usable.

CallWhat it draws
point(x, y)A single pixel: set strokeWeight(4) or more first, or it's almost invisible
line(x1, y1, x2, y2)A straight segment between two points
rect(x, y, w, h)A rectangle, anchored at its top-left corner
square(x, y, s)A square, also from the top-left corner
ellipse(x, y, w, h)An ellipse, anchored at its center
circle(x, y, d)A circle from its center; d is the diameter
triangle(x1, y1, x2, y2, x3, y3)A triangle through three points
quad(x1, y1, … x4, y4)A four-sided shape through four points
(x, y) w h rect(x, y, w, h) from the top-left corner (x, y) ellipse(x, y, w, h) from the center
The commonest early surprise: rect measures from a corner, but ellipse and circle measure from the middle. rectMode(CENTER) switches the rectangle to center-anchored if you want them to match.

rectMode() and ellipseMode() both take the same four modes as their setting; they just start from different defaults, which is why the two shapes disagree by default.

Modex, y isw, h isDefault for
CORNERa cornerwidth, heightrect()
CENTERthe centerwidth, heightellipse(), circle()
RADIUSthe centerhalf-width, half-heightn/a
CORNERSone cornerthe opposite corner (a point, not a size)n/a

Call rectMode(CENTER) or ellipseMode(RADIUS) once, near the top of setup(), and every call to that shape uses the new mode from then on: it's state, same as fill().

Shaping the line and fill

  • strokeWeight(n): outline thickness in pixels. It also sets how big a point() draws, so keep it above 2 when you're plotting points.
  • noFill(): draw the outline only.
  • noStroke(): draw the fill only, no outline.

Like fill() and stroke(), these are all state (section 07), so set them before the shapes they should affect.

Advanced

Curves

arc(x, y, w, h, start, stop) draws a slice of an ellipse. Start and stop angles are in radians (0 to TWO_PI), or call angleMode(DEGREES) first to use 0360.

arc(x, y, w, h, start, stop) swept in radians (x, y) start stop w h
The bounding box (w, h) is invisible: only the wedge from start to stop actually gets drawn.

bezier(x1, y1, cx1, cy1, cx2, cy2, x2, y2) draws a smooth curve between two endpoints, bent by two control points.

bezier(x1, y1, cx1, cy1, cx2, cy2, x2, y2) (cx1, cy1) (cx2, cy2) (x1, y1) (x2, y2)
The curve always touches its two endpoints. The control points never touch it; they just pull it toward themselves, like magnets behind the page.

beginShape()vertex(x, y)endShape() connect a list of points into a freeform outline.

beginShape() vertex(x1, y1) vertex(x2, y2) vertex(x3, y3) vertex(x4, y4) endShape() runs top → bottom 1 2 3 4 only with endShape(CLOSE)
Each vertex() adds one point, joined to the point before it. The dashed edge back to point 1 only appears if you finish with endShape(CLOSE) instead of a plain endShape().
09Color

Defining color

A color is a parameter like any other: you hand one to fill(), stroke(), or background(), and the command uses it. Before the code, though, it helps to know how a screen makes color at all.

Screens mix light, not paint

Every pixel on your screen is really three tiny lights packed side by side: one red, one green, one blue. They're far too small to see separately, so their glow blends into a single color. Turn all three up to full power and the pixel looks white; turn them all off and it's black; every other color is some in-between recipe of the three.

Notice that this is the opposite of mixing paint: paint gets darker the more you add, light gets brighter. And it means every color format below is secretly writing down the same one thing: how strong each of the three lights should be.

Three ways to write the same recipe

All three formats describe the same colors, so pick whichever is easiest to think in. p5 assumes RGB unless you tell it otherwise.

RGB, the default

R
230
G
60
B
90

Three numbers, always in the same order: red, green, blue. Each one is a light's strength, from 0 (off) to 255 (as bright as it goes). So fill(230, 60, 90) says “red almost full, only a little green, some blue,” which blends into the raspberry pink above.

Shortcut: give just one number and p5 sets all three lights to it. Equal amounts of red, green, and blue always make a grey, so fill(0) is black, fill(255) is white, and fill(120) is a middle grey.

Hex string, the shortcut

#E63C5A
R: 230G: 60B: 90

The same three numbers in disguise, squeezed into one code borrowed from the web. After the #, each pair of characters is one channel: red, green, blue, same order as always. Letters show up because hex counts past 9 with A–F, so 00 is 0 and FF is 255.

Nobody converts these in their head. You copy them out of a color picker and paste them in quotes: fill('#E63C5A'). Color names in quotes work too: fill('tomato'), background('white').

HSB / HSV, the alternative

  • Hue is which color: an angle around the wheel, 0360
  • Saturation is how vivid: 0 washed-out grey → 100 full strength
  • Brightness (also called Value) runs 0 black → 100 fully lit

RGB is how the machine thinks; HSB is closer to how you'd describe a color out loud: pick the color, then say how vivid and how bright. Tell p5 to switch with colorMode(HSB), then fill(340, 78, 90).

Its superpower: the three sliders match how you think, so “same color but darker” or “sweep through the rainbow” means nudging just one number.

10Syntax

JavaScript to recognize on sight

Syntax is a language's grammar: the rules for how words, symbols, and punctuation have to be arranged before it counts as valid. It's different from vocabulary: p5 function names like circle() or fill() are vocabulary, specific to p5. The parentheses around their parameters, the semicolon that ends the line, and the braces that wrap a block are JavaScript's syntax, and it's the same no matter which functions you're calling.

Unlike English, this grammar isn't a suggestion. A person can untangle a sentence missing a comma; the computer can't guess what a missing brace or parenthesis was supposed to mean, so it just stops. That's also why syntax is worth learning to recognize early: most of your first error messages will be some flavor of “your syntax is broken here,” and being able to name what you're looking at makes them far less mysterious.

You don't need to have mastered these yet; you need to know what they're called and roughly what they're for.

CategoryWhat you'll see
Keywordslet, function, if, else if, else, for
Operators=   + - * /   ++ --   += -= *= /=: just know these are operators; the details come later
Parentheses ( )Hold a function's parameters, and group conditions
Braces { }Wrap the block of statements that belong to a function, loop, or if
Semicolon ;Ends a statement. Technically optional, but use them anyway
Comments //Everything after // on a line is ignored. Toggle with Cmd/Ctrl - /
IndentationOptional for the computer, essential for humans. Keep it consistent
11Practice

Be able to do

Locate the five key points

Given any width and height, name the coordinates of all four corners and the center, without hesitating.

Name what you're doing

You are defining setup() and draw(). Inside them, you are calling createCanvas(), background(), fill(), and the shape functions.

Decide: setup() or draw()?

run again every frame? no setup() yes draw() canvas size, start values background(), shapes, mouse response

Describe a circle's starting position

“It starts at the center, (width/2, height/2)” or a corner, or 50 pixels in from the left edge. That decision is a setup() job, because it happens once.

Build a picture from basic shapes

Sketch a simple house or face on graph paper, read off the coordinates, then reproduce it with rect, ellipse, triangle, and line, remembering that rect starts at a corner and ellipse at the center. Going further: add a smile with arc() or a curved roofline with bezier().

Describe mouse interaction

p5 keeps mouseX and mouseY filled with the cursor's current position. Reading them belongs in draw(), so the sketch checks where the mouse is on every frame, e.g. “draw the circle at (mouseX, mouseY) so it follows the pointer.”