Text and Arrays

These notes will cover the essentials of creating text and using arrays in p5.js. All examples will make use of a poem by the poet Jane Wong entitled 10 ALTERNATE ENDINGS from the Yalobusha Review.

10 ALTERNATE ENDINGS by Jane Wong (2019)

1: The flattened road kill squirrel puffs back to life

2: My father never leaves and I sprout more ventricles in my heart

3: I love so richly, I spare millions of pennies in my trust

4: Rosehips bloom in January, pink jellyfish in shattering snow

5: My heart becomes a jar of wildflower honey, does not amber

6: Everyone is so well fed, they cry greasy tears

7: I sit on a balcony in a large city no one has ever heard of, watching the one I love come back to me like rewinding a tape I’ve played many times before

8: The dead ends of my hair spilt to form their own continents

9: My mother reaches the end of her patience and heaves my father’s cigarette stained armchair out the window and some college students catch it from below, grateful

10: I lift the end of the day up like a fat centipede with its legs kicking and say: look, look how much you have

text()

We can draw text to our canvas in p5.js by using the text() function.

The text(a,b,c,d,e) function takes in three to five parameters:

  • a: text to be displayed, can be a string or other variable such as a number
  • b: x-coordinate of text box
  • c: y-coordinate of text box

Optional:

  • d: maximum width of text box
  • e: maximum height of text box

By default, text will draw from the bottom left corner if you use three parameters. If four or five parameters are used, the text box will draw from the upper left corner, similar to how a square or rectangle is drawn in p5.js. With four or five parameters, the text box created by text() will also be affected by rectMode().

The default justification for text() is left justification.

Similar to other shapes in p5.js, the color of text is controlled by adjusting the fill and stroke.

Examples:

text() with three parameters:

text(sentence,50,50);

let sentence = "Rosehips bloom in January, pink jellyfish in shattering snow";

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

function draw() {
  background("#2E6F40");
  noStroke();
  fill("#CFFFDC");
  text(sentence, 50, 50);
}

text() with five parameters:

text(sentence,200,200,100,100);

let sentence = "Rosehips bloom in January, pink jellyfish in shattering snow";

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

function draw() {
  background(" #2E6F40");

  rectMode(CENTER);

  noFill();
  stroke("#CFFFDC");
  rect(200, 200, 100, 100);

  noStroke();
  fill("#CFFFDC");
  text(sentence, 200, 200, 100, 100);
}

textSize()

textSize() sets the size of text with a single number parameter in pixel dimensions.

Example:

textSize(50);

let sentence = "Rosehips bloom in January, pink jellyfish in shattering snow";

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

function draw() {
  background(" #2E6F40");
  noStroke();

  fill("#CFFFDC");
  rectMode(CENTER);
  textSize(40);
  text(sentence, 200, 200, 300, 300);
}

textAlign()

textAlign() will set the alignment of text within p5.js. textAlign() different effects depending on how many parameters are within the text function.

textAlign(a,b) takes up to two parameters:

  • a: Horizontal alignment (values of LEFT, CENTER, RIGHT)
  • b: Vertical alignment (values of TOP, BOTTOM, CENTER, or BASELINE)

When using 3 parameters with the text() function, changing the horizontal and vertical alignment with textAlign() will change the behavior of the (x,y) coordinate location of the text() function. When using four or five parameters, textAlign() will affect the alignment of the text within the defined text box.

Examples:

With three parameters, giving textAlign() parameters of (CENTER, CENTER) will cause the text to be drawn from its center position on the x and y axes:

textAlign(CENTER, CENTER);
text(sentence, 200, 200);

let sentence = "Rosehips bloom in January, pink jellyfish in shattering snow";

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

function draw() {
  background(" #2E6F40");
  noStroke();

  textSize(14);
  textAlign(CENTER, CENTER);
  fill("#CFFFDC");
  text(sentence, 200, 200);
}

With five parameters, giving textAlign() the parameters of (CENTER,CENTER) will align the text within the center of the defined text box:

