p5.js overview

Kenneth Lim edited this page Oct 11, 2016 · 19 revisions

p5.js is a JavaScript library that starts with the original goal of Processing—to make coding accessible for artists, designers, educators, and beginners—and reinterprets this for today's web.

Using the original metaphor of a software sketchbook, p5.js has a full set of drawing functionality. However, you're not limited to your drawing canvas, you can think of your whole browser page as your sketch! For this, p5.js has addon libraries that make it easy to interact with other HTML5 objects, including text, input, video, webcam, and sound.

p5.js is a new interpretation, not an emulation or port, and it is in active development. You can also read how this differs from processing.js, or about how this relates to Processing.

Hello world

Please see the get started page for instructions for setting up your editing environment and project.

There are two main functions you will use in your program. The setup() block runs once, and is typically used for initialization, or for creating a program that does not need a loop running code repeatedly. The draw() block runs repeatedly, and is used for animation.

For your first "Hello World" program, create a setup() block and add one line:

function setup() {
  line(15, 25, 70, 90);
}

If you view this in your browser, you should see a single line.

Adding a draw() block enables you to incorporate animation. In the example below, a variable is updated every time draw() runs, moving a circle across the screen.

var x = 0;

function setup() {
  background(100);  
}

function draw() {
  ellipse(x, height/2, 20, 20);
  x = x + 1;
}

There is a full set of 2D drawing methods, to create and styles graphics, text, and images. See the reference for the full listing, and the examples page.

createCanvas

By default, the drawing canvas has a size of 100x100. If you want to set a custom size, use the createCanvas() function. It is a good idea to always make this the first line in setup(). The code below sets the canvas to size 600x400:

function setup() {
  createCanvas(600, 400);
  line(15, 25, 70, 90);
}

createCanvas() will create a new drawing canvas in the size specified and append it to the html page you are working with. If there is other content in the body of your html page, it will add on to the page after that, so you may not see it at the top of the window.

The canvas will also be affected by any existing css (styling) on the page, including default set by your browser. For example, a lot of browsers have a default padding around the end of the page. If you are noticing that your canvas isn't all the way at the upper left corner of your window, this is probably why. To fix this, you can add a line to the <head> of your html file that overrides the default padding, like this:

<style> body{padding:0; margin:0;} </style>

If you would like to specify a location for the canvas, rather than appending directly to the end, you can use the parent() method. In the <body> of your html file, create a container where you would like your canvas to get inserted, with ID of your choice:

<div id='myContainer'></div>

Then use a variable to store a pointer to the canvas you created, and call .parent() on this variable:

function setup() {
  var myCanvas = createCanvas(600, 400);
  myCanvas.parent('myContainer');
}

The p5.js API provides a lot of functionality for creating graphics, but there is some native HTML5 Canvas functionality that is not exposed by p5. You can still call it directly using the variable drawingContext, as in the example below. See this reference for the native canvas API.

function setup() {
  drawingContext.shadowOffsetX = 5;
  drawingContext.shadowOffsetY = -5;
  drawingContext.shadowBlur = 10;
  drawingContext.shadowColor = "black";
  background(200);
  ellipse(width/2, height/2, 50, 50);
}

Mouse and touch interaction

p5.js has a set of methods for handling mouse and touch interaction. The list below shows how they relate conceptually.

mouse touch
mouseX touchX
mouseY touchY
touches[]
mouseIsPressed
mousePressed() touchStarted()
mouseMoved()
mouseDragged() touchMoved()
mouseReleased() touchEnded()
mouseClicked()
mouseScrolled()

You may notice with touch, unless you have defined a touchStarted() method, the screen may react with default touch behavior for your mobile device (i.e. your whole screen view may move around when you drag your finger). If you add an empty touchStarted() method, you should see this stop.

Many browsers have default behaviors for various interactions. For example, touchMoved on a mobile device may result in dragging the whole window. To prevent these behaviors, add a return false line at the end of your defined functions.

function touchMoved() {
  // do some stuff
  return false;
}

Asynchronous calls and file loading

JS is single threaded and synchronous, meaning one line of code completes before the next one runs. However, there are asynchronous functions used that make the program flow faster. Loading images, external files, and URLs are generally handled by async functions. (Note: Loading files from the sketch folder will require that you are running a local server, see here for a tutorial about how to set one up on your computer.)

Callbacks

All of the load functions will accept a callback function as an optional last argument. In the following example, an image is drawn once it is loaded.

