arctext

versions0135+
contributorsmflux
started on2009-09-25 16:36

So you want to display text on an arc. Easy! The following gives you some control over how to display text on a circular path with easy-to-modify code.

note

The kerning is probably not 100% spot on so you may have to adjust this if you want it looking perfect.

Pseudocode

  1. First we gather information for the shape of the circle. So we need stuff like x and y, radius, etc.
  2. Next we find the circumference of a circle which is 2 * PI * Diameter.
  3. Dividing the text width of the word we want to render with the circumference (think of the text hugging a circle) you get an actual “percentage” of how much space the text takes up on the circle.
  4. For each letter in the text, find the angle on the circle where it's supposed to land.
  5. As we're incrementing each letter, also accumulate the text width for each letter so that we know how to space out the next letter
  6. Now that we have the angle and radius, we can find the X/Y position of the letter using sin/cos
  7. Since we have the angle, we can simply rotate each letter by the angle plus 90 degrees so it “arcs” properly.
  8. The final thing to watch out for is to actually rotate from the center of the text, not from the corner.

Source code

Example of usage plus the function. Download below.

/**
arctext taken from http://processinghacks.com/hacks:arctext
@author mflux
*/
 
// the good stuff
void arcText(String text, float x, float y, float radius, float startAngle, float arcScale, int direction){
  if(g.textFont==null)
    return;
  if(text==null)
    return;
  if(text.length()<=0)
    return;
 
  textFont(g.textFont);
 
  float totalWidth = textWidth(text);
  float circumference = PI * radius * 2;  
 
 
  pushMatrix();
  translate(x,y);  
 
  float widthAccumulate = 0;  
 
  for(int i=0; i<text.length(); i++){
    char c = text.charAt(i);         
    float percent = widthAccumulate / circumference;          
    float angle = radians( startAngle + percent * 360 * arcScale) * (direction>=0? 1 : -1);
    widthAccumulate += textWidth(c);     
 
    float px = cos(angle) * radius;
    float py = sin(angle) * radius;   
 
    pushMatrix();
    translate(px,py);
 
    // this rotates from the -center- of the letter
    translate(textWidth(c)/2,0);
    rotate( angle + radians(90));
    translate(-textWidth(c)/2,0); 
    text(c, 0, 0);
 
    popMatrix();
  }
 
  popMatrix();  
}
 
// the example 
PFont font;
 
void setup(){
  size(500,500);
  font = createFont("Verdana-Bold",48);
  smooth();
}
 
void draw(){
  background(255);
 
  fill(0);
  // you have to set a font first!
  textFont(font);
  float radius = mouseX;
  float offset = -mouseY/2;
  arcText("ArcText", width/2, height/2, radius, offset, 1, 1);  
 
}

Related Links

hacks/arctext.txt · Last modified: 2009-09-25 18:05 by mflux