/*
ArcText - Rick Companje (c) 10-1-2008
Rendering dynamic text on a circle / arc
Built with processing but can easily be rewirtten to Flash, Flex, C++ etc.
Credits to teknoel.com
*/
Handle hFontsize, hTracking, hRotation, hRadius;
String [] labels = {"FONT SIZE", "TRACKING", "ROTATION", "ARC RADIUS"};
Handle[] handles;
PFont bmpfont, font;
String txt = "dynamic text rendering on an arc";
int r=200;
int w=400;
int h=400;
void setup() {
size(w,h);
smooth();
bmpfont = loadFont("Standard0755-8.vlw");
font = loadFont("Arial-BoldMT-48.vlw");
handles = new Handle[4];
handles[0] = hFontsize = new Handle(0,26,48);
handles[1] = hTracking = new Handle(-1,0,1); // EM units
handles[2] = hRotation = new Handle(0,0,TWO_PI); //path rotation offset
handles[3] = hRadius = new Handle(-300,100,300); //negative radius renders the text on the inside of the path
}
void draw() {
background(0);
pushMatrix();
translate(w/2,h/2+35);
rotate(hRotation.value);
r = int(hRadius.value);
noFill();
stroke(50);
ellipse(0,0,2*r,2*r);
int cross=20;
line(0,-cross,0,cross);
line(-cross,0,cross,0);
textFont(font,int(hFontsize.value));
float angle = 0;
textAlign(CENTER);
for (int i=0; i<txt.length(); i++) {
char letter = txt.charAt(i);
//first half letter width
float adjacent=r;
float opposite=textWidth(letter)/2;
angle += atan(opposite/adjacent);
//tracking between letters in EM measurements
adjacent=r;
opposite=textWidth("M")*hTracking.value; //EM is relative to the width of the letter M
angle += atan(opposite/adjacent);
pushMatrix();
rotate(-angle);
stroke(50);
line(0,r-50,0,r+20);
fill(255);
noStroke();
text(letter,0,r);
popMatrix();
//second half letter width
adjacent=r;
opposite=textWidth(letter)/2;
angle += atan(opposite/adjacent);
}
popMatrix();
drawHandles();
}
void drawHandles() {
textFont(bmpfont,8);
textAlign(LEFT);
text("ArcText - Rick Companje (c) 10-1-2008 - Credits to teknoel.com",5,height-5);
for (int i=0; i<handles.length; i++) {
textAlign(RIGHT);
fill(255);
text(labels[i],60,20+i*15);
handles[i].draw(70,10+i*15);
textAlign(LEFT);
fill(255);
text(handles[i].value,197,20+i*15);
}
}
public class Handle {
float fMin=0, fMax=1, value=.5;
int x = 0;
int y = 0;
int w = 115; //width
int h = 12; //height
Handle() {
}
Handle(float fMin, float fDefault, float fMax) {
this.fMin = fMin;
this.fMax = fMax;
this.value = fDefault;
}
void draw(int x, int y) {
this.x = x;
this.y = y;
if (mousePressed && mouseY>=y && mouseY<=y+h && mouseX>=x && mouseX<=x+w) {
value = fMin + float(mouseX-x)/w * (fMax-fMin);
}
noFill();
stroke(255);
rect(x,y,w,h);
noStroke();
float normValue = (value-fMin)/(fMax-fMin);
fill(180);
rect(x+2,y+2,normValue*(w-3),h-3);
}
}