p5.js Transformations: push() and pop()

Objectives and Overview

Lesson Objectives


Push and Pop in p5.js

Now that you’re familiar with some of the most common transformations and animations in p5, let’s take a look at two useful tools: push() and pop(). Push and pop are necessary when you want to create complex, multi-layered animations and motion graphics. Essentially, you can start a new drawing phase by using push() and then end it with pop(). Then you can place your transformation code between push() and pop(). This lets you create new states for all animations that you do, and is the best way to safeguard from unwanted side effects from your code.

Why Use push() and pop()?

The translate() and rotate() commands are powerful, but you may have noticed that they continue to affect all code that comes after them in your sketch. If you use translate(100, 100) to shift the origin to x:100 y:100, all code placed after this will use this new origin. Let’s take a look at an example:

let angle = 0; function setup() { createCanvas(400, 400); angleMode(DEGREES); rectMode(CENTER); } function draw() { background(0); translate(100, 100); rotate(angle); fill(255, 0, 100); rect(0, 0, 100, 100); fill(0, 255, 0); rect(50, 50, 100, 100); angle = angle +1; }
Code language: JavaScript (javascript)

If you run that code, you’ll see this sketch:

Animation of a p5 sketch on black background showing a pink square and a green square rotating

In this example, both rectangles use the newly translated origin of 100, 100 with the green rectangle offset from the new origin by 50, 50. Additionally, both rectangles are rotating at the same rate and at the same angle. This is great and saves you from repeating code, but quickly becomes an issue if you want to have shapes in different positions or rotating at different angles. At this point, you’ll want to use push() and pop() to create multiple draw states within a single sketch.

Introducing push() and pop()

Let’s redo the above sketch with push() and pop() to create a draw state within the sketch. Remember, push() and pop() need to wrap your transformation code. Let’s start with just the pink rectangle:

let angle = 0; function setup() { createCanvas(400, 400); angleMode(DEGREES); rectMode(CENTER); } function draw() { background(0); push(); //start new draw state translate(100, 100); rotate(angle); fill(255, 0, 100); rect(0, 0, 100, 100); pop(); //finish draw state fill(0, 255, 0); rect(50, 50, 100, 100); angle = angle +1; }
Code language: JavaScript (javascript)

The above code produces this sketch:

Animation of a p5 sketch with a green square and a pink square rotating around it on a black background

What is Happening?

In the second example, only the pink rectangle is transformed. This is because the animation code for the rectangle was placed inside a new, separate draw state within the sketch by using push() and pop(). This is a great tool for building complex animations and transformations. Each one can be inside its own state and not impact everything else in your sketch.

Here’s a non-code way of looking at it:

push() – start new draw state

  • animation code

pop() – end new draw state and return to default sketch

push() – start second draw state

  • second animation code

pop() – end second draw state and return to default sketch

Go ahead and experiment with push() and pop(). Try to create some complex motion graphics! It may seem unnecessary to use push() and pop(), but once your sketches start having multiple animations you’ll see how much that they quickly become essential to avoiding unintentional effects.

Activity: Multiple Transformation Challenge

This challenge is an opportunity to demonstrate your new push() and pop() skills. This activity will provide a code walkthrough for the first two shapes but then you’ll need to complete the remaining shapes.

Challenge Overview

You’ll be creating a sketch that has a shape in each corner, and then another one in the canvas center. Each of the shapes must rotate at different speeds. You’ll need to create multiple draw states in your sketch to accomplish this.

Your sketch should look something like this example:

Animation of a p5 sketch with 5 pink squares rotating in different directions on a black background

Fun Fact: The middle rectangle in the above .gif is actually rotating at such a fast rate in the sketch that it created a strange glitchy effect when converted to a gif!

Getting Started

This section provides the code and a walkthrough for the upper left and middle rectangles. You’ll need to write the code for the remaining shapes. Let’s jump in!

Global Variables and the setup() Function

This is the code that is in the global namespace and setup():

let angleOne = 0; let angleTwo = 0; let angleThree = 0; let angleFour = 0; let angleFive = 0; // note that you can use var instead of let - just make sure your variable names are consistent with the code in the draw() function function setup() { createCanvas(400, 400); angleMode(DEGREES); //set p5 to use degrees instead of radians rectMode(CENTER); //set p5 to draw from the center instead of corner }
Code language: JavaScript (javascript)

All of the above code is familiar. Setting the angleMode() and the rectMode() will make rotations and drawing a bit easier to comprehend.

The draw() Function

This section provides the draw() code for the upper left and middle rectangles. Notice how push() and pop() surround the code for each rectangle animation:

function draw() { background(0); push(); fill(255, 0, 100); rotate(angleOne); rect(0, 0, 50, 50); angleOne = angleOne + 1; pop(); push(); fill(255, 0, 100); translate(width/2, height/2); rotate(angleFive); rect(0, 0, 50, 50); angleFive = angleFive + 25; pop(); }
Code language: JavaScript (javascript)

The first draw state is for the first rectangle, and the second is for the middle rectangle. Feel free to experiment with different colors, sizes, and rotation speeds!

Once you understand the structure, create rectangles in the remaining corners. Refer back to the coordinate plane lesson and the rotation lesson if you need a refresher!

Additional Resources

If you want to expand your understanding of how to draw states in p5, here are some additional resources from the p5 Reference: