Interactive And Kinetic Typography

Learning Processing

Monica Looze
IxD Prototyping Process
7 min readApr 27, 2017

--

A Serious Challenge

The next challenge I faced was how to create compelling on-screen kinetic typography that would map to our mental model of color theory and a paint palette. I knew I wanted to include red, blue, yellow, and black and white to illustrate primary colors, secondary colors, and tints and shades.

My original plan was to include short animations, similar to this:

But I realized that in order to create every single color combination I wanted, I would have had to create 36 individual animations. With my previous experience using arduino and a potentiometer to control an single animation crashing each time I did it, I knew I needed to find a simpler way, both in the interest of time and viability, I started to explore my options.

The Constraints

Because a Makey Makey maps to a keyboard, I needed to base all the processing code on keyboard inputs, and because I wanted to mix colors, multiple key inputs would need to control the interaction to make it believable.

The MVP

To discover whether I could create color changes in processing based on a key press, I needed to first learn Processing. Cue Daniel Shiffman Tutorials. I also explored open source code on openprocessing.org, but I was having a lot of issues figuring out how to put everything together. I sought a lot of help from Ken Barry, who happens to be my father-in-law, and also a computer scientist. This is where I will admit that this project would not have been possible without him.

I split my project into smaller constituent parts to create a mental model for processing.

I first had to understand the possible options for creating images in processing, set up the space: void.setup, size, color, etc.

Then I needed to understand what draw did, so I experimented a lot with drawing really simple things, like a circle and simply writing the word design. I initially experimented with code that was static, using fills to “paint” over letters that were already there. Each letter was thus coded twice.

I tried rotating letters to see if I could match my original After Effects animation with the animation in processing, but found the process to be quite difficult.

Discovering Boolean

I also had to determine how to code multiple keystrokes together (Left & Up): This is when we added the Boolean section so that is was coding each key as a yes/no. This allowed me to be able to actually mix colors by pressing multiple keys at the same time.

Hex Codes: Never again

Choosing Hex codes for my colors proved to be difficult — if I did it again I would not choose to use hex codes, instead using RGB values instead, as this is more common in coding. I created an excel spreadsheet of codes and colors to keep track of all the combinations.

Alpha Channels

I also experimented with alpha channels and transparency, changing the first two digits ahead of the hex code. The digits range from 00-FF, following a base 16 scale.

Source Code for MVP

Adding Animation

I knew I wanted to straighten out the letters and make the type kinetic, so I started looking for animation tutorials. I found this code on learningprocessing.com:

// Example 17-6: Text breaking up 

PFont f;
String message = "click mouse to shake it up";

// An array of Letter objects
Letter[] letters;

void setup() {
size(480, 270);

// Load the font
f = createFont("Arial", 20);
textFont(f);

// Create the array the same size as the String
letters = new Letter[message.length()];

// Initialize Letters at the correct x location
int x = 125;
for (int i = 0; i < message.length (); i ++ ) {
// Letter objects are initialized with their location within the String as well as what character they should display.
letters[i] = new Letter(x, 140, message.charAt(i));
x += textWidth(message.charAt(i));
}
}

