This is an archived tutorial from the kirupa.com legacy collection. It covers software that may no longer be available, but it is kept online because the ideas still hold up.
Flash is really great for quickly displaying content from an external data source. One area where that would be useful is with news tickers. Instead of having to recompile your FLA and upload a new version of your SWF each time something new happens, you could just update the external data source using a simple text editor instead!
News tickers seemed to be all the rave back in the day along with those loveable scrolling marquees. It's time that we did our part and help bring them back. This tutorial will help explain how to create a news ticker similar to what you see below:
[ what you will create by the end of this tutorial ]
Play around with the ticker and notice that there is a brief transition between each news item, each news item is underlined when you hover over it with your mouse, and when clicked, each item loads the appropriate URL. The data for the ticker is taken from this file: http://www.kirupa.com/developer/.../swf/news.xml.
Let's get started with creating the ticker:

[ adjust your movie's properties ]

[ select dynamic text ]

[ draw your text field ]

[ the text properties I used for the above example animation ]

[ embed the first four ranges from the Character Options window ]

[ give our movie clip the instance name 'newsMC' ]
In the next section, I will explain the structure of the XML file and start explaining the code that is used.
In the previous section, we created the interface and got a working example. In this and the following sections, I will explain some of the background details that you will need to know in order to create your own, better News Ticker!
Let's take a look at our XML file now. Here is how our XML file looks like:
The structure of our XML file is fairly straightforward. Here is a simpler format that highlights the basic layout of our data:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<images>
<item>
<news>Eat
more Spam</news>
<url>http://www.kirupa.com</url>
</item>
<item>
<news>FXPression
05 Contest</news>
<url>http://www.kirupa.com/forum/</url>
</item>
<item>
<news>Check
out our Footer Contest #2</news>
<url>http://www.kirupa.com/tutorials/</url>
</item>
</images>
Each item node contains two children: news and url. Simply create new copies of the item node with the children and modify the news and url childrendata accordingly. You can take a look at my XML file here: http://www.kirupa.com/developer/mx2004/swf/news.xml
With the XML file out of the way, let's move on to the ActionScript code. Hopefully, by me explaining the code behind it, you will be better prepared to make modifications and make my generic news ticker much cooler!
Let's start:
The above section of code is fairly generic for cycling through your XML file and loading the pieces of data into an array. The two variables I used are caption and url for storing the data on our site.
In short, I load all of the URL data into the url array, and I load all of our news titles into our caption array. The thing to notice is the index position added after childNodes: 0 and 1.
I won't go into any greater detail, for I cover the concepts hidden in the code in greater detail in my explanation of the XML PhotoGallery tutorial: http://www.kirupa.com/developer/mx2004/xml_flash_photogallery5.htm
The only main variation besides the varied
variable names is that I call the function
first_item()
after all of the data from the XML file has been loaded.
xmlData = new XML();
xmlData.ignoreWhite = true;
xmlData.onLoad = loadXML;
These three lines are covered in detail here: http://www.kirupa.com/developer/mx2004/xml_flash_photogallery4.htm I am not trying to short-change you by not covering the material here, but I don't want to be repetitive when the same material has been covered in detail in that page.
xmlData.load("http://www.kirupa.com/developer/
mx2004/swf/news.xml?blarg="+new Date().getTime());
This is the line of code that specifies the URL of the XML file I am loading. If you recall, even in the code you pasted, I did not refer to an XML file stored locally. The reason is due to caching. The browser does not cache external files that are loaded from the hard drive (or another local location), but it does cache external files that are loaded from a remote location such as a web server.
Caching is great for animations that stay
constant, but for data that is constantly updated such as our
news ticker's XML file, you need to find a way to prevent
caching. That is done by using a
unique identifier that varies each time the user
accesses the animation:
blarg="+new
Date().getTime());
The unique identifier does not prevent your file from being cached, but it does prevent the cached file from being loaded when the animation is accessed again. Each time you load the XML file, the identifier produces a varied string based on the data and time in our case.
For example, your browser interprets
news.xml?blarg=blkajdf
as being different from
news.xml?blarg=352ld even if the content of the XML file
is not varied. I know it is weird, but I don't write the rules
![]()
More coding up ahead, so onwards to the next section!
The remaining pieces of code are responsible for displaying and cycling through all of our text. I have divided each major responsibility into functions. There is a first_item() function that sets up the initial variables, a timer() function that keeps track of the time before proceeding to the next image, a display() function that displays the news text, and finally a fadeout() function that fades the text out before displaying the next news item.
Let's start from the top:
function first_item() {
delay = 3000;
p = 0;
display(p);
p++;
}
This is the first function that is called, and if you recall, it is called by our loadXML function itself. I initialize two variables: delay and p. Delay stores the time your news item is displayed in milliseconds. The variable p is a counter that keeps track of which news item is being displayed. Since this is our first image, p is set to 0.
Within this function, I make a call to the display function
with the value of p. Immediately after making that call,
I increment the value of p by one (p++),
because essentially, we have already loaded the first image by
calling our display function, so it's time to dance over to the
next image.
myInterval = setInterval(ticker, delay);
In this line, I initialize a new variable that stores our setInterval function. The setInterval function, in our case, takes in only two arguments: a function name (ticker) and the time (delay) at which to call that function. The way setInterval works is that it calls the ticker function after a delay of delay seconds.
function ticker() {
clearInterval(myInterval);
if (p == total) {
p = 0;
}
fadeout();
}
This is the ticker function that is called by our setInterval. I immediately, make a call to clearInterval function and delete our initial setInterval call represented by the variable myInterval. The reason I do this is because I don't want the timer to automatically make a call to ticker() every x seconds as defined by delay.
I am content with simply calling the ticker() function once after the delay, and if I need to call the ticker() function again, I'll explicitly make another call to the timer() function. In most cases you would not do that, for the advantage of setInterval is that it makes a call to the function you specify indefinitely every few seconds. I am interested in having the delay before calling the ticker function for the first time only.
if (p == total) {
p = 0;
}
fadeout();
If our counter variable, p, reaches the value of total, the total number of data stored in our XML file, that means that we have reached the end of our XML file. There is nowhere to go but back to the front. I do that by setting the value of p back to zero.
Finally, I make a call to the fadeout() function to, literally, fade out what is currently displayed in our text field. You should note that the fadeout() function is called each time the ticker() function is called. It isn't a part of the if statement at all.
function display(pos) {
I define a function called display, and it takes in one argument in the guise of a position variable called pos. The value of pos will always be the value of p that is passed into it by the calling function.
over = new TextFormat();
over.underline = true;
//
out = new TextFormat();
out.underline = false;
In order to make stylistic changes such as underlining our text during rollOver, you will need to use the TextFormat() class. I initialize both the over and out variables the properties of the TextFormat class in order to just that.
over = new TextFormat();
over.underline = true;
//
out = new TextFormat();
out.underline = false;
Because both the over and out variables have inherited the properties of the TextFormat() class, I can simply combine those variables with the underline property to specify which style I am interested in. In the case for our over scenario, I would like there to be an underline - hence the use of true. When the user rolls out from the text field, we no longer want an underline. So, the opposite is true for our out case, and the underline is set to false.
newsMC.newsText._alpha = 100;
newsMC.newsText.text = caption[pos];
In the first line, I set the transparency of our text field, newsText to be fully opaque. The fading in of text is done by varying the alpha property of the newsText text field, so in other words, in order to make sure that the text is fully visible initially, I remove all transparency by setting alpha to 100.
In the second line I access the text that has already been
loaded into caption array. Since pos is equivalent
to the value of p - the counter,
it acts as the index position for retrieving the appropriate
text from our caption array: caption[pos].
|
|
Note |
|
In order to be able to
adjust the alpha of text in a Dynamic or
Input text field, you need to make sure to
embed the fonts for that text field. If you
recall, we already did that in our previous section.
If you fail to embed your fonts, your text will simply ignore any alpha property changes. Even if you set the alpha for your text field to a really low number, your text field will still be fully visible. Moral of this action-packed story? Embed your fonts if you are planning on adjusting the alpha! |
|
newsMC.onRelease = function() {
getURL(url[pos], "_self");
};
In this line and subsequent lines, I define the various mouse events that cause your news ticker to be more than something that looks pretty. First, let's tackle the onRelease case that loads a URL when you click on the news caption.
I apply the action to our movie clip newsMC, and I use the getURL function with the url and window target as the two arguments. The URL data is stored in our url array, and I access it using a number representing the index position of our data in our array That number is represented by, again, the variable pos.
newsMC.onRollOver = function() {
this.newsText.setTextFormat(over);
};
newsMC.onRollOut = function() {
this.newsText.setTextFormat(out);
};
timer();
These lines of code are fairly straightforward. I simply apply the over text formatting as defined earlier when someone hovers over the link. Likewise, I apply the out text formatting when someone hovers out of the link. If you recall, over and out determine whether the text is underlined or not.
The last thing this function does is call the timer() function to restart the setInterval that I cleared earlier.
Only one more page to go, so let's go to the next section!
This is page 4 of the tutorial, so if you are visiting here from a search engine without having completed the previous section, click here.
Our fadeout function is responsible for fading out our news text. Let's take a look at how it is done!
this.onEnterFrame = function() {
if (newsMC.newsText._alpha>=0) {
newsMC.newsText._alpha -= 5;
} else {
display();
p++;
delete this.onEnterFrame;
}
};
I place everything in an onEnterFrame function because I want whatever I place to repeat smoothly for a period of time. The easiest way to do that, would be to use an onEnterFrame function that executes code with a speed proportional to your frame rate.
if (newsMC.newsText._alpha>=0) {
newsMC.newsText._alpha -= 5;
} else {
display();
p++;
delete this.onEnterFrame;
}
In the first part of the if statement, I check to see if the alpha of our text is greater than 0. Since we are interested in fading out our text, ultimately we would want our text to be invisible with an alpha of at least 0 at the end.
So, if our text is still visible with an alpha greater than zero, I decrease the alpha by 5:
newsMC.newsText._alpha -= 5;
Since this code is in an onEnterFrame, the text field will gradually decrease its alpha by 5 until the alpha of the text field becomes less than or equal to zero. When that happens, it's time to look at our else case!
display(p);
p++;
delete this.onEnterFrame;
First, I call our display function to display the next caption in the series. At this point, the previous news caption should have faded out completely, so it makes sense to display the next item now.
I increment the value of the counter variable p to inform Flash that I want to proceed to the next image when the display function is called again.
Finally, I delete the onEnterFrame statement. After displaying the new news item and incrementing the value of p, there is no need to waste CPU cycles by keeping our onEnterFrame to run through code that no longer needs to be run. The delete command allows you to delete the onEnterFrame function we declared earlier easily.
You are now done with this tutorial and the explanation for it. The main idea I hope you get out of this tutorial is how to divide important responsibilities of your code to different functions. Breaking your code into various functions makes it easier to troubleshoot, or more importantly, to extend your animation without having to extensively modify the ticker's core functionality.
I have provided the source file for you to see my version of the exact same tutorial.
|
|
Just a final word before we wrap up. What you've seen here is freshly baked content without added preservatives, artificial intelligence, ads, and algorithm-driven doodads. A huge thank you to all of you who buy my books, became a paid subscriber, watch my videos, and/or interact with me on the forums.
Your support keeps this site going! 😇

:: Copyright KIRUPA 2026 //--