textAlign(CENTER,CENTER)
text(sentence,200,200,300,300);

let sentence = "Rosehips bloom in January, pink jellyfish in shattering snow";

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

function draw() {
  background(" #2E6F40");
  noStroke();

  fill("#CFFFDC");
  rectMode(CENTER);
  textSize(40);
  textAlign(CENTER, CENTER);
  text(sentence, 200, 200, 300, 300);
}

Bottom example:

textAlign(CENTER,BOTTOM)
text(sentence,200,200,300,300);

let sentence = "Rosehips bloom in January, pink jellyfish in shattering snow";

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

function draw() {
  background(" #2E6F40");
  noStroke();

  fill("#CFFFDC");
  rectMode(CENTER);
  textSize(40);
  textAlign(CENTER, BOTTOM);
  text(sentence, 200, 200, 300, 300);
}

Adding Fonts

Adding a font is p5.js is three step process:

  1. Download a font as a OpenType (.otf) or TrueType (.ttf) file.
  2. Add the font to your p5.js sketch
  3. Load the font in your sketch using async and await function.

Downloading Fonts

Fonts can be downloaded from a variety of websites including Google Fonts.

Select the font you would like and download the font as an OpenType (.otf) or TrueType (.ttf) file.

For more free font options check our this repository as well as the site Republish

Adding Font

We can add our font to our p5.js sketch by pressing the arrow on the left side of our UI in p5.js.

We can then press the plus button, select “Upload file” and upload our font.

You can rename your font by right clicking on the font and selecting “Rename.”

Async and Await

To load a font and your sketch, you first need to learn about Async and Await.

async_await Reference.

Async and Await allow us to write asynchronous code, or, in other words, code that starts and then finishes at a later moment without stopping the rest of your program. In p5, we can use Async and Await to load in large amounts of data at the start of our p5 sketch. What this will look like practically in our sketch is that we will modify a few of our functions with the keyword await. This will tell our program to wait for these functions to finish before completing the rest of our program.

In our particular case, we want to load the font SpaceGrotesk.ttf at the start of our sketch before the rest of our code runs. To do this, we can use the function loadFont() and provide this function with the name of our font file as a string. We can also set this function equal to our font variable:

let spaceGroteskFont;

function setup() {
  spaceGroteskFont = loadFont("SpaceGrotesk.ttf");
}

loadFont() (as well as other load functions which will talk about later in the course), are asynchronous functions. Since we are loading large amounts of data, these functions therefore can take an undetermined amount of time to finish. In order to prevent this from stopping our program from running (imagine if circle() took five minutes to run), we can instead wait for all of the load functions to finish before we begin our sketch.

To enable this in our code, we need to use the keyword await before our loadFont() function:

let spaceGroteskFont;

function setup() {
  spaceGroteskFont = await loadFont("SpaceGrotesk.ttf");
}

Then, since parts of the setup function are running asynchronously, we need to set our setup() function to be an asynchronous function using the keyword async:

let spaceGroteskFont;

async function setup() {
  spaceGroteskFont = await loadFont("SpaceGrotesk.ttf");
}

Set our Font

We can set our font in our p5.js sketch by using the function textFont(), providing the variable of our preloaded font.

textFont(spaceGroteskFont);

Example:

let spaceGroteskFont;
let sentence = "Rosehips bloom in January, pink jellyfish in shattering snow";

async function setup() {
  createCanvas(400,400);
  spaceGroteskFont = await loadFont("SpaceGrotesk.ttf");
}

function draw() {
  background(" #2E6F40");

  noStroke();
  fill("#CFFFDC");

  rectMode(CENTER);

  textFont(spaceGroteskFont);
  textSize(40);
  textLeading(40);
  textAlign(CENTER, CENTER);

  text(sentence, width / 2, height / 2, 300, 300);
}

Arrays

An array is an object within Javascript that can store an ordered list of data.

To create an array within Javascript, we can use the bracket characters, [ ].

I could begin by making an array variable called poem.

let poem = [ ];

