views:

699

answers:

2

Has anyone here come up with an elegant way to take a piece of text and make it go around the edge of a line that is warped? (specifically, circular, but I'm sure once it's following the line, the shape is not relevant). I can't find a good resource for how to do this. I assume I'll need to create separate movie clips for each character and then rotate, and position, but I'm having a hard time finding a resource for how to do this.

edit: Sorry, forgot to mention that the text is dynamic, obviously. I'm not interested in how to make static text go in circles :)

+1  A: 

The easiest thing would be to create a movieclip with a textfield in it and aligned so that the bottom left edge of the textfield was on the origin of the movieclip. You'll want to set the textfield's autosize property to "left" so it grows as needed for each letter (this will help you get the kerning right).

Then you just loop over your sentence and create a movieclip for each letter. The only hard part then is getting the position of the next letter.

One way that I've solved this problem in the past that works with any line or curve you could want is to create a very long animation (at least a few hundred frames) of my textfield tweening across the length of the curve I want. Then it's that movieclip that I duplicate. I simply then have to choose, for each letter, what frame on the animation to stop on - this will dictate where the textfield for each letter is actually displayed. It's a hack, but it's worked well in the past.

Branden Hall
I'm up-voting your answer, but am hoping someone can give me a pointer to a more programmatic solution, though I like your hack... it's clever, if not overly elegant.
Dr.Dredel
+3  A: 

Hello there. I've put up an example with 2 classes that write on circles. In order for this to work, you need to put a Sprite in your library with class name Letter. This is for simpler text manipulation. Letter needs to have a TextField, at least 2 letters wide, with instance name value. The text should be centered as well as the textfield itself, centered to the 0.0 coordinates of the sprite.

So. DocumentClass.as

package {

    import flash.display.Sprite;

    public class DocumentClass extends Sprite {

     public function DocumentClass () {
      // draw on circle tester

      var c1:CircleText = new CircleText(200, 200, 90, "Hello World - Circle Text", 0.5, -90);
      var c2:CircleText = new CircleText(300, 300, 50, "Hope you like this", 0.6, -90, true);
      var c3:CircleText = new CircleText(420, 200, 50, "By Virusescu", 0.35, -60);

      this.addChild(c1);
      this.addChild(c2);
      this.addChild(c3);


     }

    }


}

Letter.as package {

import flash.text.TextField;
import flash.display.Sprite;

public class Letter extends Sprite {

 // public var value:TextField; // defined by IDE

 public function Letter(val:String) {
  this.value.text = val;
 }

}

}

CircleText.as

package {

    import flash.display.Sprite;

    public class CircleText extends Sprite {

     public function CircleText(centerX:Number, centerY:Number, radius:Number, string:String, coverage:Number, startAngle:Number, showCircle:Boolean = false) {

      if (showCircle) {
       this.graphics.lineStyle(1, 0xFF0000, 0.5);
       this.graphics.drawCircle(0, 0, radius);
      }


      var step = 360*coverage / (string.length-1);
      // convert to radians
      step = step * Math.PI / 180;

      for (var s = 0; s < string.length; s++) {
       var letter:Letter = new Letter(string.charAt(s)); // from library, check description below
       letter.x = radius*Math.cos(step*s);
       letter.y = radius*Math.sin(step*s);
       letter.rotation = (step*s)*180/Math.PI + 90;
       this.addChild(letter);
      }
      this.x = centerX;
      this.y = centerY;
      this.rotation = startAngle - 90;
     }
    }
}

That's preety much it.

Virusescu
haven't tried this yet, but it looks promising, at a glance. One question... what if you want the text to just follow a crescent? (semi-circle)
Dr.Dredel
If you look at the constructor of CircleText you can see a parameter named coverage. It represents how much of the circle the text should occupy. For a semicircle you put 0.5. For a quarter of circle you put 0.25 and so on. Full circle has coverage = 1 of course.
Virusescu