creating interactive type #3 evolving type
This issue is part of the series: creating interactive type #1 interactive type light #2 timed type #3 evolving type #4 3-dimensional type #5 outline-generated type
introduction The booklet series »creating interactive type« introduces how to design interactive and responsive type. Visual attributes of typefaces, like style, colour or size, have always given an additional meaning to the text’s content. Interactivity can take this formaspect to another level. By adding behaviour, letter shapes are able to respond to time and usage and make this process part of the given information. The described interactive type applications are built with the opensource programming language Processing, that was in particular developed for designers and artists. Because of its clear structure, it is quite accessible to the ones with no or only little programming skills. Beginners are able to write their own programmes after only a few minutes of instructions. This issue »evolving type« introduces how to create letter shapes that are formed of interactive elements/spirals that evolve over time. Applications and codes can be viewed and copied from www.StefanieSchwarz-GraphicDesign.de/interactive-type.html
step 1 / designing grid-based letter forms In order to make it easier, to define the coordinates of the interactive elements, that will form the letters, a grid is set up suggesting the element’s positions.
step 2 / coding grid-based letters To translate the grid-letters to codes, first the ellipse() function is used, which will later be replaced by a more complex and interactive element. The first two parameters set the location of the ellipse, the third and forth set the width and the height.
size (300, 700); background(255); fill(0); noStroke(); // declare variable for diameter int d = 24; // build letter I ellipse(72, 113, d, d); ellipse(132, 113, d, d); ellipse(192, 113, d, d); ellipse(132, 193, d, d); ellipse(132, 270, d, d); ellipse(132, 350, d, d); ellipse(132, 429, d, d); ellipse(132, 507, d, d); ellipse(72, 586, d, d); ellipse(132, 586, d, d); ellipse(192, 586, d, d);
step 3 / coding an evolving element The following example shows how to create an element that is more complex than an ellipse. This interactive spiral can increase and decrease its length and vary from a smooth line to a rough, uneven one which is partially determined by the random() function. The code uses the cosine and sinus function in relation to the radius in order to draw the spiral. The actual size and grade of irregularity are influenced by the position of the mouse, using the variables mouseX and mouseY. Parts of the code are placed inside a for structure that continuously calculates the length and increase of the spiral. In general, for structures perform repetitive calculations and update a variable after each iteration through the block.
void setup() { size (500, 500); background(255); frameRate(1); smooth(); strokeWeight(0.5); stroke(0); } void draw() { float radius = 10; int centX = 200; int centY = 200; float x,y; float lastx = -999; // for connecting points float lasty = -999; // length/increase of spiral for(float ang=0; ang<=200+mouseY*5; ang+=12) { radius += 0.2; // convert degrees to radians float rad = radians(ang);
â&#x2030;Ľ
x = centX + (radius * cos(rad) + random(10+mouseX/25)); y = centY + (radius * sin(rad) + random(7+mouseX/25)); // connect points/draw a line if (lastx > -999) { line (x,y, lastx, lasty); } lastx = x; lasty = y; } }
step 4 / coding an evolving letter The positions defined in step 2, with a static ellipse, are now used for placing the interactive spiral in order to form a letter. To simplify the code, the spiral is defined as a function, named drawSpiral, that can be run many times within the programme. Another simplification is achieved by using the translate() function that defines a position relative to the previous one, instead of referring to the 0,0 coordinate each time.
void setup() { size (300, 700); background(255); frameRate(1); smooth(); strokeWeight(0.5); stroke(0); } void draw() { // draw letter I translate(-72, -88); drawSpiral(); translate(0, 78); drawSpiral(); translate(0, 78); drawSpiral(); translate(0, 78); drawSpiral(); translate(0, 78); drawSpiral();
â&#x2030;Ľ
translate(0, 78); drawSpiral(); translate(0, 78); drawSpiral(); translate(-62, 0); drawSpiral(); translate(124, 0); drawSpiral(); translate(0, -468); drawSpiral(); translate(-124, 0); drawSpiral(); } void drawSpiral() { float radius = 10; int centX = 200; int centY = 200; float x,y; float lastx = -999; float lasty = -999;
â&#x2030;Ľ
for(float ang=0; ang<=200+mouseY*5; ang+=12) { radius += 0.2; float rad = radians(ang); x = centX + (radius * cos(rad) + random(10+mouseX/25)); y = centY + (radius * sin(rad) + random(7+mouseX/25)); if (lastx > -999) { line (x,y, lastx, lasty); } lastx = x; lasty = y; } }
step 5 / recording an evolving letter Additionally a function can be included in the code that allows to record PDFs of the running application and by doing so capture stills of the evolving letter shapes.
import processing.pdf.*; void keyPressed() { // when a is pressed if (key == 'a') { // start recording and save as xxx.pdf beginRecord(PDF, "xxx.pdf"); // when s is pressed } else if (key == 's') { // stop recording PDF endRecord(); } }
references Reas, C. & Fry, B. (2007) Processing: a programming handbook for visual designers and artists. Cambridge: MIT Press. www.processing.org concept and design Stefanie Schwarz www.stefanieschwarz-graphicdesign.de Central Saint Martins College of Arts and Design London, June 2012