function setup() {
  createCanvas(400, 240);
  loadImage('cat.jpg', drawCat);
}

function drawCat(img) {
  image(img, 0, 0);
}

Compare this to calling image() directly after loadImage(), which ends up blank:

function setup() {
  createCanvas(400, 240);
  var img = loadImage('cat.jpg');
  image(img, 0, 0);
}

Preload

Alternatively, you could use the preload() function. If a preload() block exists it runs first, then setup() will wait until everything in there has completed before it gets run, so you can make use of things loaded in preload in setup and draw. Note that nothing else should be in preload besides load calls, all other initialization should happen in setup. No callbacks are required for load functions in preload.

var img;
function preload() {
  img = loadImage('cat.jpg');
}

function setup() {
  createCanvas(400, 240);
  image(img, 0, 0);
}

Loading Screen

As mentioned above, if your sketch has large media dependancies such as images, audio or videos, these should be loaded into your sketch using the preload() function. Since loading large files can take some time, you might want to display a loading screen to your users. This will convey that your sketch is indeed running — it just has a lot of cool things to load first. To add a loading screen to your p5.js sketch, all you need to do is include an HTML element on your page the id p5_loading. It would look something like the following:

<div id="p5_loading" class="loadingclass">this could be some sweet graphics loading lots of bits.</div>

P5.js looks through your HTML to see if you have included an element with the id p5_loading. P5.js will use this element and its content as the loading screen for your sketch. Since the loading element is included in your HTML, you can add any additional classes and/or style the element anyway you see fit.

For an example of a sketch using a loading screen refer to examples/loadingscreen/index.html in the p5.js source.

Browser functions and native JavaScript

There are a few variables and functions that make browser interaction easier, many more to come!

You should also be able to use any native JS functions in your p5.js sketch without a problem, the MDN JavaScript reference is a good place to learn more. Read the next section to learn how to make p5 play extra nice with the rest of your project.

Instantiation / namespace

By default, all p5.js functions are in the global namespace (i.e. bound to the window object), meaning you can call them simply ellipse(), fill(), etc. However, this might be inconvenient if you are mixing with other JS libraries (synchronously or asynchronously) or writing long programs of your own. p5.js currently supports two ways around this problem: "instance mode" and "on-demand global mode". In instance mode, all p5 functions are bound up in a single variable instead of polluting your global namespace.

Consider a program like this:

var x = 100;
var y = 100;

function setup() {
  createCanvas(200,200);
}

function draw() {
  background(0);
  fill(255);
  ellipse(x,y,50,50);
}

A conversion to "instance mode" looks like this:

var s = function( p ) {

  var x = 100; 
  var y = 100;

  p.setup = function() {
    p.createCanvas(700, 410);
  };

  p.draw = function() {
    p.background(0);
    p.fill(255);
    p.rect(x,y,50,50);
  };
};

var myp5 = new p5(s);

Optionally, you can specify a default container for the canvas and any other elements to append to with a second argument. You can give the ID of an element in your html, or an html node itself:

var myp5 = new p5(s, 'myContainer');

Note that creating instances like this also allows you to have more than one p5 sketch on a single web page, as they will each be wrapped up with their own set up variables. Of course, you could use iframes to have multiple sketches in global mode.

Another option is on-demand global mode. To initialize on-demand global mode at any point in a web page's lifetime, simply call new p5() without any arguments. Calling p5 explicitly this way gives you more control over how your sketch is loaded, which is helpful when you’re working with other libraries.

Along these lines, on-demand global mode also allows p5 to be instantiated before page load, so folks who really want to work around the assigning variables using p5 functions and variables before setup limitation can write the following sorts of sketches:

new p5();

var boop = random(100);

function setup() {
    createCanvas(100, 100);
}

function draw() {
    background(255, 0, boop);
}

Libraries

One of the core ideas behind p5.js is that your sketch is not just the graphics canvas but the whole web page in your browser. For this reason, there is the p5.dom library that makes it easy to interact with other HTML5 objects, including text, hyperlink, image, input, video, audio, and webcam. There is also a p5.sound library that provides a friendly interface to HTML5 web audio API for loading, playing, and synthesizing sounds.

Learn how to use these libraries or develop your own here.

Editor

You can use any editing environment you like, in addition, a p5.js editor is in development, you can try out the alpha version now. The p5.js editor handles setting up projects and runs a local server for you. You can usually run p5.js sketches without a server, but it is required if you are doing certain things like loading external files. Here are instructions for setting up a local server.