Olin Kirkland
Olin Kirkland

Reputation: 545

How to center a TextField with spaces at the end?

I've got an application in which some text expands from the center of a TextField one letter at a time. It works just fine as long as there are no spaces, but as soon as a space is reached in the string, it is ignored until a non-space is reached, at which point the text centers itself in the TextField.

myText is a TextField on the stage with centered text as its default alignment.

// Write the words
var charBetweenWords:String = " ";
var whatToWrite:String = "THERE ARE 200 BARRELS OF OIL IN ONE TANKER TRUCK";
whatToWrite = whatToWrite.split(" ").join(charBetweenWords);
var wordTimer:Timer = new Timer(100, 1);
wordTimer.addEventListener(TimerEvent.TIMER_COMPLETE, wordHandler);
function wordHandler(e:TimerEvent)
{
    if (whatToWrite.length > 0)
    {
        myText.appendText(whatToWrite.substr(0, 1));
        whatToWrite = whatToWrite.substr(1);
        wordTimer = new Timer(5, 1);
        wordTimer.addEventListener(TimerEvent.TIMER_COMPLETE, wordHandler);
        wordTimer.start();
    }
    else
    {
        // Done
    }
}
wordTimer.start();

I've considered replacing the spaces with a non-space (but still whitespace) character like /u0020, but the font I'm using doesn't appear to support that. No spaces appear at all when I do that (but a trace of whatToWrite returns boxes between the words).

The Flash IDE doesn't center text considering spaces at the end. myText is placed in the Flash IDE and not initialized in code.

What can I do to make this work?

Upvotes: 2

Views: 171

Answers (2)

BotMaster
BotMaster

Reputation: 2223

Better would be to create a custom class and use masking with a full textfield that slides in. As the textfield slides in you expand the custom class size and you will get a smoother result. But anyway you can get very precise result using the TextLineMetrics class that gives a bunch of info about all characters in a text. A simpler way is to get the boundaries of the characters:

import flash.geom.Rectangle;

var whatToWrite:String = "THERE ARE 200 BARRELS OF OIL IN ONE TANKER TRUCK";
var wordTimer:Timer = new Timer(25);
wordTimer.addEventListener(TimerEvent.TIMER, wordHandler);
wordTimer.start();
var textWidth:Number = 0;
function wordHandler(e:TimerEvent)
{
    if (whatToWrite.length)
    {
        myText.appendText(whatToWrite.substr(0, 1));
        var rect:Rectangle = myText.getCharBoundaries(myText.text.length - 1)       
        textWidth += rect.width;        
        myText.width = textWidth + 5//compensate for rect with + 5
        whatToWrite = whatToWrite.substr(1);
        myText.x = stage.stageWidth / 2 - myText.width / 2
    }
    else
    {
        wordTimer.stop();
    }
}

Upvotes: 1

BadFeelingAboutThis
BadFeelingAboutThis

Reputation: 14406

Perhaps there is a better way (that would be great if someone found a better way), but for now, this is the solution/hack I came up with: (single line only)

var whatToWrite:String = "THERE ARE 200 BARRELS OF OIL IN ONE TANKER TRUCK";    
var wordTimer:Timer = new Timer(100, 1);
wordTimer.addEventListener(TimerEvent.TIMER, wordHandler);

//set the the auto size to left so the width matches the text width
myText.autoSize = TextFieldAutoSize.LEFT;

function wordHandler(e:TimerEvent)
{
    if (whatToWrite.length > 0){
        //if the new character to add is a space, replace it with an underscore
        var newChar:String = whatToWrite.substr(0, 1);
        var charToAdd = newChar == " " ? "_" : newChar;
        myText.appendText(charToAdd);

        whatToWrite = whatToWrite.substr(1);

        wordTimer.reset();
        wordTimer.delay = 150;
        wordTimer.start();

        //center the text field manually
        myText.x = (stage.stageWidth - myText.width) * 0.5;

        //if it was originally a space, take off the underscore and make it a space again.
        if(newChar == " ") myText.text = myText.text.substring(0,myText.text.length-1) + " ";

    }
    else
    {
        // Done
    }
}

wordTimer.start();

If you need multiple lines, you'd have to programatically split up each line into it's own text field.

Upvotes: 2

Related Questions