Flash CS3 – Quote Rotator

All began a while ago while answering some questions on the Adobe Flash Forums, I ran into a guy (sorry forgot the name) asking on how to create a quote rotator in Flash. I thought this shouldn’t be a big issue.. Load an XML with the data in, display it in flash, and create a setinterval which let’s our quotes rotate. hmm.. did I mention he wanted to use actionscript 3? Still not that hard, but for people that were used to work with actionscript 2.0 and didn’t migrate yet, it could cause a few problems.
Don’t look at this tutorial as if it could only be used for text, with this code you can also rotate images or banners, actually you can rotate every kind of object, you just need to re-write the code a tiny little bit. Let’s get it on..

First of all let’s create our XML file which will act as a dataholder for our quotes. As you see it’s a very very basic XML holding our quotes and author contents, in our case simple text.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<quotes>
<quote>
<text>What makes a river so restful to people is that it doesn't have any doubt
 - it is sure to get where it is going, and it doesn't want to go anywhere else.</text>
<author>Hal Boyle</author>
</quote>
<quote>
<text>Knowing trees, I understand the meaning of patience. Knowing grass, 
I can appreciate persistence. </text>
<author>Hal Borland</author>
</quote>
<quote>
<text>For every person who has ever lived there has come, at last, 
a spring he will never see. Glory then in the springs that are yours. </text>
<author>Pam Brown</author>
</quote>
<quote>
<text>All things are artificial, for nature is the art of God. </text>
<author>Thomas Browne</author>
</quote>
<quote>
<text>Autumn is a second spring when every leaf is a flower. </text>
<author>Albert Camus</author>
</quote>
</quotes>

Ok, now that the pre work is done the next step is where it begins to get interesting. Let’s fire up Flash and create a new Actionscript 3 document.

I’ve setup my document to a size of 460×90 px, of course you are free to use your own settings.
Next we need to create 2 dynamic textfields which will be holding the quote & the author informations that are being passed from our XML file we created earlier. So go on create 2 textfields keep in mind that the one holding the quotes should be rather big and wide so it has enough space to fit the content, mine has following settings:

InstanceName: quotes_txt
Width: 439
Height: 60
X: 228
Y: 9

Last but not least we need to create the author text field which of course will hold our author’s name:

InstanceName: author_txt
Width: 138
Height: 21
X: 376
Y: 66

Flash isn’t capable of animating textfields (you can move a textfield left and right by using another movieclip but that’s not what we want to achieve) so therefore select the quote textfield and press F8 to wrap the textfield into a movieclip, give it a suitable name and press OK, do the same procedure for the author textfield, at the end you should have 2 textfields each inside of a movieclip. Give those movieclips an unique instance name, I named them quoteMC and authorMC.

It’s always good to have instance names that describe most accurately by the name what kind of symbol it’s holding.
I’m used to assign InstanceNames as follow:

Buttons: xxxBtn
Movieclips: xxxMC
Graphics: xxxBM
Textfields: xxx_txt

You can start with the ones above or create your own rules, just be sure that you feel comfortable with them and that keep in mind to keepm them consistent throughout the whole script.

Now that you are ready to start scripting create a new layer and re-name it to “actions”, lock the layer instantly so you can’t insert any objects into it. Select the first frame if not selected already and press F9 to open the actionscript panel. Now this is where our fun will begin to start.

Here the complete code that you are going to create:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var quote:Array = new Array();
var author:Array = new Array();
var totalQuotes:Number;
 
var rotateTimer:Timer = new Timer(2000, 100);
rotateTimer.addEventListener("timer", rotateQuote);
rotateTimer.start();
 
function init():void {
	var quotesXML:XML = new XML();
	quotesXML.ignoreWhitespace = true;
	var XMLURL:URLRequest = new URLRequest("http://localhost/quoteRotator/quotes1.xml");
	var myLoader:URLLoader = new URLLoader(XMLURL);
	myLoader.addEventListener("complete", xmlLoaded);
	function xmlLoaded(event:Event):void {
		quotesXML = XML(myLoader.data);
		totalQuotes = quotesXML.quote.length();
		for (var i:int = 0; i < quotesXML.quote.length(); i++) {
			quote[i] = quotesXML.quote[i].text;
			author[i] = quotesXML.quote[i].author;
		}
	}
}
 
function rotateQuote(evt:TimerEvent) {
	var randomness:Number = randomNumber(0, totalQuotes);
	quoteMC.quote_txt.text = quote[randomness];
	authMC.author_txt.text = author[randomness];
}
 
function randomNumber(low:Number, high:Number):Number {
	var low:Number = low;
	var high:Number = high;
	return Math.round(Math.random() * high - low) + low;
}
 
init();

And now let’s start looking at every line of the code, I’ll try to explain every line as accurate as possible but I’m assuming as well that you already know a few basics of actionscript.

1
2
3
var quote:Array = new Array();
var author:Array = new Array();
var totalQuotes:Number;

Here we are going to define 2 new arrays and initialize them, as we want to save our data from the XML into a simple array, arrays are very powerful holding data, are indexable and really really handy for such tasks, with the last line we create an empty variable which will hold our total Amount of quotes, we're creating it right at the top so it can be scoped from every function further down.

1
2
3
var rotateTimer:Timer = new Timer(2000, 100);
rotateTimer.addEventListener("timer", rotateQuote);
rotateTimer.start();

