In the realm of generative art, typography occupies a unique space, serving as a bridge between conventional design elements and algorithmic unpredictability. This p5.js sketch seeks to delve into the granular aspects of type manipulation, building on the typographic scripts supplied generously by Generative Gestaltung. We build on their framework by simplyfying the sketch to a general template that allows learners to build their own creations.
This document examines in detail some of the code snippets. It is not necessarily in the order the code is written in the script. Learners are encouraged to examin the sketch.js file , which is structured, in conjunction with this.
The code consists of multiple layers, working in tandem to produce the final output:
- Font Loading: Utilizing the
opentype.js
library to load custom fonts. - Type Rendering: Leveraging p5.js for rendering the typed text.
- Path Tracing: Tracing the paths around each glyph (character) of the typed text.
- Path Manipulation: Algorithmically manipulating the traced paths.
Ensure you've integrated all the necessary external files into your index.html
. Insert the required dependencies under the following comment in your HTML:
<!-- Generative Design Dependencies here -->
...
For the complete setup, refer to this index.html boilerplate.
The font is loaded asynchronously using opentype.js
. This library offers a robust set of functionalities to handle OpenType and TrueType fonts.
This function searchs for a font file in the data directory. If it finds the file, it will load it into the font variable, otherwise it gives us an error.
The font needs to be uploaded to a folder of your own creation. This example creates and uses a folder "data". Learners can download this data directory with the example font files.
opentype.load("data/FreeSans.otf", function (error, _font) {
if (error) {
console.log(error);
} else {
font = _font;
}
});
let font;
let textTyped = "Type...";
Here, font
serves as a placeholder for the loaded OpenType font, and textTyped
holds the string subjected to generative transformations.
The draw
function is the core of the script, encompassing the logic for type rendering and manipulation. In practice, the code which determines the visual output of the script occur at the end of the draw
function:
Looping through the path points, the sketch allows for selective point manipulation. In the snippet below, every 21st point undergoes a transformation, influenced by the mouse position:
if (i % 21 == 0) {
fill(255,127,127);
rect(letterPoint.x + (mouseX/100), letterPoint.y + (mouseY/100), 2 + (mouseX/10), 2 + (mouseY/10));
}
Users are encouraged to develop their interactions and generative algorithms by creating additional if
statements or modifying and extending the existing if
statements.
The sections of the draw
function leading up to the if
are more concerned with extracting the path data. For a detailed explanation of that we provide below a breakdown of the key phases:
The outline path of each glyph is extracted via font.getPath
, and stored in fontPath
.
let fontPath = font.getPath(textTyped, 0, 0, 200);
Resampling is performed using the g.resampleByLength
function. This optimizes the number of points and controls the granularity of the subsequent manipulations.
let path = new g.Path(fontPath.commands);
path = g.resampleByLength(path, 1);
The script captures keyboard events for textual interaction. ASCII values are used to filter keys and modify the textTyped
string dynamically.
ASCII is the way computers map numbers to letters.
- ASCII 32 = the space bar.
- ASCII 65 = UPPERCASE "A"
- ASCII 97 = lowercase "a"
This code is telling the function to only add key strokes which are 32 and above.
More information about ASCII values can be found here
if (keyCode >= 32) {
textTyped += key;
}