Recently somebody asked about creating multi-column text flow in ActionScript 2. I have suggested ActionScript 3 since it offers relatively simple solution, but after few minutes of thinking also figured out a solution for ActionScript 2. I know that AS2 is quite obsolete now and I personally don’t use it, only when it is unescapable, but probably there are still many people using it on daily basis for different reasons (legacy projects, target player version limitations, etc.), so even an AS2 solution may be useful.
So, how to do that in AS2? Since there is no built-in support for formatting a text field’s content into multiple columns, we have to create it from scratch. Placing text fields beside each other and filling them with text chunks, which exactly fit into them seems to be what we need. The only problem is splitting the text to be displayed into chunks according to columns. Basically we need to know where is the end of the text that fits into a text field (= column) in order to determine the beggining of the text to be placed into the next text field or column. In AS2 there is no way to know which is the last visible character in a text field, but we have information on the vertical scroll position of the last line and it will be quite enough for us. We will not split the text into parts, instead we place the same text into each column (= text field) and set their vertical scrolling position based on the last visible line of the previous column. The scrolling position of the first visible line can be set by the scroll property of the TextField class, and the scroll position of the last line is in the bottomScroll property. The last column requires a little bit more attention, since its visible content probably will not fill the entire column, but a text field’s last line can be displayed at the bottom only. In order to avoid this we will add some blank lines to the content of the last column.
Here is the proof of concept script, which takes a string and creates as many text fields (= columns) as many required to display the whole text. The script can be placed directly on a frame of an empty .fla and it will work. This script is a proof of concept only, it could be wrapped into a nice class for general use, but this work should be done by somebody else
(or by me, if I will need it in a real project, but that’s not the case at the moment).
// the text to be displayed in multiple columns var text: String = "Lorem ipsum dolor sit amet..."; // the width of a column in pixels var columnWidth: Number = 200; // the height of a column in pixels var columnHeight: Number = 300; // the space betweeb columns in pixels var columnSpacing: Number = 10; // the format of the text in the columns var tf: TextFormat = new TextFormat(); tf.font = "Arial"; tf.size = 12; tf.align = "left"; tf.color = 0x000000; // the index of the column currently processed var colIndex: Number = 0; // the index of the previous column var prevColumn: TextField; // true, if we have placed the last column and can quit the loop var done: Boolean = false; do { // create a text field for the current column var column: TextField = createTextField("column" + colIndex, getNextHighestDepth(), colIndex * (columnWidth + columnSpacing), 0, columnWidth, columnHeight); // set some properties of the text field column.border = true; column.multiline = true; column.wordWrap = true; // selectable should be false, otherwise the text field's content will be scrollable, // and that can mess our precisely positioned text columns column.selectable = false; column.setNewTextFormat(tf); // place the whole text into each column column.text = text; // if it is not the first column... if (prevColumn != null) { // check whether the last visible line is beyond the last scrollable line, so did we reach // the last text chunk and the last column or not if (prevColumn.bottomScroll > prevColumn.maxscroll) { // calculate how many lines are missing from the last chunk to form a whole column var missingLines: Number = prevColumn.bottomScroll - prevColumn.maxscroll + colIndex; // append so many lines to the content of the last column var s: String = ""; for (var i: Number = 0; i < missingLines; i++) s += "\n"; column.text += s; // and quit at the end of the loop, since we reached the last column done = true; } // scroll to the line following the last visible line of the previous column column.scroll = prevColumn.bottomScroll + 1; } else { // in the case of the first column check whether we have the text // long enough for displaying at least one more column (is the text field scrollable) if (column.maxscroll <= 1) done = true } prevColumn = column; colIndex++; } while (!done);
That’s all – enjoy
Update: I corrected the script according to Mau’s observation. Thank you Mau for catching the bug!
October 7th, 2009 at 11:58
Great! This is exactly what i am looking for. How do you do it for AS3?
December 17th, 2009 at 21:58
Hello!
I thought u had save the day… been searching for this for a long time!
BUT…
Have you tested it??
It seems there is some kind of bug!
The text repeats in the end… have you an email to where I can send you the file so you see what’s happening?
try to copy the second paragraph from this post and use it to see what I mean!
Hope you can solve it!! =)
December 17th, 2009 at 22:14
I guess I found the bug… =)
Instead of:
var missingLines: Number = prevColumn.bottomScroll – prevColumn.maxscroll;
Use:
var missingLines: Number = prevColumn.bottomScroll – prevColumn.maxscroll + (colIndex);
December 19th, 2009 at 04:26
Mau: Thank you for catching this bug, I will update the post. Actually I have not tested it thoroughly, since I did not need it personally, and worked it out quickliy as a proof-of-concept script only