Next we're going to create a TimerObject, Timer Objects are similar to the setInterval method which you all know from Actionscript 2, setInterval is still available in Actionscript 3.0 but it's recommended by Adobe to use this new method, and I must say it's a lot more easier to use it then the setInterval.

Again we defining a variable called rotateTimer and we already passing a few attributes when initializing it, the first number "2000" is the interval in milliseconds that the function will be called, the 2nd number "100" is the amount of repetitions that the timer is going to handle. i.e. if you would like to rotate your quotes in an interval of 10 seconds and you are planning to do that 80 times, the that line would look like this:

var rotateTimer:Timer = new Timer(10000, 80);

On the next line add an eventlistener to the timer object, Event Listeners were already know in Actionscript 2.0, in Actionscript 3.0 they became very important, and it's time to start using them properly, therefore we define an Event Listener
that will call up our function named "rotateQuote" (we'll create it on a later point)

The last line starts our Timer immediately, in case you would like to switch off the rotation you would just need to write following line of code:

rotateTimer.stop();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function init():void {
	var quotesXML:XML = new XML();
	quotesXML.ignoreWhitespace = true;
	var XMLURL:URLRequest = new URLRequest("http://localhost/quoteRotator/quotes1.xml");
	var myLoader:URLLoader = new URLLoader(XMLURL);
	myLoader.addEventListener("complete", xmlLoaded);
	function xmlLoaded(event:Event):void {
                totalQuotes = quotesXML.quote.length();
		quotesXML = XML(myLoader.data);
		for (var i:int = 0; i < quotesXML.quote.length(); i++) {
			quote[i] = quotesXML.quote[i].text;
			author[i] = quotesXML.quote[i].author;
		}
	}
}

Line1:
Now this is a big block isn't it? ;)
don't worry, it's also very easy to understand, first of all we create a function called init, since it's not returning anything we define it as "void"
Line2:
Then on the second line we create a new variable called "quotesXML" assigning it as an XML Object and initialize straight away.
Line3:
with the third line we're telling our application to ignore the whitespaces in the xml which sometimes could cause heavy problems during the parsing of the data.
Line4:
Then we generate an URL Request that picks up the XML that we just created
Line5:
Then we load our XML
Line6:
We add an event listener to our loader Object which calls up the function "xmlLoaded"
Line7:
Now we store the totalamount of quotes in a variable so that we're able to grab the number for our random function further below
Line9:
When the XML is loaded we assign the data of it to the XML object created on the second line called quoteXML
Line10:
Here we create a for loop that checks the length of our XML, eg. it counts how many quotes we have in our XML file
Line11 & 12:
Finally we assign each of the nodeobjects to their responsive array, filling them up exactly the length of the XML file thanks to our for.. loop method

Remember that we created an event on the TimerObject that called up this function? This where we are going to create it

1
2
3
4
5
function rotateQuote(evt:TimerEvent) {
	var randomness:Number = randomNumber(0, 5);
	quoteMC.quote_txt.text = quote[randomness];
	authMC.author_txt.text = author[randomness];
}

Line 1:
We again create a new function that will handle the rotation of our quotes which is linked to our timer object
Line 2:
Then we create a new variable which holds a random number being generated from the randomNumber function (which again we're going to create at a later point) holding the lowest & highest possible number that can be generated.
Line 3 & 4:
Lastly we assign the values of the array by using the result of the randomfunction and display them in the appropriate text fields.

Now to our last function in this script, the randomizer.

1
2
3
4
5
function randomNumber(low:Number, high:Number):Number {
	var low:Number = low;
	var high:Number = high;
	return Math.round(Math.random() * high - low) + low;
}

Line1:
again a function holding 2 arguments that must be passed when calling the function, one being the lowest possible number and one being the highest possible number that can be randomly generated, this is pretty handy because with it you can really define which range of numbers can be generated, something which is not possible with the standard Math.Random method
Line2 & 3:
two variables holding the numbers passed from the function called
Line4:
Then we return the result of the randomization process, which is being passed to our rotateQuote function above.

With it our tutorial is partly done, test out your movie and you will see that quotes will rotate every 2 seconds.
In the next tutorial I'm showing you how to animate the movieclips with Actionscript to create a nicer effect to the rotator.

As usual you can download the source files HERE quoteRotator.zip

Leave a comment

42 Comments.

  1. Wow. This is wonderful! It might have been me asking the question on the Flash forum. There are a lot of good programmers out there; few take the time to share their code with others. Most just don’t have the time. Thank you for taking the time to write this great article with step-by-step instructions for those of us who are Flash-challenged (like me!!).

    Knowledge is like water from a fountain; let the fountain be emptied, and it will fill up again and again. Hope your fountain of knowledge will be filled again and again with great ideas :)

  2. Hi Alex

    Many thanks for your words, I really appreciate it.
    You are the people that give me the ideas on what to write, so anytime you guys have something interesting to know about, I will take a bit of time off and try to write a tutorial to help people out.

    That’s the way I’ve learned Flash, and I think I owe the community something back.

    Tiago

  3. I can only agree with Alex and couldn’t have said it better!
    I am surely looking forward to more of your very fine examples…
    Thanks Tiago ! ! !

  4. Thanks a bunch Cor, again I really appreciate all comments from you guys.
    Don’t forget to tell me what you would like to see next.

    Tiago

  5. I am wondering how to get the first quote to load right away. I seems like the first quote takes 2 seconds to load, and so on when you ad time. For example, I made it 10000, 100 and it took 10 seconds for the first quote to show up. Is there a quick fix for this that I am missing?

    Thanks
    Jason

  6. Jason
    Right after the for.. loop insert this lines.

    var initRandom:Number = randomNumber(0, totalQuotes);
    		quoteMC.quote_txt.text = String(quote[initRandom]);
    		authMC.author_txt.text = String(author[initRandom]);

    then on the rotateQuote function right at the beginning put this in:

    quoteMC.quote_txt.text = "";
    	authMC.author_txt.text = "";

    The first 4 lines creates a new random number using the last function we wrote, then it assigns the results to a textfield.

    the last 2 new lines we entered into the rotateQuote function are just deleting the content of the textfields everytime it rotates, apparently AS3 doesn’t like to overwrite textfields, you can also take this 2 lines out, they won’t affect your end product but you’ll see the compiler errors when testing on the IDE.

    Hope this helped
    Tiago

  7. Hi, Tiago. I need to build a map of North Carolina with each county being interactive, so when the user rolls over a county, the app would display some foreclosure data for that region. The user can also type a zip code in to view the data. I work for a state agency and need to build this by the end of January for a non-profit site to help folks to keep their homes. I’ve posted to the Flash forum but wondered if you’ve got a trick or two up your sleeve. Are there 3rd party components that can accomplish this task? Thanks.

  8. Alex, I’ve sent you an email

  9. Tiago,
    This is great. Thanks. I, too, am interested in the interactive map, searching with zip code, like Alex C. mentioned. I am trying to build a map that you can enter a zip code to return day care names and phone numbers from xml. I am a new dad and have learned how hard it is to find day care. Wanted to try building something as a free service for others.
    Thanks.

  10. Tiago,

    Great tutorial- you should add a donations button, really. Any idea how to add a one second opacity fade in/ fade out to the quotes as they are displayed? I was working on making 2 different containers and alternating them but it got too complicated and I’m sure there is a better way to do this.

    Thanks.

  11. Toby

    Toby, thanks for your feedback :)
    It’s actually quite easy to fade in to the quotes, and you don’t even need a fade out as the fade in is so smooth that you won’t even notice that it displays instantly :)

    1. Get this package: http://code.google.com/p/tweener/ , follow the installation instructions
    2. Go to your actions frame and type following things in, be aware of the line numbers (based on the code above)

    1
    
    import caurina.transitions.Tweener;
    6
    7
    
    quoteMC.alpha = 0;
    authMC.alpha = 0;
    27
    28
    
    Tweener.addTween(quoteMC, {alpha:1, time:5});
    Tweener.addTween(authMC, {alpha:1, time:5});
    36
    37
    38
    39
    
    	quoteMC.alpha = 0;
    	authMC.alpha = 0;
    	Tweener.addTween(quoteMC, {alpha:1, time:5});
    	Tweener.addTween(authMC, {alpha:1, time:5});

    That’s it, if you have any questions on this, let me know.

    Cheers
    Tiago

  12. OK, so it works but only for the author part of the quote- At first I thought it was because I tried to mix it with the immediate display solution(post #6) but removed that and it was still not tweening. Then I rebuilt the entire thing and still no dice. If you don’t mind taking a quick look I put my code below. I’ll figure it out in anycase :)

    import caurina.transitions.Tweener;

    var quote:Array = new Array();
    var author:Array = new Array();
    var totalQuotes:Number;

    var rotateTimer:Timer = new Timer(4000, 400);
    quoteMC.alpha = 0;
    authMC.alpha = 0;
    rotateTimer.addEventListener(“timer”, rotateQuote);
    rotateTimer.start();

    function init():void {
    var quotesXML:XML = new XML();
    quotesXML.ignoreWhitespace = true;
    var XMLURL:URLRequest = new URLRequest(“quotes1.xml”);
    var myLoader:URLLoader = new URLLoader(XMLURL);
    myLoader.addEventListener(“complete”, xmlLoaded);
    function xmlLoaded(event:Event):void {
    quotesXML = XML(myLoader.data);
    totalQuotes = quotesXML.quote.length();
    for (var i:int = 0; i < quotesXML.quote.length(); i++) {
    quote[i] = quotesXML.quote[i].text;
    author[i] = quotesXML.quote[i].author;
    }
    }
    }
    function rotateQuote(evt:TimerEvent){
    var randomness:Number = randomNumber(0, 4);
    Tweener.addTween(quoteMC, {alpha:1, time:5});
    Tweener.addTween(authMC, {alpha:1, time:5});
    quoteMC.quote_txt.text = quote[randomness];
    authMC.author_txt.text = author[randomness];
    }

    function randomNumber(low:Number, high:Number):Number {
    var low:Number = low;
    var high:Number = high;
    quoteMC.alpha = 0;
    authMC.alpha = 0;
    Tweener.addTween(quoteMC, {alpha:1, time:5});
    Tweener.addTween(authMC, {alpha:1, time:5});
    return Math.round(Math.random() * high – low) + low;

    }

    init();

  13. Tiago,

    Thanks for the great tutorial. I’m still having some trouble though. It seems that my authors aren’t being parsed correctly. An example of my quotes.xml file is below:

    "The problem to be faced is: How to combine loyalty to one's own tradition with reverence for different traditions."
    Abraham Joshua Heschel

    "Injustice anywhere is a threat to justice everywhere."
    Martin Luther King, Jr.

    "For it isn't enough for one to talk about peace. One must believe in it. And it isn't enough to believe in it. One must work at it."
    Eleanor Roosevelt

    "Peace is not the absence of conflict but the presence of creative alternatives for responding to conflict--alternatives to passive or aggressive responses, alternatives to violence."
    Dorothy Thompson

    "The hottest places in hell are reserved for those who in times of great moral crises maintain their neutrality."
    Dante

    Basically, a lot of the time, the author’s last name does not show up. However, sometimes it does…any idea why?

  14. OK, that copy/paste didn’t work out, but you imagine the XML tags in there…

  15. Ok that copy/paste didn’t work out quite right…but you can imagine where the XML tags are…

  16. okay.. I haven’t moved to as 3, and can’t because much of the rest of the site I’m building is in flashlite…. but this is the only quote rotator I can find… can it be modified?

  17. Wow, you are fantastic!! Thank you so so much.

  18. How can I get them to fade in? :(

  19. Oh, nevermind….

    ..but how do I get them to fade out? :(

  20. Hi Tiago,

    Thanks a TON for this. Exactly what I needed to jump-start my brain back into Flash development.

    I cannot, however, for the life of me get the fade-in/fade-out to work.

    I am not sure if the line numbers in that bit correspond to the original file, or the file after the modification you gave to Jason for bringing the first quote up immediately. Also, in the fade-in bit, does line 6 in the second code bit correspond to the original file’s line 6 or line 6 AFTER adding the code in line 1, which would be line 7 in the new code…

    Don’t mean to be obtuse, but I can’t get it and have tried all of the permutation I can think of. I am also not very familiar with how Tweener works, and rather than delving into the details of it, I was hoping you could shed some light.

    Thanks!

    Chris

  21. Has anyone gotten the Tweener code to work? I cannot get it to work at all… I step through it and it all looks great, but the text just shifts directly from one quote to the next without any fade.

    Here is my code. If someone is willing to comment on it, I sure would appreciate it!


    import caurina.transitions.Tweener;

    var quote:Array = new Array();
    var author:Array = new Array();
    var totalQuotes:Number;
    var rotateTimer:Timer = new Timer(5000, 0);

    quoteMC.alpha = 0;
    authMC.alpha = 0;

    rotateTimer.addEventListener("timer", rotateQuote);
    rotateTimer.start();

    function init():void {
    var quotesXML:XML = new XML();
    quotesXML.ignoreWhitespace = true;
    var XMLURL:URLRequest = new URLRequest("http://localhost/blogs/QuoteRotator/QuoteBase.xml");
    var myLoader:URLLoader = new URLLoader(XMLURL);
    myLoader.addEventListener("complete", xmlLoaded);
    function xmlLoaded(event:Event):void {
    quotesXML = XML(myLoader.data);
    totalQuotes = quotesXML.quote.length();
    for (var i:int = 0; i < quotesXML.quote.length(); i++) {
    quote[i] = "\"" + quotesXML.quote[i].text + "\"";
    author[i] = "- " + quotesXML.quote[i].author;
    }

    var initRandom:Number = randomNumber(0, totalQuotes);
    quoteMC.quote_txt.text = String(quote[initRandom]);
    authMC.author_txt.text = String(author[initRandom]);
    }

    Tweener.addTween(quoteMC, {alpha:1, time:2, transition:"easeInSine"});
    Tweener.addTween(authMC, {alpha:1, time:2, transition:"easeInSine"});
    }

    function rotateQuote(evt:TimerEvent) {
    // quoteMC.quote_txt.text = "";
    // authMC.author_txt.text = "";

    quoteMC.alpha = 0;
    authMC.alpha = 0;

    var randomness:Number = randomNumber(0, totalQuotes - 1);
    quoteMC.quote_txt.text = quote[randomness];
    authMC.author_txt.text = author[randomness];

    Tweener.addTween(quoteMC, {alpha:1, time:2, transition:"easeInSine"});
    Tweener.addTween(authMC, {alpha:1, time:2, transition:"easeInSine"});
    }

    function randomNumber(low:Number, high:Number):Number {
    var low:Number = low;
    var high:Number = high;
    return Math.round(Math.random() * high - low) + low;
    }

    init();

    Cheers,

    Chris

  22. Hey Chris

    Sorry for the delay replying to your comment, below the link for you to download the .fla with the tweener code inside.
    http://blog.six4rty.ch/downloads/quoteRotator_source.zip

    let me know if you still encounter any problems.

    Cheers
    Tiago

  23. Hi Tiago,

    Thanks for the code. Yours works, and mine doesn’t on my machine. I have modified my so much that it is hard to compare, but I don’t see anything different from yours compared to what I remember mine looking like when I first did it and couldn’t get it to work.

    I think I will just use yours as a baseline and begin adding my mods and see where it breaks.

    I do, however, have a gauntlet to throw down before you. :) Using AS3 and this little quote rotator, the quotes and authors are of different lengths. Being constrained by width, that means that the text in each control needs to resize vertically for each quote/author pair. I need to make both controls bottom-aligned and resize correctly.

    What I need to do is this. The Author is the bottom-most control, and the Quote sits atop it. The bottom coordinate for the author box is the height of the stage (in this case 150), and that will never change. When the text is loaded into it, I need to calculate the height, set the height of the textbox and then set the “y” value to 150 – textHeight. Sound right?

    Next, the quote. The bottom coordinate of the quote textbox should be the same as the “y” value of the author textbox. So, I need to get the height of the quote text, set the height of the textbox, and then set the “y” value to yValOfAuthor – quoteTextHeight. Make sense?

    Problem is, when I resize the textbox, the movie clip wrapping it moves on the stage. So I thought I would set the height and y values of the movie clips wrapping the textboxes, but when I do that the actual text size changes… This seems like it might be overly complicated, which makes me think I am doing something wrong.

    Do you have any code socked away that does this, or can you help me figure this thing out? I would be forever grateful and would leave you an ENORMOUS “thank you” on my site.

    Cheers,

    Chris

  24. Hey there,

    Ok, here is some interesting stuff… if you are interested, that is!

    I dropped your code into my FLA, and it did NOT work. After mucking around and creating a whole new FLA and testing again, I tried dropping your text boxes onto my stage, and suddenly everything worked as expected.

    Did you do anything special when you created your text boxes?

    I literally just drew the text box with the text tool. Set it to be Dynamic Text, and that was it. I did notice yours are bold and are set to Anti-alias for animation (mine were set to anti-alias for readability), but changing both of those did nothing in my testing.

    Another interesting thing is that in trying to bottom-align things, the movie clip wrapper was screwing things up when the box was resized (or if I resized the movie clip the font would get all wonky). So I tried it without the MCs and viola! Tweener works just fine on animating the alpha channel of a text box. Makes the code a bit easier, and the manipulation of the widgets much simpler.

    Thanks!

    Chris

  25. Tiago,

    thank you so much for this, I’ve got it working and have learnt some new things too!

    I just have one question – there is a long pause at the beginning with a blank screen before the rotation actually starts, is there anyway to remove the pause – or have some kind of placeholder image there while it loads.

    I think someone (jason) asked this question above , but I could not get the solution you gave to work.

    Any ideas?

    Thanks Again.

  26. Excelent job and thanks for sharing your work Tiago. I’m using it and works fine however I’m getting an error:

    TypeError: Error #2007: Parameter text must be non-null.
    at flash.text::TextField/set text()
    at quotes_fla::MainTimeline/rotateQuote()
    at flash.utils::Timer/flash.utils:Timer::_timerDispatch()
    at flash.utils::Timer/flash.utils:Timer::tick()

    The code I’m using is:

    import caurina.transitions.Tweener;

    var quote:Array = new Array();
    var author:Array = new Array();
    var totalQuotes:Number;
    quoteMC.alpha = 0;

    var rotateTimer:Timer = new Timer(5000, 100);//rotates the quote every 2 seconds for 100 times
    rotateTimer.addEventListener(“timer”, rotateQuote);//add a listener to the timer
    rotateTimer.start();// start the timer

    function init():void {
    var quotesXML:XML = new XML();
    quotesXML.ignoreWhitespace = true;
    var XMLURL:URLRequest = new URLRequest(“flash/quotes1.xml”);
    var myLoader:URLLoader = new URLLoader(XMLURL);
    myLoader.addEventListener(“complete”, xmlLoaded);
    function xmlLoaded(event:Event):void {
    quotesXML = XML(myLoader.data);
    totalQuotes = quotesXML.quote.length();
    for (var i:int = 0; i < quotesXML.quote.length(); i++) {
    quote[i] = quotesXML.quote[i].text;
    }
    var initRandom:Number = randomNumber(0, totalQuotes);
    Tweener.addTween(quoteMC, {alpha:1, time:5});
    quoteMC.quote_txt.text = String(quote[initRandom]);
    }

    }

    function rotateQuote(evt:TimerEvent) {
    quoteMC.alpha = 0;
    Tweener.addTween(quoteMC, {alpha:1, time:5});
    quoteMC.quote_txt.text = “”;
    var randomness:Number = randomNumber(0, totalQuotes);
    quoteMC.quote_txt.text = quote[randomness];
    }

    function randomNumber(low:Number, high:Number):Number {
    var low:Number = low;
    var high:Number = high;
    return Math.round(Math.random() * high – low) + low;
    }
    init();

    I’m totally new at as3 so any help will be welcome.
    Thanks in advance.

  27. Excelent job and thanks for sharing your work Tiago. I’m using it and works fine however I’m getting an error:

    TypeError: Error #2007: Parameter text must be non-null.
    at flash.text::TextField/set text()
    at quotes_fla::MainTimeline/rotateQuote()
    at flash.utils::Timer/flash.utils:Timer::_timerDispatch()
    at flash.utils::Timer/flash.utils:Timer::tick()

    The code I’m using is:

    import caurina.transitions.Tweener;

    var quote:Array = new Array();
    var totalQuotes:Number;
    quoteMC.alpha = 0;

    var rotateTimer:Timer = new Timer(5000, 100);//rotates the quote every 2 seconds for 100 times
    rotateTimer.addEventListener(“timer”, rotateQuote);//add a listener to the timer
    rotateTimer.start();// start the timer

    function init():void {
    var quotesXML:XML = new XML();
    quotesXML.ignoreWhitespace = true;
    var XMLURL:URLRequest = new URLRequest(“flash/quotes1.xml”);
    var myLoader:URLLoader = new URLLoader(XMLURL);
    myLoader.addEventListener(“complete”, xmlLoaded);
    function xmlLoaded(event:Event):void {
    quotesXML = XML(myLoader.data);
    totalQuotes = quotesXML.quote.length();
    for (var i:int = 0; i < quotesXML.quote.length(); i++) {
    quote[i] = quotesXML.quote[i].text;
    }
    var initRandom:Number = randomNumber(0, totalQuotes);
    Tweener.addTween(quoteMC, {alpha:1, time:5});
    quoteMC.quote_txt.text = String(quote[initRandom]);
    }

    }

    function rotateQuote(evt:TimerEvent) {
    quoteMC.alpha = 0;
    Tweener.addTween(quoteMC, {alpha:1, time:5});
    quoteMC.quote_txt.text = “”;
    var randomness:Number = randomNumber(0, totalQuotes);
    quoteMC.quote_txt.text = quote[randomness];
    }

    function randomNumber(low:Number, high:Number):Number {
    var low:Number = low;
    var high:Number = high;
    return Math.round(Math.random() * high – low) + low;
    }
    init();

    I’m totally new at as3 so any help will be welcome.
    Thanks in advance.

  28. Hi there is there a way I can make a Flash SWF to add quotes to the XML? so People can add quotes by themselves?

  29. Is there a way to do this but in AS2??

  30. I was having the same error #2007. It’s caused by this line:

    var XMLURL:URLRequest = new URLRequest(“http://localhost/quoteRotator/quotes1.xml”);

    You need to change that to the localhost folder where the app is running. However, after fixing that, the first quote comes up as “undefined” and then it works ok. What’s causing this?

  31. If you get error #2007, i think the problem is

    totalQuotes = quotesXML.quote.length();

    needs to be changed too

    totalQuotes = quotesXML.quote.length() – 1;

    You get the #2007 because the original code is reaching out of the array bounds.

  32. Since this is open forum, I felt like I should share my code. In no way I’m a flash programmer, maybe get a half dozen projects a year. And hack most of the code together. So be nice!

    Modifications: Added no duplicate rotation, so no one quote is shown twice in a row. Added Fade in and fade out based on Toby’s code. I also added a system to move the author up or down depending if it was using multiple lines or not (the size will very depending on you’re dimensions). With my last message also fixed that annoying #2007 error.

    CODE:

    import caurina.transitions.Tweener;

    var quote:Array = new Array();
    var author:Array = new Array();
    var lastQuote:Number = 0;

    var totalQuotes:Number;
    quoteMC.alpha = 0;
    authMC.alpha = 0;

    var rotateTimer:Timer = new Timer(7000, 100000); //rotates the quote every 2 seconds for 100000 times
    rotateTimer.addEventListener(“timer”, rotateQuote);//add a listener to the timer
    rotateTimer.start();// start the timer

    function init():void {
    var quotesXML:XML = new XML();
    quotesXML.ignoreWhitespace = true;
    var XMLURL:URLRequest = new URLRequest(“http://localhost/quotes1.xml”);
    var myLoader:URLLoader = new URLLoader(XMLURL);
    myLoader.addEventListener(“complete”, xmlLoaded);
    function xmlLoaded(event:Event):void {
    quotesXML = XML(myLoader.data);
    totalQuotes = quotesXML.quote.length() – 1;
    for (var i:int = 0; i < quotesXML.quote.length(); i++) {
    quote[i] = quotesXML.quote[i].text;
    author[i] = quotesXML.quote[i].author;
    }
    var initRandom:Number = randomNumber(0, totalQuotes);
    lastQuote = initRandom;

    var temp:String = quote[initRandom];
    if (temp.length < 60) {
    authMC.y = 50;
    } else {
    authMC.y = 72;
    }

    Tweener.addTween(quoteMC, {alpha:1, time:5});
    Tweener.addTween(authMC, {alpha:1, time:5});
    quoteMC.quote_txt.text = String(quote[initRandom]);
    authMC.author_txt.text = String(author[initRandom]);
    }

    }

    function wait(evt:TimerEvent)
    {
    stop();
    var myInterval = setInterval( function () {
    play();
    clearInterval(myInterval);
    rotateQuoteIN(evt);
    }, 2000);
    }

    function rotateQuote(evt:TimerEvent) {
    Tweener.addTween(quoteMC, {alpha:0, time:3});
    Tweener.addTween(authMC, {alpha:0, time:3});
    wait(evt);
    }

    function rotateQuoteIN(evt:TimerEvent) {
    quoteMC.alpha = 0;
    authMC.alpha = 0;
    Tweener.addTween(quoteMC, {alpha:1, time:6});
    Tweener.addTween(authMC, {alpha:1, time:6});
    quoteMC.quote_txt.text = “”;
    authMC.author_txt.text = “”;
    var randomness:Number = randomNumber(0, totalQuotes);

    /* prevent the same quote from showing */
    while ( lastQuote == randomness) {
    randomness = randomNumber(0, totalQuotes);
    }

    lastQuote = randomness;

    var temp:String = quote[randomness];
    if (temp.length < 60) {
    authMC.y = 50;
    } else {
    authMC.y = 72;
    }

    quoteMC.quote_txt.text = quote[randomness];
    authMC.author_txt.text = author[randomness];

    }

    function randomNumber(low:Number, high:Number):Number {
    var low:Number = low;
    var high:Number = high;
    return Math.round(Math.random() * high – low) + low;
    }
    init();

  33. Hey I’m trying to put the script in a class (the one with the Tweener Class). But I cant get it to work. I imported to necessary classes:
    =================
    import flash.events.*;
    import flash.xml.*;
    import flash.utils.*;
    import flash.net.*;
    import caurina.transitions.Tweener;
    =================
    But now I get these errors:
    =================
    - 1119: Access of possibly undefined property alpha through a reference with static type Class. || QuoteMC.alpha = 0;

    - 1119: Access of possibly undefined property alpha through a reference with static type Class. || AuthorMC.alpha = 0;

    - 1120: Access of undefined property rotateTimer. || rotateTimer.addEventListener(“timer”, rotateQuote);//add a listener to the timer

    - 1120: Access of undefined property rotateQuote. || rotateTimer.addEventListener(“timer”, rotateQuote);//add a listener to the timer

    - 1120: Access of undefined property rotateTimer. || rotateTimer.start();// start the timer

    - 1180: Call to a possibly undefined method init. || init();

    - 1119: Access of possibly undefined property quote_txt through a reference with static type Class. || QuoteMC.quote_txt.text = String(quote[initRandom]);

    - 1119: Access of possibly undefined property author_txt through a reference with static type Class. || AuthorMC.author_txt.text = String(author[initRandom]);

    - 1119: Access of possibly undefined property alpha through a reference with static type Class. || QuoteMC.alpha = 0;

    - 1119: Access of possibly undefined property alpha through a reference with static type Class. || AuthorMC.alpha = 0;

    - 1119: Access of possibly undefined property quote_txt through a reference with static type Class. || QuoteMC.quote_txt.text = “”;

    - 1119: Access of possibly undefined property author_txt through a reference with static type Class. || AuthorMC.author_txt.text = “”;

    - 1119: Access of possibly undefined property quote_txt through a reference with static type Class. || QuoteMC.quote_txt.text = quote[randomness];

    - 1119: Access of possibly undefined property author_txt through a reference with static type Class. || AuthorMC.author_txt.text = author[randomness];
    =================
    Now I’m adding the text field Dynamically in another class containing:
    =================
    public var quote:QuoteMC = new QuoteMC();
    public var quotegen:Quotes = new Quotes();

    auteur.x = 659;
    auteur.y = 282;
    addChild(auteur);

    quote.x = 2;
    quote.y = 282;
    addChild(quote);
    =================

    Can someone please help me out with the classes.
    I think the common problem is that I don’t give the created MC’s the instance names needed (quote_txt & author_txt). The other problems I can’t seem to figure out. If anyone knows the answer please post a reply on my blog here: http://blog.libertystudio.nl/2009/02/23/quote-rotator-using-classes/ or email me.

    Thanks in advance :)

  34. Solved my problem.
    instead of adding the the movieclip containing the text field I dynamically generated a text field.

  35. I think more people have this problem but I can’t seen to get a proper fix for it:

    TypeError: Error #2007: Parameter text must be non-null.
    at flash.text::TextField/set text()
    at quoteRotator_fla::MainTimeline/rotateQuote()
    at flash.utils::Timer/flash.utils:Timer::_timerDispatch()
    at flash.utils::Timer/flash.utils:Timer::tick()

    It’s because sometimes it tries to place the text before it loaded the XML.

  36. Hi there – thanks for sharing!!! It really helps us noobs learn.
    Wondering if you might be able to walk through making this index the xml tree in order rather than random? Im trying everything but just bungle it everytime ; )

    thx in advance

  37. This is great, but I’m curious how you remove the random rotation and make it cycle in the order of the XML?


  38. stop();
    import caurina.transitions.Tweener;
    import flash.display.*;

    var quote:Array = new Array();
    var author:Array = new Array();
    var lastQuote:Number = 0;

    var totalQuotes:Number;
    quoteMC.alpha = 0;
    authMC.alpha = 0;

    var rotateTimer:Timer = new Timer(5000, 100000); //rotates the quote every 2 seconds for 100000 times
    rotateTimer.addEventListener("timer", rotateQuote);//add a listener to the timer
    rotateTimer.start();// start the timer

    function init():void {
    var quotesXML:XML = new XML();
    quotesXML.ignoreWhitespace = true;
    var XMLURL:URLRequest = new URLRequest("quotes1.xml");
    var myLoader:URLLoader = new URLLoader(XMLURL);
    myLoader.addEventListener("complete", xmlLoaded);

    function xmlLoaded(event:Event):void {
    quotesXML = XML(myLoader.data);
    totalQuotes = quotesXML.quote.length()-1;
    for (var i:int = 0; i < quotesXML.quote.length(); i++) {
    quote[i] = quotesXML.quote[i].text;
    author[i] = quotesXML.quote[i].author;
    }

    var initRandom:Number = randomNumber(0, totalQuotes);
    lastQuote = initRandom;

    var temp:String = quote[initRandom];
    if (temp.length < 60) {
    authMC.y = 50;
    } else {
    authMC.y = 72;
    }

    Tweener.addTween(quoteMC, {alpha:1, time:5});
    Tweener.addTween(authMC, {alpha:1, time:5});
    quoteMC.quote_txt.text = String(quote[initRandom]);
    authMC.author_txt.text = String(author[initRandom]);
    }
    }

    function wait(evt:TimerEvent) {
    stop();
    var myInterval = setInterval(function () {
    play();
    clearInterval(myInterval);
    rotateQuoteIN(evt);
    }, 2000);
    }

    function rotateQuote(evt:TimerEvent) {
    Tweener.addTween(quoteMC, {alpha:0, time:3});
    Tweener.addTween(authMC, {alpha:0, time:3});
    //quoteMC.quote_txt.text = "";
    //authMC.author_txt.text = "";
    wait(evt);
    }

    function rotateQuoteIN(evt:TimerEvent) {
    quoteMC.alpha = 0;
    authMC.alpha = 0;
    Tweener.addTween(quoteMC, {alpha:1, time:6});
    Tweener.addTween(authMC, {alpha:1, time:6});
    //quoteMC.quote_txt.text = "";
    authMC.author_txt.text = "";
    var randomness:Number = randomNumber(0, totalQuotes);
    /* prevent the same quote from showing */
    while ( lastQuote == randomness) {
    randomness = randomNumber(0, totalQuotes);
    }

    lastQuote = randomness;

    var temp:String = quote[randomness];
    if (temp.length < 60) {
    authMC.y = 50;
    } else {
    authMC.y = 72;
    }

    quoteMC.quote_txt.text = quote[randomness];
    authMC.author_txt.text = author[randomness];

    }

    function randomNumber(low:Number, high:Number):Number {
    var low:Number = low;
    var high:Number = high;
    quoteMC.alpha = 0;
    authMC.alpha = 0;
    Tweener.addTween(quoteMC, {alpha:1, time:5});
    Tweener.addTween(authMC, {alpha:1, time:5});
    return Math.round(Math.random() * high - low) + low;
    }

    init();


  39. stop();
    import caurina.transitions.Tweener;
    import flash.display.*;

    var quote:Array = new Array();
    var author:Array = new Array();
    var lastQuote:Number = 0;

    var totalQuotes:Number;
    quoteMC.alpha = 0;
    authMC.alpha = 0;

    var rotateTimer:Timer = new Timer(5000, 100000); //rotates the quote every 2 seconds for 100000 times
    rotateTimer.addEventListener(“timer”, rotateQuote);//add a listener to the timer
    rotateTimer.start();// start the timer

    function init():void {
    var quotesXML:XML = new XML();
    quotesXML.ignoreWhitespace = true;
    var XMLURL:URLRequest = new URLRequest(“quotes1.xml”);
    var myLoader:URLLoader = new URLLoader(XMLURL);
    myLoader.addEventListener(“complete”, xmlLoaded);

    function xmlLoaded(event:Event):void {
    quotesXML = XML(myLoader.data);
    totalQuotes = quotesXML.quote.length()-1;
    for (var i:int = 0; i < quotesXML.quote.length(); i++) {
    quote[i] = quotesXML.quote[i].text;
    author[i] = quotesXML.quote[i].author;
    }

    var initRandom:Number = randomNumber(0, totalQuotes);
    lastQuote = initRandom;

    var temp:String = quote[initRandom];
    if (temp.length < 60) {
    authMC.y = 50;
    } else {
    authMC.y = 72;
    }

    Tweener.addTween(quoteMC, {alpha:1, time:5});
    Tweener.addTween(authMC, {alpha:1, time:5});
    quoteMC.quote_txt.text = String(quote[initRandom]);
    authMC.author_txt.text = String(author[initRandom]);
    }
    }

    function wait(evt:TimerEvent) {
    stop();
    var myInterval = setInterval(function () {
    play();
    clearInterval(myInterval);
    rotateQuoteIN(evt);
    }, 2000);
    }

    function rotateQuote(evt:TimerEvent) {
    Tweener.addTween(quoteMC, {alpha:0, time:3});
    Tweener.addTween(authMC, {alpha:0, time:3});
    //quoteMC.quote_txt.text = "";
    //authMC.author_txt.text = "";
    wait(evt);
    }

    function rotateQuoteIN(evt:TimerEvent) {
    quoteMC.alpha = 0;
    authMC.alpha = 0;
    Tweener.addTween(quoteMC, {alpha:1, time:6});
    Tweener.addTween(authMC, {alpha:1, time:6});
    //quoteMC.quote_txt.text = "";
    authMC.author_txt.text = "";
    var randomness:Number = randomNumber(0, totalQuotes);
    /* prevent the same quote from showing */
    while ( lastQuote == randomness) {
    randomness = randomNumber(0, totalQuotes);
    }

    lastQuote = randomness;

    var temp:String = quote[randomness];
    if (temp.length < 60) {
    authMC.y = 50;
    } else {
    authMC.y = 72;
    }

    quoteMC.quote_txt.text = quote[randomness];
    authMC.author_txt.text = author[randomness];

    }

    function randomNumber(low:Number, high:Number):Number {
    var low:Number = low;
    var high:Number = high;
    quoteMC.alpha = 0;
    authMC.alpha = 0;
    Tweener.addTween(quoteMC, {alpha:1, time:5});
    Tweener.addTween(authMC, {alpha:1, time:5});
    return Math.round(Math.random() * high – low) + low;
    }

    init();

  40. Just corrected a few things … working like a beaty :-)

  41. Hi Tiago.
    I am fairly new to actionscript and I am trying to use this quote rotator, however I keep gettin an error:
    TypeError: Error #1010: A term is undefined and has no properties.
    at quote_rotator_fla::MainTimeline/rotateQuote()
    at flash.utils::Timer/flash.utils:Timer::_timerDispatch()
    at flash.utils::Timer/flash.utils:Timer::tick()
    TypeError: Error #1010: A term is undefined and has no properties.
    at quote_rotator_fla::MainTimeline/rotateQuote()
    at flash.utils::Timer/flash.utils:Timer::_timerDispatch()
    at flash.utils::Timer/flash.utils:Timer::tick()

    I really need this to work as I am trying to create something similar for a website that I am currently working on, but I need to do it by wednesday haha. Is there any way you could help please?

    Thank you

Leave a Reply

Your email address will not be published.


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">