One By One Design

Event.EXIT_FRAME && Multi Column Text in Flash 10

All right, I’ll be the first in class to raise my hand and ask a potentially stupid question: What the hell is Event.EXIT_FRAME for? Playing around with it, it seems to do the same thing as Event.ENTER_FRAME. In fact, contrary to what I was expecting, it seems to fire before the ENTER_FRAME event. Most peculiar, mama. Of course, it’s entirely possible that .swf applications begin by leaving a frame rather than entering one. Not really something I’d ever considered before. In any case, if anyone wants to shed some light on the purpose of this odd event, I’d be most obliged.

In the meantime, while I’ve seen plenty of examples of 3d and sound generation, I haven’t seen much on the new text engine in the Flash 10 player, so I threw together my own example. There may be an easier way to do this, but this is new territory, man. Besides, this isn’t that complicated considering it generates dynamic multi-columned text. And just look at that purty antialiased system font.

The class in question:

package {

	import com.onebyonedesign.ui.events.ComboBoxEvent;
	import com.onebyonedesign.ui.OBO_ComboBox;
	import flash.display.Sprite;
	import flash.text.engine.ContentElement;
	import flash.text.engine.TextJustifier;
	import flash.text.engine.LineJustification;
	import flash.text.engine.TextBlock;
	import flash.text.engine.TextElement;
	import flash.text.engine.GroupElement;
	import flash.text.engine.TextLine;
	import flash.text.engine.ElementFormat;
	import flash.text.engine.FontDescription;

	[SWF(width="500", height="500", backgroundColor="#FFFFFF", framerate="31")]
	public class MultiColumnTextExample extends Sprite {

		private var _numLines:int = 20;
		private var _lineWidth:int = 150;
		private var _linesCB:OBO_ComboBox;
		private var _widthCB:OBO_ComboBox;

		private var _textBlock:TextBlock;
		private var _textLines:Vector.;

		private var _textHolder:Sprite = new Sprite();

		public function MultiColumnTextExample():void {

			var format:ElementFormat = new ElementFormat();
			var fontDescription:FontDescription = new FontDescription("Arial");
			format.fontSize = 11;
			format.fontDescription = fontDescription;

			var testString:String = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas at leo eget nisl porta viverra. Ut laoreet, dui at tempus vestibulum, eros leo egestas neque, id adipiscing odio eros et lectus. Vivamus pretium lorem sit amet nulla. Praesent nec dolor at augue ultrices blandit. Quisque aliquet ultrices mi. Donec ac nibh. Phasellus sed sem sed mauris mattis laoreet. Ut fermentum augue ac pede. Duis vitae augue sed nulla lacinia tempor. Pellentesque non ante in magna tincidunt malesuada. Nunc eu mi. Nulla adipiscing posuere nunc. Donec congue, sem vitae aliquam sagittis, tellus lectus laoreet libero, in interdum mi dui ut tellus. Nam pulvinar nibh a ante. Maecenas laoreet placerat ante. Vivamus feugiat magna ut leo. Integer sed risus. Quisque porttitor massa a sem. Sed mollis, purus vel condimentum tristique, enim wisi gravida erat, at hendrerit libero neque sit amet felis. Duis quis erat sed est vestibulum viverra. Sed eu wisi. Praesent nunc. Pellentesque porttitor, augue quis commodo accumsan, purus lorem ullamcorper eros, eu mollis wisi sapien vel lectus. Vivamus metus wisi, sollicitudin a, bibendum quis, dictum ut, lectus. In hac habitasse platea dictumst. Cras eget purus. Vestibulum turpis. Sed ultricies, neque id cursus pretium, nibh tellus eleifend metus, sit amet tempus augue magna at dolor. Proin eleifend. Sed laoreet pharetra quam. Sed gravida pharetra eros. Praesent feugiat. Vestibulum in ligula. Sed in tellus sed lorem pretium accumsan. Vivamus fringilla, neque ac venenatis varius, orci pede lobortis est, quis volutpat arcu leo vel mauris. Curabitur imperdiet nunc nec nunc.";

			var textElement:TextElement = new TextElement(testString, format);
			var groupVector:Vector. = new Vector.();
			groupVector.push(textElement);
			var groupElement:GroupElement = new GroupElement(groupVector);

			_textBlock = new TextBlock();
			_textBlock.content = groupElement;
			createTextLines();

			_linesCB = new OBO_ComboBox("Number of lines per column:", _numLines.toString(), [ { label:"20", data:20 }, { label:"25", data:25 }, { label:"30", data:30 }, { label:"35", data:35 } ], 40);
			_linesCB.addEventListener(ComboBoxEvent.OPTION_SELECTED, comboHandler);
			_linesCB.x = 20;
			_linesCB.y = 470;
			addChild(_linesCB);

			_widthCB = new OBO_ComboBox("Number of characters per column:", _lineWidth.toString(), [ { label:"100", data:100 }, { label:"150", data:150 }, { label:"200", data:200 } ], 40);
			_widthCB.addEventListener(ComboBoxEvent.OPTION_SELECTED, comboHandler);
			_widthCB.x = _linesCB.x + _linesCB.width + 20;
			_widthCB.y = 470;
			addChild(_widthCB);

			addChild(_textHolder);
		}

		private function comboHandler(event:ComboBoxEvent):void {
			clearTextLines();
			if (event.currentTarget == _linesCB) {
				_numLines = event.data;
			} else {
				_lineWidth = event.data;
			}
			createTextLines();
		}

		private function clearTextLines():void {
			// release previous lines for potential garbage collection
			_textBlock.releaseLines(_textBlock.firstLine, _textBlock.lastLine);

			// remove the previous lines from the text holding sprite
			var len:int = _textLines.length;
			for (var i:int = 0; i < len; i++)
				_textHolder.removeChild(_textLines[i]);
		}

		private function createTextLines():void {

			var xPos:int = 0;
			var yPos:int = 0;
			var textLine:TextLine = _textBlock.createTextLine(null, _lineWidth);
			var currentLine:int = 1;

			// rewrite the _textLines vector
			_textLines = new Vector.();

			while (textLine) {
				_textHolder.addChild(textLine);
				_textLines.push(textLine);
				textLine.x = xPos;
				yPos += textLine.textHeight + 3;
				textLine.y = yPos;
				textLine = _textBlock.createTextLine(textLine, _lineWidth);
				if (currentLine++ % _numLines == 0) {
					xPos += _lineWidth + 5;
					yPos = 0;
				}
            }
        }
    }
}

and the example (which, again, requires the Flash 10 player to be installed):

[kml_flashembed movie=”http://blog.onebyonedesign.com/wp-content/uploads/2008/05/f10text.swf” height=”500″ width=”500″ /]

Posted by