Wednesday, April 23, 2008
The current implementation below allows for the adjustment of chunks and the speed in which the chunks are rendered.
This is a quick implementation that indeed works, but its picky about the specified container at the moment, but it could be expanded upon to include line by line rendering, fading in text elements as they are placed (that would be pretty snazzy), etc.
If you know of existing classes that provide interesting textual placements, please share with us.
Anyway, I have three classes: StringFeeder.as, FeedUpdateEvent.as, and Application.as. The Application class is the document class here and simply provides a little testing environment.
How this works is when you tell the StringFeeder class instance to run, it requires the use of an eventListener to supply the bits of text to render in a text field. So if you don't listen for the UPDATE event, you won't be able to do much with any of this code. I'll bold that listener for you where it's used.
FeedUpdateEvent.as
package net.ericd.v8.events
{
import flash.events.Event;
import flash.text.TextField;
/**
* This class allows one to pass properties on the event
* object, to make things easier to implement.
*/
public class FeedUpdateEvent extends Event
{
public static const UPDATED:String = "EVENT_FEED_UPDATE";
public static const DONE:String = "DONE";
public var value:String;
public var who:TextField;
public function FeedUpdateEvent( type:String,
value:String,
who:TextField )
{
super( type );
this.value = value;
this.who = who;
}
public override function clone():Event
{
return new FeedUpdateEvent( type,
this.value,
this.who );
}
}
}
You can always go ahead and add more types of your own liking, but the constructor expects those two properties. I suppose you could rest that (...) so you'd have the option of sending more (I've never tried that with events though... wonder if it would work at all).
StringFeeder.as
package net.ericd.v8.content
{
import flash.display.Sprite;
import flash.text.TextField;
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.*;
import net.ericd.v8.events.FeedUpdateEvent;
public class StringFeeder extends Sprite
{
private var $array:Array;
private var $string:String;
private var $speed:Number;
private var $target:TextField;
private var $delay:Timer;
private var nCount:Number = 0;
private var nTotalCount:Number = 0;
private var nextStart:Number = 0;
private var nextEnd:Number = 0;
private var $eachCut:Number = 4;
private var nRunLimit:Number;
private var myEvent:FeedUpdateEvent;
public function StringFeeder( oTarget:*, sValue:String,
nSpeed:Number )
{
this.$string = sValue;
this.$speed = nSpeed;
this.$target = oTarget;
nRunLimit = Math.ceil( $string.length / $eachCut );
}
private function sendData( event:TimerEvent ):void
{
var sSnippet:String = $string.substring( nextStart,
nextEnd );
myEvent = new FeedUpdateEvent( FeedUpdateEvent.UPDATED,
sSnippet, $target );
this.dispatchEvent( myEvent );
nextStart = nextEnd;
nextEnd += $eachCut;
if ( nTotalCount > nRunLimit )
{
$delay.stop();
var doneEvent = new FeedUpdateEvent(
FeedUpdateEvent.DONE,
null, $target );
this.dispatchEvent( doneEvent );
return;
}
nTotalCount++;
}
public function run():void
{
nextStart = 0;
nTotalCount = 0;
nextEnd = nextStart + $eachCut;
$delay = new Timer( $speed );
$delay.addEventListener( TimerEvent.TIMER,
sendData );
$delay.start();
}
public function set span( eachCut:Number ):void
{
$eachCut = eachCut;
nRunLimit = Math.ceil( $string.length / $eachCut );
}
public function get span():Number
{
return $eachCut;
}
public function interrupt():void
{
$delay.stop();
}
}
}
A little ugly, but again, she does work.
Application.as code
And here is some code from the Application document class. There is an instance of a MovieClip containing a TextField on the stage already, "holder_mc.test_txt". I am copying and pasting some code out of the live class, so if I miss something, the compiler errors/warnings should be able to direct you.
import flash.text.TextField;
import flash.display.MovieClip;
import gs.TweenFilterLite;
import gs.TweenLite;
import net.ericd.v8.content.StringFeeder;
import net.ericd.v8.events.FeedUpdateEvent;
...
var bigText = "huge string here please...* for linefeed";
feeder = new StringFeeder( holder_mc.test_txt, bigText, 10 );
feeder.span = 12;
feeder.addEventListener( FeedUpdateEvent.UPDATED, updateFeedText );
//DONE event only for blur effect. Actually ugly.
feeder.addEventListener( FeedUpdateEvent.DONE, finishedUpdate );
TweenFilterLite.to( holder_mc, 0, { blurFilter:{blurX:5, blurY:5}});
feeder.run();
...
private function updateFeedText( event:FeedUpdateEvent ):void
{
var tmpString:String = stringReplace( event.value, "*", "\n" );
event.who.appendText( tmpString );
}
private function stringReplace( $str:String, $search:String,
$replace:String ):String
{
return $str.split($search).join($replace);
}
private function finishedUpdate( event:FeedUpdateEvent ):void
{
// Yes, I know, this thing's parent COULD be the
// document class itself (Application). But since
// we know what's really going on here, s'ok mb.
TweenFilterLite.to( event.who.parent, 2,
{ blurFilter:{blurX:0, blurY:0}});
}
My apologies for this code not being formatted as per long ago. My linefeed settings on publish are a little messed up for posting code, but great for random typing such as this.







