Generative Typography

Text

Students will leave the session with the ability to create compositions with text and an understanding of the typography functionality in p5.js.

Class Agenda

Morning Sketching 8:30 - 9am
Presentations & Critique 9 - 9:45am
BREAK 15min
Read & Discussion 10 - 10:45am
Code Lecture 10:45 - 11:30am
BREAK 60min
Workshop 12:30 - 2pm

Morning Sketch

Create a sketch using loops and the lerpColor() function.

Weekly Assignment

Choose a word or letter and create a typographic sketch using a custom font.

Readings

Discussion Questions

Further Resources

Code Lecture

Text

To display text in p5.js we use the text() function.

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

function draw() {
  background(220);
  text("hello class", 100, 100);
}

Similar to shapes the color of the text is controlled via fill() and the outline can be controlled with stroke(). The default size of the font is 12 pixels and it can be updated with the textSize(). p5.js comes with a number of Typography functions and I will cover some of them.

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

  // slow down the frame rate
  frameRate(2);

  textSize(48);
}

function draw() {
  background(220);

  var fillColor = "red";

  if (frameCount % 2 === 0) {
    fillColor = "blue";
  }

  fill(fillColor);

  text("blinking text", 100, 100);
}

Text Alignment

The textAlign() functions help us align our fonts similar to other design programs. Alignment is done in relation to the x and y coordinates passed to the text() function. The following sketch demonstrates the horizontal alignment options:

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

function draw() {
  background(220);

  // default
  textAlign(LEFT);
  text("LEFT", 200, 100);
  circle(200, 100, 10);

  textAlign(CENTER);
  text("CENTER", 200, 200);
  circle(200, 200, 10);

  textAlign(RIGHT);
  text("RIGHT", 200, 300);
  circle(200, 300, 10);
}

The second parameter of textAlign() controls the vertical alignment. The following sketch demonstrates the vertical alignment options:

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

function draw() {
  background(220);

  // default
  textAlign(CENTER, BASELINE);
  text("BASELINE", 200, 75);
  circle(200, 75, 10);

  textAlign(CENTER, TOP);
  text("TOP", 200, 125);
  circle(200, 125, 10);

  textAlign(CENTER, CENTER);
  text("CENTER", 200, 225);
  circle(200, 225, 10);

  textAlign(CENTER, BOTTOM);
  text("BOTTOM", 200, 325);
  circle(200, 325, 10);
}

Multiple Fonts

The textFont() function gives you the ability to set and update the font you are using in your sketch. Using this you can switch between fonts similar to how you switch between fill color, stroke size and color, etc. One thing to note, when you call textFont() in this way the font must exist on the computer of the person using your sketch. Here are some fonts that are usually installed/supported by a majority of computers: safe web fonts.

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

function draw() {
  background(220);
  textSize(48);

  textFont("Comic Sans MS");
  text("Comic Sans", 50, 100);

  textFont("Georgia");
  text("Georgia", 50, 200);

  textFont("Helvetica");
  text("Helvetica", 50, 300);
}

Custom Fonts

p5.js supports loading custom fonts via the loadFont() function.

var myFont;

function preload() {
  /**
   * Please note that this is a font hosted by another project of mine.
   * There is no guarantee that this url will function in the future.
   */
  myFont = loadFont("https://garnet.website/static/fonts/BebasNeue.ttf");
}

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

  // set the font and typography settings
  textFont(myFont);
  textSize(64);
  textAlign(CENTER, CENTER);
}

function draw() {
  background(220);

  text("Bebas Neue", 200, 200);
}

The example above loads the font from an external url. Any url that points to a .ttf or .otf font file will work. The p5.js editor also comes with the ability to upload fonts (tutorial).

/*
 * Coolvetica DaFont page: https://www.dafont.com/coolvetica.font
 * Upload it to the p5.js editor.
 */
var myFont;

function preload() {
  myFont = loadFont("coolvetica rg.otf");
}

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

  // set the font and typography settings
  textFont(myFont);
  textSize(64);
  textAlign(CENTER, CENTER);
}

function draw() {
  background(220);

  text("Coolvetica", 200, 200);
}

Arrays and Objects

Let's pause and learn about two more javascript data types. Arrays and Objects. An Array is a data type that holds a list of values. One thing to note is that typically the values are all of the same data type but that is not a requirement for arrays.

var letters = ["A", "B", "C", "D", "E", "F"];

You access the contents of the loops using the item's index and you can also use loops to iterate through the list.

var letters = ["A", "B", "C", "D", "E", "F"];

console.log("index 0 " + letters[0]);
console.log("index 1 " + letters[1]);
console.log("index 2 " + letters[2]);

for (var index = 0; index < letters.length; index += 1) {
  console.log("loop " + index + " " + letters[index]);
}

So far we've covered a variety of data types such as String, Numbers, and Booleans. Objects can be seen as a collection of data. An object consists of pairs of keys and values.

var teacher = {
  name: "Romello Goodman",
  college: "MICA",
  course: "Generative Typography",
};

To access an object's values you refer to it's keys.

var teacher = {
  name: "Romello Goodman",
  college: "MICA",
  course: "Generative Typography",
  nicknames: ["Mello", "Marshmellow"],
};

console.log(teacher.name);

We've already been using something similar to this when we use the console.log() function. It is a part of the console Object.

var words = [
  {
    text: "hello",
    x: 100,
    y: 100,
  },
  {
    text: "how are you",
    x: 200,
    y: 150,
  },
  {
    text: "goodbye",
    x: 300,
    y: 250,
  },
];

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

function draw() {
  background(220);

  for (var index = 0; index < words.length; index += 1) {
    var word = words[index];

    text(word.text, word.x, word.y);
  }
}

p5.Font

When we use loadFont() we are actually creating an instance of a Font class. We will cover what classes are later but for now you can think of them as objects with a bunch of functions and other uses wrapped into them. The p5.Font() class comes with two very handy functions: textToPoints() and textBounds(). textToPoints() takes our text and returns a list of points along its path. Using textBounds() we can understand the width and height of that same text.

// DaFont page: https://www.dafont.com/coolvetica.font Upload it to the p5.js editor.
var myFont;
var bounds;
var points;

function preload() {
  myFont = loadFont("coolvetica rg.otf");
}

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

function draw() {
  background(255);

  bounds = myFont.textBounds("Cool", 10, 200, 200);
  points = myFont.textToPoints("Cool", 10, 200, 200, {
    sampleFactor: 0.25,
    simplifyThreshold: 0,
  });

  push();
  fill("pink");
  noStroke();
  rect(bounds.x, bounds.y, bounds.w, bounds.h);
  pop();

  for (var index = 0; index < points.length; index += 1) {
    var point = points[index];

    circle(point.x, point.y, 10);
  }
}