p5.js Particle Workshop 1/3
November 22, 2019
A series of code snapshots from day one of the p5.js Particle
To run a snapshots, copy and paste the code into the
sketch.js file in your
own p5.js project, such as one created by cloning the
This is the code boilerplate for a p5.js sketch.
setup function is run once, when the sketch is started.
The code in the
draw function is run once per animation frame.1
draw function is empty, so is the drawing.
draw function now draws a rectangle. The rectangle is 100 pixels wide, and
50 pixels high.
draw function draws the same thing each time, this sketch appears as
a still image — it is not animated.
p5.js maintains graphics state — what color should rectangles (and other shapes) be drawn, should be colored along their edges (“stroke”), interior (“fill”), or both? A function that changes the graphics state, affects the behavior of subsequent drawing functions.
The call to
fill affects the behavior of
rect on the following line.
Changing the fourth
rect argument from
100 makes the rectangle twice
as tall (as it was before). Now it has the same width and height.
Changing the third
rect argument from
200 ought to make the
rectangle twice as wide. But it doesn’t. What’s going on?
All drawing happens on a “canvas”. The default canvas is only 100 pixels wide by 100 pixels high. If we try to draw a larger rectangle, we’re only seeing the left 100 pixels.
The rectangle didn’t appear any larger, becuase the (default) canvas was too
small. Add a function call to the
setup, to make the canvas bigger.
createCanvas directs p5.js to create a canvas of the specified size, instead
of the 100 x 100 canvas that it creates if we don’t specify anything more
createCanvas is inside the
setup function, because it only takes place once
(when the sketch is created). We don’t want a new canvas for each animation
frame; we want to keep drawing on the existing one.
Change the background to dark blue, and make the rectangle large enough to fill the entire canvas.
"blue"), or as mixtures of red, green, and blue light.
p5.js provides variables
windowHeight, whose values are the
width and height of the browser page. If we use these in
setup, the canvas
will be exactly large enough to fill the browser page.
p5.js also provides
height. These are width and height of the
canvas. By changing the
draw to use these, we’ll insure that the
rectangle is exactly large enough to fill the canvas (and, therefore, the page)2.
Draw a smaller rectangle, in white. This will be our first particle.
Once we’ve used
let to define a variable named
particleX whose value is 150,
we can use
particleX instead of
The introduction of these variables changes the source code of the program, but we haven’t changed its behavior.
Now that the particle’s y position is specified by a variable, we can vary it.
This new line increases the value of
particleY by one, each animation frame.
For the first time,
draw has a different behavior each time it runs. (Its
behavior depends on the value of
particleY has a different
value each time it runs — because
draw changes it.)
Our sketch is now an animation.
particleY represents the particle’s (vertical) position, the change to
its position is the particle’s velocity. The particle now has a constant
downwards velocity — it is moving towards (and past) the “ground”.
particleY = particleY + 1 into a new variable, and give it
a name (
dy represents the difference in
particleY’s value between one frame and
the next3. This is a common naming pattern for variables whose values are the
difference between other values.
The rectangle disappears when it passes the bottom of the window. Later, we’ll fix this. For now, you can reload the browser page in order to restart the animation.
dy by a constant amount each time.
dy is the velocity: the rate
at which the value of
0.01 is the rate at which this
velocity increases; it’s the acceleration. In this sketch, the particle has a
constant acceleration, as though it were subject to a constant force. This is
just like objects in the real world, that are subject to gravity.
Increasing a variable’s value by a number is a common operation.
particleX += dx is a shortcut for
particleX = particleX + dx. It is exactly
equivalent, but (1) easier to type, and (2) avoids the risk of a certain typo
particleY = particleX + dy).
This step also demonstrates the practice of commenting out code4. The code that is
being replaced (
particleX = particleX + dx) is disabled by prefixing it with
//, in order to turn it into a comment, that isn’t executed. This allows it
to be used as a visual reference while writing or debugging the new code. Where
it’s not too messy, I like to see the new code working before I completely
delete the code that it replaced.
Now remove the unused code.
(In coding, as with cooking and various other crafts, it is useful to alternate between making messes and cleaning them up, as you go along.)
Part 2 continues these notes.
- p5.js looks for functions named
drawin your sketch, and calls them if they are present.↩
- In this sketch, since we made the canvas the same width and height as the
heighthave the same same value as
windowHeight, we could have used
rect(0, 0, windowWidth, windowHeight)instead of
rect(0, 0, width, height). I chose to use
heightbecause (1) they’re shorter, and (2) this way of doing it is less fragile: it will continue to work if we change our mind later about how large the canvas should be in relation to the browser page.↩
- “d” also stands for “delta”. In math and physics, the Greek letters ẟ and Δ — delta — are used for difference. But this is just because delta is the Greek letter that’s closed to “d”, and “difference” begins with “d”.↩
- Every modern code editor has a keyboard shortcut that comments out the
selected lines of code by adding
//to the beginning of each line — or, removes the initial
//s if all the lines already begin with them, in order to un-comment-out the code. On macOS, this short cut is command-/. On Windows, it’s control-/.↩