p5.layers is a p5.js library that simplifies some common use cases for p5.js Graphics objects.

It does this by addings this functionality to p5.js:

trail example animation trail example animation

For example:

circle(width / 2, height / 2, 100);

is equivalent to:

let pg = createGraphics(100, 100);
pg.circle(pg.width / 2, pg.height / 2, 100);
image(pg, 0, 0);

The version with beginLayer() doesn’t require the use of pg. as a prefix in order to affect the created Graphics. This simplifies the tasks of modifying a sketch so that different parts of it use different layers, and sharing functions between sections of the sketch that draw onto the canvas and sections that draw onto a layer.

The Graphics instances that beginLayer() creates persist across calls to draw(). For example, the following code, from examples/lissajous/sketch.js, leaves a trail of circles, because the layer is only partially erased (the second argument to background() is a value that indicates partial opacity). It is drawn onto a canvas that is completely erased each frame, as required by the other code in the draw() function in that file.

  background(100, 10);
  let x = map(sin(millis() / 500), -1, 1, 0, width);
  let y = map(sin(millis() / 700), -1, 1, 0, height);
  circle(x, y, 20);

The equivalent functionality, without using beginLayer() and endLayer(), would require code that is distributed among setup(), draw(), and the global context:

let pg;

// in setup():
  pg = createGraphics(width, height);

// in draw():
  pg.background(100, 10);
  let x = map(sin(millis() / 500), -1, 1, 0, pg.width);
  let y = map(sin(millis() / 700), -1, 1, 0, pg.height);
  pg.circle(x, y, 20);
  image(pg, 0, 0);


Download p5.layer.js from this repository and include it in your HTML document:

<script src="p5.layers.js" type="text/javascript"></script>

Or, use the online version:

<script src="https://unpkg.com/p5.layers@0.0/p5.layers.js" type="text/javascript"></script>



Sets the p5.js global functions background(), draw() etc. to render into the specified layer. If no layer is specified, one is created.


beginLayer() beginLayer([width, height, [renderer]])

The first time this function is called, it creates a p5.Graphics. Subsequent calls return the existing Graphics. (If the arguments are omitted, the Graphics is created at the canvas width and height.) On subsequent calls, the width, height, and renderer arguments are ignored, and the previously-created Graphics is used.

beginLayer() returns the Graphics.

beginLayer(key, [width, height, renderer])

This form can be used to create multiple layers. beginLayer() will create a new layer for each distinct key. The special key value "new" always creates a new layer.


This form can be used to set global draw functions to render onto a Graphics that was created by createGraphics().


Restores the global draw functions rect() etc. so that they operate on the canvas again, instead of the Graphics created by or passed as an argument to beginLayer(). This function also draws the Graphics onto the canvas – although this behavior can be suppressed.



Restores the global draw functions, and draws the Graphics onto the canvas unless the argument to enterGraphics() was a Graphics.

endLayer(x, y, [width, height])

Restores the global draw functions, and draws the Graphics onto the canvas.


Restores the global draw functions. Does not draw the Graphics onto the canvas.


You can find a collection of examples in the examples folder in this repository.


  1. My students in Creative Coding frequently wanted to use the equivalent of the Layers concept that is common in GUI painting and drawing programs. I found that this was a significant hurdle, both because of the terminology and the mechanics.
  2. Because the p5.Graphics functions are methods on the instance, changing code to operate on the canvas such that it instead operates p5.Graphics requires a significant amount of editing.