Probably useful snippets: Circle Text

 circle text thumb

Circular text can be useful in several designs, so here is a little class that produces the following:

What the swf shows is first the ‘debug-version’ which changes after a click to the naked text version. Consecutive clicks will produce the same for randomized values.

CircleText.as

package
{
	import flash.display.Sprite;
	import flash.geom.Matrix;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	
	/**
	 * CircleText.as
	 * @author kegogrog
	 */
	public class CircleText extends Sprite
	{
		private static const degToRad:Number = Math.PI / 180;

These are the basic imports and the private var degToRad used for the conversion of degrees into radians.

		public function CircleText( startAngle:Number = -90, endAngle:Number = 90, radius:Number = 80, inner:Boolean = false, text:String = "This text is a test.", debug:Boolean = true )

The class accepts several inputs, the most important are startAngle, endAngle and radius. I hope I do not need to explain those. inner defines if the text is located on the outside of the circle or on the inside. text should be pretty obvious and debug just defines what one can see. I recommend to delete that once the class is implemented while it is nothing the user has to see.

		{
			var tff:TextFormat = new TextFormat();
			tff.font = "calibri";
			tff.size = 20;

It is important to use an embedded font, so here I am just defining a text format. One could also reference that in the constructor or use a global format.

			
			var sr:Number = startAngle * degToRad;
			var er:Number = endAngle * degToRad;
			
			if ( debug )
			{
				this.graphics.lineStyle(0, 0xcccccc);
				this.graphics.drawCircle(0, 0, 3);
				this.graphics.drawCircle(0, 0, radius);
				this.graphics.drawCircle(Math.sin(sr) * radius, -Math.cos(sr) * radius, 4);
				this.graphics.drawCircle(Math.sin(er) * radius, -Math.cos(er) * radius, 2);
			}

The angles are converted to radians and if debug is true the midpoint, the circle itself are drawn and the start and end of the text is marked.

	
			var i:int;
			var tf:TextField;
			var m:Matrix;
			for ( i = 0; i < text.length; i++ )
			{
				tf = new TextField();
				tf.selectable = false;
				tf.autoSize = TextFieldAutoSize.LEFT;
				tf.defaultTextFormat = tff;
				tf.embedFonts = true;
				tf.text = text.charAt(i);
				
				if ( debug )
				{
					tf.background = true;
					tf.backgroundColor = 0xcccccc;
					tf.alpha = 0.8;
				}
				
				m = new Matrix();
				m.translate( -tf.width * 0.5, -tf.height * ( inner ? 0 : 1 ) - radius );
				m.rotate( sr + ( ( er - sr ) / ( text.length - 1 ) ) * i );
				tf.transform.matrix = m;
				
				addChild(tf);
			}
		}
	}
}

The biggest code chunk here splits the string into single characters, creates a textfield for each one and applies translation (depending on inner) and rotation according to the start and end angle and the characters position in the string. The translation in x moves the textfield so that it is centered.

I was using FlashDevelop for this presentation with the following

Main.as

:

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	
	/**
	 * Main.as for CircleText
	 * @author kegogrog
	 */
	public class Main extends Sprite
	{
		[Embed(
			source = 'font/calibri.ttf',
			fontName = "calibri",
			fontWeight = "normal",
			advancedAntiAliasing = "true",
			mimeType = "application/x-font",
			fontStyle = "normal",
			embedAsCFF = 'false',
			unicodeRange = 'U+0020-U+007E'
			)]
		private var calibri:Class;
		
		private var startAngle:Number = -90;
		private var endAngle:Number = 90;
		private var radius:Number = 80;
		private var inner:Boolean = false;
		private var text:String = "This text is a test.";
		private var debug:Boolean = true;
		
		private var ct:CircleText;
		
		public function Main():void
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			buildText();
			stage.addEventListener(MouseEvent.CLICK, buildText);
		}
		
		private function buildText(event:MouseEvent = null):void
		{
			if ( ct )
			{
				removeChild(ct);
			}
			ct = new CircleText( startAngle, endAngle, radius, inner, text, debug );
			ct.x = stage.stageWidth >> 1;
			ct.y = stage.stageHeight >> 1;
			addChild(ct);
			
			if ( !debug )
			{
				startAngle = Math.random() * 360;
				endAngle = startAngle + Math.random() * 180 + 90;
				radius = Math.random() * 30 + 50;
				inner ? inner = false : inner = true;
			}
			debug ? debug = false : debug = true;
		}
	}
}

buildText takes the predefined variables and adds a new CircleText. With the next click it shows the non-debug version and and changes the variables prior to the next click.

Being a sprite, CircleText can be rotated by its own rotation property. One could also put all text fields into an array and animate them, maybe flying of the screen from the center. Have fun playing with that.

Yoho!

This entry was posted in as3, flash, Snippet and tagged , . Bookmark the permalink.

Comments are closed.