Tutorial details:
Written by: Shaun Inman
Time: 30 min. tops
Difficulty Level: Advanced
Requirements: Flash 5 (the pixel font "standard 07_53" is recommended)
Assumed Knowledge: user-defined functions, basic understanding of the use of array and string indexes

Download the source.

This example dynamically reflows text based on user input. It is used to replace certain spaces with line breaks in existing text but it could be modified to find and replace entire strings.

Before you read any further I want to make it clear that using html-enabled textboxes causes this function to create unexpected line breaks because there is no way for the current reflow() function to distinguish between html and display text. Using html-enabled textboxes WILL increase the minimum pixels per line length (which renders the function pretty much useless). If you attempt to rework it to account for HTML feel free to contact me with questions about the existing code or to share the reworked code.

Font Choice Note:
The value used to calculate the charPerLine variable (.24 or 24 letters per 100 pixels) is determined by the typeface you choose. For this example I used a face specially developed for use with Flash, standard 07_53, designed by Craig Kroeger and is available for free at www.miniml.com (be sure to read the READ_ME). If you wish to use another font look in the movie clip "charactersPer100px" for the necessary tools to calculate this value.

Please download the source FLA to view the document set up. It's ridiculously simple - only four symbols (and two aren't even necessary for the script to work) - so I'll jump straight into the code that is all on frame 1 of the main movie:

var initText = "...(your text here)";

This is the text that will be reflowed according to user input. Make sure that there are no line returns/new lines in your text if you load it from an external source since this script won't account for existing line returns/new lines. Maybe in version two...

var charPer100px = .24;

This sets the number of characters tat can fit in a width of one hundred pixels. If you're not using the font "standard 07_53" this number may be different.

function reflow () {
  if (lineLength && lineLength<530 && lineLength>99) {

"If the user has entered any value and if it is a usable value..." The value multiplied by charPer100px must be greater than the longest word in your text or the following for() will get stuck in an interminable loop and may crash the computer.

// trace ("i hear you - i just don't care");

If for some reason you have moved the button that calls reflow() into another movie and it no longer works uncomment this trace() to make sure that you are targeting it correctly.

var charPerLine = Math.floor(Number(lineLength)*Number(charPer100px));

This determines the number of letters per line for the entered lineLength

var initLinesReq = Math.ceil(initText.length/charPerLine);

This is an initial estimation of the number of lines the new text will require. This value will be updated throughout the reflowing function.

var linesReq = initLinesReq;

The number of times the for() will loop.

var reflow;

An empty variable that the for() will fill with our reflowed text.

for (var i = 0; i <= Number(linesReq); i++) {
            var idealBreak = Number(prevBreak + charPerLine);

Estimates the next ideal place for a new line based on the charPerLine and starting position of the end of the previous new line.

if (i != Number(linesReq)) {

"If this isn't the last time through the loop..." This is a necessary distinction. Without it the last word would always be isolated on its own line.

var nextLine = (initText.substring(Number(prevBreak),
      Number(initText.lastIndexOf(" ", idealBreak))));

This is the first line of the new text. The substring() "copies" some text from where the last line began (prevBreak or 0 if it is the first time through) and ends at the first space found counting backwards from the idealBreak. (This should all be one line instead of two. I broke it up to preserve the line length of this html document.)

var prevBreak = Number(initText.lastIndexOf(" ", idealBreak)+1);

"Remembers" the index of the character after the space that nextLine "copied" up to. For use when determining the idealBreak in the next loop.

var remainText = (initText.substring(
            Number(initText.lastIndexOf(" ", idealBreak)+1)));

"Copies" remaining text. (This should all be one line instead of two. I broke it up to preserve the line length of this html document.)

freshLinesReq = Math.ceil(remainText.length/charPerLine);

Updates the number of remaining loops.

linesReq = freshLinesReq;

Resets the counter of the for() loop in case the number of lines required was more than the initial calculation

reflow += nextLine+" ";

"Pastes" nextLine to the existing reflowed text

      else {

We're almost done - this is pulling out the last line!

nextLine = (initText.substring(prevBreak));

"Copy" the remaining a text.

reflow += nextLine;

"Pastes" the final bit of text into reflow.


Updates the on screen text with the new reflowed text.

    else {
      text="please enter a number less than 530 (the width of this swf)
      and greater than 99."

Notify the user of unacceptable values. (This should all be one line instead of two. I broke it up to preserve the line length of this html document.)


And to finish it up just call the function _root.reflow(); from an on (release) or onClipEvent (load). onClipEvent (enterFrame) is not recommended since string handling can be processor intensive. That's all there is to it. If anyone does anything interesting with this code send me a link - I'd love to see it.