Reputation: 545
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
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
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