Anatomy of a (p5.js) Sketch

Disclaimer: This is not JavaScript (JS) 101. To get started with JS please read these articles on MDN.

This article is focused on getting you up and running with p5.js

Sketch Building Blocks

The most common building blocks of a sketch are setup, draw and the global and local scope. Below you see a very basic sketch that actually does nothing. Roll over the different areas to visualize their scope.

				
					
const globalVariable = 123;
function setup() { const scopedSetupVariable = "Only in setup"; console.log(globalVariable); // 123 }
function draw(){ console.log(globalVariable); // 123 console.log(scopedSetupVariable); // undefined const scopedDrawVariable = "Only in draw";
if(true){ let blockScopedVariable = "Only in block!" console.log(scopedDrawVariable); // Only in draw }
console.log(blockScopedVariable); // undefined }

Scopes (global and local)

In JavaScript (JS) and other programming languages we encounter the idea of scopes. That means something like a variable is bound to a specific area of the code. Functions can have their own scope, there are block scopes and there is something called the global scope where everything exists inside. We can even declare our own scopes in JS by wrapping some part of the code into curly brackets.

Why is this useful? For one thing it allows us to reuse variable names without overwriting other parts of the program. We can define which variables are available to which part of the program. It also enables use to write more conscious code that does not leak into other areas of the program. Code that has less sideeffects. To make sure that we use the scoping features of JS we always should use const and let to define our variables, never var.

let is for variables that change over the course of our programm, const is for constant variables. var is the old way to declare variables and should be avoided since they are not scoped. To learn more about the difference take a look at this article: "Grammar and types - JavaScript - Variable scope | MDN"

When you write p5.js sketches you declare the things you want to use throughout your programm in the global scope at the top. When something is only needed in the setup, the draw, another function, or even the block scope of an if or for statement you declare them inside of that scope (the curly brackets ). To sum this up.

setup()

The setup is the area of your code where you initilze things, like calculating a value you need or setting up 1000 particles for your program. You name it. The setup is executed once you load the page/sketch and the code inside will be executed from top to bottom. Of course you can also ue drawing commands in the setup but you won't be able to make things interactive. As the function name says you set things up.

You should not try to load other resources like images, fonts or data from some file in the setup. p5.js has a specilized function for that. The preload. This function will run before your setup and draw and will also wait until all things are done loading.

draw()

The draw (also as the name says) is there for drawing and making things interactive. It is executed all the time and the code inside will also be evalutated from top to bottom. The speed of the program depends on many things. The resources of your computer and of course the amount of calculations that need to be done. You could see the draw as the main function of your program where all things should flow together.

Due to JavaScript's asynchronous nature and the browser's event-based system, drawing and interactivity can also occur in other functions. This is a more advanced topic for later discussion.

Other Magic Functions

Both of these functions are somehow magically executed. There are also others like these. For example there is the mousePressed function that is executed everytime the mouse is pressed. (duh!). Or the preload function as already mentioned above. To use these you declare them besides your setup and draw in the global scope. (There are even more of these functions but we won't list them all here.)


	function preload()
	function setup()
	function draw()
	function mousePressed()
	

Besides these "magic" functions that are declared in global scope and executed automagically there are other functions we use to manipulate or generate things. For example there is the random functio which generates random numbers for us. Or the createCanvas function, that allows us to manipulate the size of the canvas where we draw onto. The point, rect, circle, line functions to draw primitive shapes. And so on. There are many specialized functions that we will have to discuss and learn. The most important thing is. The names of these function are some kind of reserved by p5.js. They wont throw an error in the browser console when we try to use them in a different way (not like reserved words for JS). At least p5.js will give you a friendly error when you do that.

Sketch

In the above sketch we make use of many concepts we discussed above. We declare the global mutable variables x and y both with the value 50 in the global scope so they are both available in setup and draw.

Within the setup we use createCanvas function to create drawing area with a size of 100 pixel width and 100 pixel height and assign it to the immutable const variable canvas. Then we call a function of the canvas object canvas.parent() to put it into the right element in the DOM. The element with the attribute id set to sketch. Then we set 3 things for the drawing context of p5.js. The background for the canvas. The stroke color and the fill color. The stroke and fill affect all elements we create after these command is called until we reset them again. The context of p5.js keeps track of these information which colors to use. These values will be valid also in the draw function.

In the draw we declare two immutable locallly scoped variables called previousX and previousY and store the current value x and y before we reassign them with a random value in the range between 10 and 90. This allows us to draw a line from the previous x/y value to the newly calculated one. After the line we draw a circle at x/y with a radius of 10 pixels.

Tasks

Referenced Methods