void draw() {
background(255);
for (int i = 0; i < letters.length; i ++ ) {

// Display all letters
letters[i].display();

// If the mouse is pressed the letters shake
// If not, they return to their original location
if (mousePressed) {
letters[i].shake();
} else {
letters[i].home();
}
}

This code allows a string of letters to shake while the mouse is clicked. I thought it would make sense to do the opposite: when the keys are pressed, the shake should stop and clearly write DESIGN in the colors chosen. I wanted to underscore the choice that designers make about design and finding clarity in their final outcomes.

Switching up that code was easy so the opposite actions worked, but I could not get the “DESIGN” code and the animation to work together.

I was then introduced to arrays, in class, by Clare. She helped me restructure the code into an array so the hex code gradient was coded by the array and it would be easier to add an animation. I put the text into a string, and was then able to do it.

Hex Codes: Never again

After adding the DESIGN code to an array and adding a shake animation to the whole thing, I worked on refining the solution. Because of the gradient values in the array, and my missing mental model of hex codes, I had to test various hex codes over and over again to make the values work with the array. If I did this again, I would absolutely use rgb. I still do not understand how or why they are working, but I finally landed on values that work with gradients and color mixing.

Monospace Type

I also discovered the difficulty of choosing a typeface without the ability to kern. You cannot kern (as far as I know) in processing, so I decided to use a monospace typeface to prevent strange spacing around the “I” in DESIGN. I think, luckily, the monospace typeface works well with the theme of the color mixing and a toy for children, so I left it as is.

The Final Code

// Example 17–6: Text breaking up

PFont f;
String message = “design”;
int hexcolor;
boolean isLeft, isRight, isUp, isDown, isSPACE;
SinOsc sine; SoundFile file;
// An array of Letter objects
Letter[] letters;
int[] values = { 0, 25, 50, 75, 100, 125 };

void setup() {
size(1680,1100);
hexcolor = unhex(“000000”);
sine = new SinOsc(this);
//sine.play();

// Load the font
f = createFont(“Consolas”, 50);
textFont(f);

// Create the array the same size as the String
letters = new Letter[message.length()];

// Initialize Letters at the correct x location
int x = 180;
int y = 652;
for (int i = 0; i < message.length (); i ++ ) {
// Letter objects are initialized with their location within the String as well as what character they should display.
letters[i] = new Letter(x, y, message.charAt(i), i);
x += textWidth(message.charAt(i))*9.5;
//println(textWidth(message.charAt(i)));
}
}

void draw() {
background(255);
for (int i = 0; i < letters.length; i ++ ) {

// Display all letters
letters[i].display();
// If the mouse is pressed the letters shake
// If not, they return to their original location
if (keyPressed) {
letters[i].home();
}
else {
letters[i].shake();
hexcolor = unhex(“000000”);
textSize(600);
//sine.stop ();
}
}

//logic to detect which key(s) are depressed and draw the right color “design” as well as add sound to each keystroke

if (isLeft){
hexcolor = unhex(“FFFFDA00”);
//sine.freq(400);
//sine.play();
//yellow
}
if (isRight){
hexcolor = unhex(“FFFF0000”);
//sine.freq(200);
//sine.play;
//Red
}
if (isDown){
hexcolor = unhex(“FF080080”);
//sine.freq(300);
//sine.play;
//Blue
}
if (isUp){

hexcolor = unhex(“FFFFFFFF”);
//sine.freq(400);
//sine.play;
//White
}
if (isSPACE){
hexcolor = unhex(“FF000000”);
//sine.freq(400);
//sine.play;
//Black
}
if (isLeft & isRight){
hexcolor = unhex(“FFffa500”);
//Orange
}
if (isLeft & isDown){
hexcolor = unhex(“FF51b848”);
//Green
}
if (isRight & isDown){
hexcolor = unhex(“FF790482”);
//790482
//67016D
//Purple
}
if (isLeft & isUp){
hexcolor = unhex(“77FFDA00”);
//Light Yellow
}
if (isLeft & isSPACE){
hexcolor = unhex(“FF998002”);
//Dark Yellow
}
if (isRight & isUp){
hexcolor = unhex(“FFff6666”);
//Light Red
}
if (isRight & isSPACE){
hexcolor = unhex(“FFb20000”);
//Dark Red
}
if (isDown & isUp){
hexcolor = unhex(“77080080”);
//Light Blue
}
if (isDown & isSPACE){
hexcolor = unhex(“FF000035”);
//Dark Blue
}
if (isLeft & isRight & isUp){
hexcolor = unhex(“FFFFC966”);
//Light Orange
}
if (isLeft & isRight & isSPACE){
hexcolor = unhex(“FFB27300”);
//Dark Orange
}
if (isLeft & isDown & isUp){
hexcolor = unhex(“FF7FBF7F”);
//Light Green
}
if (isLeft & isDown & isSPACE){
hexcolor = unhex(“FF004C00”);
//Dark Green
}
if (isRight & isDown & isUp){
hexcolor = unhex(“66790482”);
//Light Purple
}
if (isRight & isDown & isSPACE){
hexcolor = unhex(“FF4C004C”);
//Dark Purple
}
}

void keyPressed() {
println(+keyCode); // debuging code so the key pressed is known
println(+key); // this will help with the Makey Make is attached
println(“pressed”);
setMove(keyCode, true); //true a specific key is pressed
}
// KeyReleased is an interupt routine that is called whenever a key is released
void keyReleased() {
setMove(keyCode, false); //that key pressed is now false
println(“Released”);
}

// setting the key status as true or false
boolean setMove(int k, boolean b) {
switch (k) {

case DOWN:
return isDown = b;

case LEFT:
return isLeft = b;

case RIGHT:
return isRight = b;

case UP:
return isUp = b;

case 32:
return isSPACE = b;

default:
return b;
}
}

--

--