gSkinner - Home

Multi Column Text in Flash 9: TextFlowLite

Posted on January 5, 2009 by Grant Skinner

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).

Here’s a simple demo:


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.

Follow @gskinner on Twitter for more news and views on interactive media.
25 Comments

404 error on the download link.

Posted by: yavstr on Jan 5, 2009 12:34pm URL: http://www.yavstr.com

Whoops, fixed now.

Posted by: Grant Skinner on Jan 5, 2009 12:37pm URL: http://gskinner.com/blog/

Great tool. Very good.

Posted by: pixel4 on Jan 5, 2009 1:13pm URL: http://www.pixel4.com.br

Good work again ;)

Posted by: Armetiz on Jan 5, 2009 2:32pm URL: http://www.armetiz.info

Awesome Grant - you're classes always are though!

Posted by: jassa on Jan 5, 2009 3:54pm URL: 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 on Jan 5, 2009 9:35pm

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 on Jan 5, 2009 9:57pm URL: 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 on Jan 6, 2009 12:37am

Great, thanks!

Posted by: Jankees on Jan 6, 2009 2:25am URL: http://blog.base42.nl

Awesome Grant! It would be great to add a vertical scrollbar to this text!

Posted by: Anton Granik on Jan 6, 2009 2:31am URL: http://granik.com

Really nice Grant.

Posted by: William from Lago on Jan 6, 2009 3:06am URL: 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 on Jan 14, 2009 9:45am

Lovely. Using it now.

Posted by: myGengo on Jan 14, 2009 9:07pm URL: 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 on Jan 15, 2009 10:09am

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.

Josh

Posted by: Josh on Jan 20, 2009 4:07am URL: http://www.joschaunger.de

Awsome but i still didn't understand how to use htmlText...

If 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

Posted by: Michele on Jun 29, 2009 2:20am

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 on Aug 23, 2009 2:40pm

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 on Sep 25, 2009 11:27am

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, '');

Best regards

screenworker, Berlin

Posted by: screenworker on Oct 22, 2009 3:52pm

Thanks! Worked first time.

Posted by: Kyle on Feb 10, 2010 11:09pm URL: http://www.kyleward.co.za

Thanks!

Posted by: Graham on Apr 25, 2010 3:55am URL: http://www.graham-mitchell.com

quite cool, thx alot - with the HTML fix it´s really great stuff. This is my solution:

********************

protected function flowField(fld1:TextField,fld2:TextField):void {

fld1.scrollV = 1;

fld2.htmlText = "";

if (fld1.maxScrollV

Posted by: Oxigan on Apr 30, 2010 5:41am

Great!

Could someone point me in the right direction for implementing this with dynamically added textfields?

Thanks,

Chris

Posted by: Chris on Jun 23, 2010 11:43pm URL: http://www.chriseriksson.com

Having some troubles here...

line 62: 1170 Function does not return a value.

line 68: 1170 Function does not return a value.

Posted by: k on Sep 27, 2010 1:00am

The source code download seems to be for the AS3 version. Is there still an AS2 version?

Posted by: Danny on Feb 15, 2011 2:08pm

Leave a Reply

Your email is never published nor shared.




You may use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">