Currently, this is an empty array, there are no lines to our poem. We can add lines to our poem, by making a series of strings that are separated by commas.

let poem = [
  "1: The flattened road kill squirrel puffs back to life",
  "2: My father never leaves and I sprout more ventricles in my heart",
  "3: I love so richly, I spare millions of pennies in my trust",
  "4: Rosehips bloom in January, pink jellyfish in shattering snow",
];

Index && Length

Index

Now that I have an array with lines of a poem, I can access each element in that array. An element’s position within an array is called its index. When counting elements within an array, the first element always has an index of 0. This continues with the second element having an index of one and so on.

If I wanted to print one particular line of my poem, I can access an element in my array by providing its index. I do this by calling the name of my array followed by open and closed brackets [] containing the index number I want to access.

For example, to call the third line of my poem I could code:

poem[2];

let poem = [
  "1: The flattened road kill squirrel puffs back to life",
  "2: My father never leaves and I sprout more ventricles in my heart",
  "3: I love so richly, I spare millions of pennies in my trust",
  "4: Rosehips bloom in January, pink jellyfish in shattering snow",
];

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

function draw() {
  background(" #2E6F40");
  noStroke();
  fill("#CFFFDC");
  textAlign(CENTER, CENTER);
  textSize(15);
  text(poem[2], width / 2, height / 2);
}

Index and Variables

We also use a variable to determine which index we want our array to display.

If I create a variable named index, I can increment this value to change which line of the poem I display.

let index = 0;

function mousePressed() {
  index++;
}

If I continue to increase my index, however, eventually the number value of the index variable will be larger than the number of elements in my array. For example, if index equals 4, I would be looking for the 5th element in my array which does not exist as there are only 4 lines in my poem. In order to prevent this index out of bounds error, I need to know the length of my array.

Length

In order to limit the amount my index is increased by, I can use the length property of my array to see how long my array is.

poem.legth

This will return the total length of my array, or, in other words, how many elements are in my array. In the case of poem, poem.length would return a value of 4.

I can use this length value to make sure my index variable never goes beyond the length of my array:

function mousePressed() {
  if (index < poem.length - 1) {
    index++;
  } else {
    index = 0;
  }
}

In this example, I am checking to see if my index is less than length minus 1. The reason I use minus 1, is that the number of the last index in the array will always be equal to the total length minus 1. For example, since our poem has 4 lines, it has a length of 4 and the index of the last element is 3.

Click to progress poem

let poem = [
  "1: The flattened road kill squirrel puffs back to life",
  "2: My father never leaves and I sprout more ventricles in my heart",
  "3: I love so richly, I spare millions of pennies in my trust",
  "4: Rosehips bloom in January, pink jellyfish in shattering snow",
];
let index = 0;

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

function draw() {
  background(" #2E6F40");
  noStroke();
  fill("#CFFFDC");
  textAlign(LEFT, CENTER);
  textSize(12);
  text(poem[index], 20, height / 2);
}

function mousePressed() {
  if (index < poem.length - 1) {
    index++;
  } else {
    index = 0;
  }
}

Arrays and Iteration

Since elements of an array are ordered and can be accessed with an index value, I can use a for loop to iterate over my array to access all of its elements. I could use a for loop to draw all of the lines of my poem using a variable as the index value, checking to see if it is less than the length value of my array.

  for (let i = 0; i < poem.length; i++) {
    text(poem[i], 20, y);
    y = y + 20;
  }

let poem = [
  "1: The flattened road kill squirrel puffs back to life",
  "2: My father never leaves and I sprout more ventricles in my heart",
  "3: I love so richly, I spare millions of pennies in my trust",
  "4: Rosehips bloom in January, pink jellyfish in shattering snow",
];

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

function draw() {
  background(" #2E6F40");
  noStroke();
  fill("#CFFFDC");
  textAlign(LEFT, TOP);
  textSize(12);
  let y = 50;
  for (let i = 0; i < poem.length; i++) {
    text(poem[i], 20, y);
    y = y + 20;
  }
}