Ever wanted to be able to display multi-column text in Flash? What about text that spans multiple arbitrary text fields? Sure, Adobe's Text Layout Framework will let you display multi column text, but it's still in beta, not to mention that it's a big, robust framework.
TextFlowLite is a simple, light-weight class that works in Flash Player 9 with standard text fields. It takes one line of code to link any number of text fields together so that the overflow of each textfield runs into the next. Likewise, it's one line of code to change the text, or reflow it if the textfields are resized.
import com.gskinner.text.TextFlowLite; // set up the TextFlow, by default it will use the text of the first field: var tfl:TextFlowLite = new TextFlowLite([fld1,fld2,fl3]); ... // change the text: tfl.text = "my new text"; ... // change the size of a field, and reflow the text: fld1.height += 20; tfl.reflow();
I built this class about a year and a half ago while working on the Spelling Plus Library, and had meant to release it much earlier. It is part of a set including TextFlow (adds support for orphans and widows), and TextFlowPro (which includes support for selection, editing, copy/paste). I will release the other two for free when I have time to retest and clean them up (hopefully later this week).
It's a pretty simple class, but hopefully it's useful for someone. As I said above, I will be releasing TextFlow and TextFlowPro in the near future. You can download the source code by clicking here. As usual, the code is released under the MIT license.

Comments (20)
404 error on the download link.
Posted by: yavstr at January 5, 2009 12:34 PMURL: http://www.yavstr.com
Whoops, fixed now.
Posted by: Grant Skinner at January 5, 2009 12:37 PMURL: http://gskinner.com/blog/
Great tool. Very good.
Posted by: pixel4 at January 5, 2009 01:13 PMURL: http://www.pixel4.com.br
Good work again ;)
Posted by: Armetiz at January 5, 2009 02:32 PMURL: http://www.armetiz.info
Awesome Grant - you're classes always are though!
Posted by: jassa at January 5, 2009 03:54 PMURL: http://www.bangersandflash.net
Cool work Grant! Only thing maybe i have missed something, but can you elaborate the parameters passed to the TextFlowLite Constructor ?
Posted by: Subroto at January 5, 2009 09:35 PMURL:
Hi Subroto,
The constructor takes two parameters. The first is an array of textfields in the order that you want the text to flow through them (ex. in the example above it will flow from fld1 to fld2 to fld3). The second parameter just specifies the text to flow between the fields. If you omit the second parameter, it will default to use the text from the first field specified in parameter 1.
Posted by: Grant Skinner at January 5, 2009 09:57 PMURL: http://gskinner.com/blog/
Looks amazing.
How's the performance when using embedded fonts and anti-aliasing? We've used and developed various layout engines over the years and flash's rendering of fonts have always been a performance issue.
Posted by: Torbjørn Caspersen at January 6, 2009 12:37 AMURL:
Great, thanks!
Posted by: Jankees at January 6, 2009 02:25 AMURL: http://blog.base42.nl
Awesome Grant! It would be great to add a vertical scrollbar to this text!
Posted by: Anton Granik at January 6, 2009 02:31 AMURL: http://granik.com
Really nice Grant.
Posted by: William from Lago at January 6, 2009 03:06 AMURL: http://williamukoh.com
Awesome man, this is great. This is the one thing Flash was always missing. Thanks for all of your hard work. - Chris
Posted by: chris at January 14, 2009 09:45 AMURL:
Lovely. Using it now.
Posted by: myGengo at January 14, 2009 09:07 PMURL: http://mygengo.com
Very nice, thank you! How about selecting the text from one column into another and htmlText so the tag wouldn't break?
Posted by: Rodney at January 15, 2009 10:09 AMURL:
To use this with htmlText just replace the 2 lines (65+66):
fld2.text = fld1.text.substr(nextCharIndex).replace(/^\s+/, '');
fld1.text = fld1.text.substr(0,nextCharIndex).replace(/\s+$/, '');
with:
var splitChar:String = "ҖҖ"; //any string that is unique in the text
fld1.replaceText(nextCharIndex, nextCharIndex, splitChar);
var nextHtmlCharIndex:Number = fld1.htmlText.indexOf(splitChar);
fld2.htmlText = fld1.htmlText.substr(nextHtmlCharIndex).replace(/^\s+/, '');
fld1.htmlText = fld1.htmlText.substr(0, nextHtmlCharIndex).replace(/\s+$/, '');
Hope that helps.
Posted by: Josh at January 20, 2009 04:07 AMJosh
URL: http://www.joschaunger.de
Awsome but i still didn't understand how to use htmlText...
Posted by: Michele at June 29, 2009 02:20 AMIf i have a tag eg:visit the google website what do i have to replace?
(instead of "var splitChar:String = "ҖҖ"; //any string that is unique in the text")
Thank you in advance
URL:
I think that he's implying when you use "ҖҖ" in the text you are flowing across columns, you can split the column at this point... which only works when you know exactly where you want to break columns (i.e. when you are not resizing anything). Are there any better solutions for dynamic html content?
Posted by: wes at August 23, 2009 02:40 PMURL:
thanks for the class. i have a little addition that would make it even more useful:
- a boolean property to find out if there is some hidden overflowed text.
- a number property to find out how much lines or pixelheight of hidden overflowed text there is.
those properties would offer a dynamic way to add textfields at runtime to show all the text. what do you think about that?
Posted by: lauritz at September 25, 2009 11:27 AMURL:
There is a mistake in your example for HtmlText! The split Char in your Example is a know a visible part of the splitted text. To remove the splitChar, you have to remove the splitchar after processing with the following line:
fld2.htmlText = StringUtil.replaceString(fld2.htmlText, splitChar, '');
To use this with htmlText just replace the 2 lines (65+66) with the (corrected) line:
var nextCharIndex:Number = fld1.getLineOffset(fld1.bottomScrollV);
var splitChar:String = "ҖҖ"; //any string that is unique in the text
fld1.replaceText(nextCharIndex, nextCharIndex, splitChar);
var nextHtmlCharIndex:Number = fld1.htmlText.indexOf(splitChar);
fld2.htmlText = fld1.htmlText.substr(nextHtmlCharIndex).replace(/^\s+/, '');
fld1.htmlText = fld1.htmlText.substr(0, nextHtmlCharIndex).replace(/\s+$/, '');
//remove splitChar
fld2.htmlText = StringUtil.replaceString(fld2.htmlText, splitChar, '');
Posted by: screenworker at October 22, 2009 03:52 PMBest regards
screenworker, Berlin
URL:
Thanks! Worked first time.
Posted by: Kyle at February 10, 2010 11:09 PMURL: http://www.kyleward.co.za