Tutorial One

DeliverableDue Date
Tutorial 01September 24, 2026 at 02:15 PM
Tutorial 01 (revision)October 05, 2026 at 11:59 PM

Goals

After this tutorial you should be able to:

  • Create a basic p5.js sketch
  • Change the color mode and explain why you might use RGB or HSB
  • Use the lerpColor function to interpolate between two colors
  • Know how to add UI elements to your page and use their values in your sketches

Getting started

  1. Start a new repository by accepting the assignment.
  2. Clone the repository to your local computer (in your shell, type git clone and the name of the repository)

Task

For this warm-up tutorial, we are going to make two bands which fade from one color to another through interpolation. The top band will operate in RGB, and the bottom band will operate in HSB. Each band will consist of a row of small rectangles, the color of which will be chosen based on its position.

Important

Part of this tutorial is for you to get used to looking up commands in the references, so I will not give you the precise commands to type in. I have, however, linked to the references for the functions you need at the bottom of this page.

Versioning Note that the links go to the v1 references. We are still using v1! The folks behind p5.js transitioned to v2 as the default about two weeks before the start of the semester. When I tried moving my examples I found a collection of inconsistencies and bugs in some of my simple examples, so I do not have enough confidence in the transition to make the move yet.

Part 1: Setup

We will need three main variables to control our color bands: a start color (startColor), and end color (endColor), and the number of divisions in the band (divisions). We are going to declare them above the setup() function (i.e., as global variables).

Note

When we are working with p5.js, it is very common that we will want to have variables that are visible to both the setup() function and all invocations of the draw() (recall that this is how we animate things). Since there isn’t a mechanism that allows us to pass values into these functions, a common pattern is to create global variables like these.

Declare divisions to be a constant with const and set it to 100. Use let to declare the other two as variables.

If you hunt around online for examples long enough, you will find variables in JavaScript declared using var. This used to be the only way, but the semantics of var are a little funky, and the standard was changed to include const and let. Everything you need can be accomplished better with const and let, and you should stick to those in this class.

Inside the setup() function, initialize the two colors to red and blue using the color() function. Use the three channel form (e.g., color(255,0,0) for red).

ImportantWhy not initialize the colors where we declared them?

One of the quirks of working with p5.js is that none of the built-in functions are available until setup() is called. In this instance, it means we can’t use the color() function to initialize our values where we declare them.

After initializing the colors, call noStroke() in setup() to turn off the shape outlines.

Part 2: Draw the RGB band

In draw(), make a for loop and draw a rect for each one of the divisions. The band should span the width of the canvas, which is available in the width variable. Use width to determine the size of your rectangles given the number of divisions. The height of the rectangles is up to you.

Use lerpColor to figure out the color for each rect based on the percentage of the distance across the canvas.

Run this – you should have a nice band that fades from red to blue.

In order to see your sketch, your sketch needs to be served from a web server to your web browser.

If you are using VSCode, you can use the Live Preview extension. Once installed, you will see a “Go Live” button on the bottom of your editor window. This will start a web server in the directory of the file you are currently viewing. Once it is started, you will see something that looks like “Port : 5500” (the number may vary). This tells you that to see the site you need to go to localhost:5500 in your browser.

Alternatively, you can start a server on the command line using Python by navigating to the directory and running

python -m http.server 5500

This starts the server on port 5500. Unlike the VSCode extension, this will not hunt for new ports if 5500 is already taken. It will fail and you need to try again with a new number (or kill the process that is using the port).

Part 3: Draw the HSB band

Copy your for loop and paste it into the draw() function a second time. Change the y position for the rectangles so the second band is below the first.

Call colorMode() before each loop. Set the mode for the first loop to be RGB and the mode for the second to be HSB

Note

The default mode is RGB. However, p5.js is stateful. When you call colorMode() to change the mode, it is then set that way until the next time it is called. Because draw() is called repeatedly, we now need to be explicit that the first band should be drawn in RGB mode so it switches back on the next iteration of draw().

You should see a distinct difference between the two bands.

The reason for the change is that lerpColor is operating in the color space we chose with colorMode. In both cases, we are doing an interpolation over the channels. However, in RGB mode that means changing the red, green and blue channels, while in HSB, the saturation and brightness are the same for both colors and we are primarily interpolating the hue, which will rotate around the color wheel.

Part 4: Commit your changes

Let’s be mindful about our git use. Commit your changes to your repository before moving to the next step. (If you are a 312 vet, don’t worry about making feature branches, however. We aren’t getting that complex yet.)

Part 5: User interaction

We are going to add some basic user interaction to allow the user to control our three primary variables.

Add color pickers

The createColorPicker() function places a swatch of color on the page, and clicking on it opens up a color picker, allowing the user to select a new color.

Comment out your startColor and endColor variables, and create two new variables: startPicker and endPicker. Use createColorPicker() in setup to initialize your pickers.

Use the pickers’ position function to place them under your sketch (the height variable might be useful here).

Adjust the draw function to pull the colors from your pickers using their value() function, which returns the current color.

Try changing the two end points of the band.

Add a slider

Comment out the divisions variable and add a new divisionSlider variable. In setup, use the createSlider() function to make a slider that allows the user to vary the number of divisions between 2 and 200. Set the default to 100, and the step size to 1.

Use the slider’s position function to place it just below the pickers.

Adjust the draw() function so that it pulls the number of divisions from the slider’s value function.

You should now be able to slide the slider back and forth and see the number of divisions change.

Part 4: Fixing the bands

Having control over the colors and the divisions reveals a couple of issues.

The first issue becomes obvious if you crank the divisions down to two colors. The end colors of the two bands are different. If you have a tool for examining the colors on your screen, you will find that neither one is actually the color that you selected in the second color picker.

The issue comes from how we are using lerpColor. We are passing in the percentage of the distance across the band of the start of the rectangles we are drawing. As such, we will never have a moment when that percentage is 1, which is what we need to pass to lerpColor if want the actual final color. This is an instance of the “fence post error”.

A solution is to change the percentage so that we are at 1 on the final rectangle. We can do that by dividing our current step number by one less than the total number of divisions. This will subtly change all of the rectangles, but aesthetically the result will be better.

The second issue becomes obvious as you slide the slider to increase the number of divisions. For some values, there will be white lines that appear in the band.

This is caused by float precision errors. For some division sizes, we can’t really represent the width of the box correctly, or the width would split a pixel in half and the system is rounding down.

The simple solution is to add 1 to the width of all of the rectangles. Then the next rectangle will cause an overlap.

Finishing up

  1. Add and commit your changes and push those commit(s) to GitHub.
  2. Submit your repository to Gradescope

References

Links to the reference pages for the functions you will be using:

background
color
colorMode
createCanvas
createColorPicker
createSlider
fill
lerpColor
noStroke
rect