Content updates in Flash can be difficult and time consuming due to the many steps involved. Simply reading content from an XML file means that importing new assets and recompiling the swf is no longer necessary. This tutorial will cover dynamically loading images from an XML file and then deal with inconsistencies in image dimensions using the GreenSock Tween Max animation library.
Final Result Preview
Let's take a look at a screenshot of the final slideshow we will be working towards:

Background
Interface images and examples are provided using Flash CS4 and Actionscript 2 but other versions of Flash as far back as version 8 should be able to follow along without problems. This tutorial assumes at least a working knowledge of Actionscript since I'm not going to explain every line, however even if you simply copy and paste you should be able to get this to work.
Step 1 – Create a Project Folder
With a project of this type it's important to keep everything organized so that Flash can find things as it needs them. So create a project folder on your computer where you can place ALL the files related to this project.
Step 2 – Prep the Assets
Find images for your slideshow. I used several images from http://www.sxc.hu (sxc_hu_410471_5588.jpg, sxc_hu_1151936_79441078.jpg, sxc_hu_1152040_85122875.jpg, sxc_hu_1154131_54136948.jpg).
Create an “assets” folder inside your project folder. Open up your favorite image editor and resize your photos so they're all a similar size. I resized my images so that the longest side (height or width) is 700px and allowed the image editing software to maintain the image proportion.
Since external assets don't benefit from a Flash preloader this would be an excellent time to optimize your images for speedy downloads. Flash can load png, jpeg, or gif files so make sure your final images are in one of those formats and save them into the assets folder you just created.
Step 3 – Create a New Actionscript 2 Flash File

Step 4 – Setting Up The Stage
Resize your stage to be a little larger than the images you created in Step 2. The goal is to make sure that what ever images are displayed don't get cut off in the final presentation. I used 800px x 800px to give the 700px images 50px of space on all sides. Now is also a great time to change the frame rate to 30fps for nice smooth transitions and pick a background color of your choice.

Step 5 – Setting Up The Timeline
Rename “layer 1” to “background”. Create a new layer and call it “content”. Create one more layer and call it “script” and it's a good idea to lock this layer. Anything you place on the background layer will display behind the slideshow. If you look at the example, the text is in this layer.

Step 6 – Create a Shell For The Loaded Images
Use the drawing object to create a white square on the stage. Select the square and convert it to a symbol (F8). Make sure the registration point is in the top left corner and call the clip “shell”. Give the clip an instance name of “shell_mc”.


Step 7 – Add the Photo Background
Inside “shell_mc” select the white box and convert it to a symbol (F8). Again, make sure the registration is in the top left and name the clip “background”. Give the new movieClip an instance name of “background_mc”. Lastly, name the layer "background" and lock it.
Step 8 – Create Loading Text
Inside “shell_mc” create a new layer called “text”. Use the text tool to create static text that says “loading image”. Move the text to x:20 and y:20 so that it ends up underneath the image.
Step 9 – Add an Image Load Target
Create another new layer inside “shell_mc” called “images”. Create a blank movieClip called “pics” then drag it from the library to the newly created "images" layer. Move the clip to x:10 and y:10 and give it an instance name of “pics_mc”.
Step 10 – Create a Shape to Mask the Image
Inside “shell_mc” create a layer above “images and name it “mask”. Make a new square, convert it to a movieClip called “mask” and give it an instance name of “mask_mc”. Move the clip to x:10 and y:10.
Step 11 – Convert the Shape to a Mask
Right click on the “mask” layer and select Mask. Make sure that the “mask” and “image” layer icons change to look like the example.

Step 12 – Create an Image Frame
Inside “shell_mc” create a layer above “mask” and name it “frame”. In the tool palette, select a stroke color and a different fill color, then create a square on the “frame” layer. Select the fill area and delete it leaving only the border. Double click the border to select it and convert it to a movieClip called “border”. Give the movieClip and instance name of “border_mc” and place it at x:10 and y:10.

Step 13 – Add a Drop Shadow
Go back to the root timeline and select “shell_mc”. Go to the properties panel and twirl down the Filters arrow. Click the small “page” icon and select drop shadow. This will add a little depth.

Step 14 – Create XML File and Add Structure
We're done with Flash for the moment and need to create an XML file to keep track of our pictures. Open your favorite text editor (pretty much anything that can edit HTML will work) and create a new file. Save the file in your project folder as content.xml. Now we need to add a structure to the file so Flash can understand how to use the information, we can do that with the following code:
<?xml version='1.0' encoding='UTF-8'?> <gallery></gallery>
Step 15 – Add Image Paths to XML File
Now we need to add paths to all the images in the slideshow (this is how Flash is going to “find” the images). Inside the <gallery> tags add a new tag called “image” and give it an attribute of “imgurl”. This attribute should equal an image path relative to the xml file. You'll need to create a new “image” tag for each image you plan to use in the slideshow.
<?xml version='1.0' encoding='UTF-8'?> <gallery> <image imgurl="assets/sxc_hu_410471_5588.jpg"></image> <image imgurl="assets/sxc_hu_1151936_79441078.jpg"></image> <image imgurl="assets/sxc_hu_1152040_85122875.jpg"></image> <image imgurl="assets/sxc_hu_1154131_54136948.jpg"></image> </gallery>
Save the file and close your text editor.
Step 16 – Download Tween Max
We're going to use a tweening library to help us animate the transitions between images, so open up your browser, go to http://blog.greensock.com/tweenmaxas2/ and click the "download AS2" button at the top. Open the zip file you downloaded, then copy the "gs" folder and its contents to your project folder.
It's time to go back to your Flash file and start writing some Actionscript. Select the first frame of the "script" layer and open the Actions Panel (Window > Actions). The following steps all require you to edit the contents of the Actions window, so from now on I'm simply going to refer to this as "script". As we go through the steps below you'll see all the script created to that point with the newest additions highlighted.
Step 17 – Include Tween Max
The first thing we need to do is include the tween class we downloaded so that it compiles when the swf is created. Add the following code to your script:
import gs.*; import gs.easing.*;
Step 18 – Tell Flash to Load the XML File
(Additional lines: 3-15)
import gs.*;
import gs.easing.*;
var xmlPath = "content.xml";
var photos_xml = new XML();
photos_xml.ignoreWhite = true;
photos_xml.onLoad = function(success) {
if (success) { // ----------- load successful
} else {// ----------- problem loading, check path
trace("Error loading photos_xml");
}
}
photos_xml.load(xmlPath);
This is creating a new XML object that targets our "content.xml" file. Since XML files don't load instantly, it's important to check for a completed load. We do this with the onLoad callback that waits for the xml file to be loaded and then performs an action.
Step 19 – Convert XML Data to an Array
First we need to create an array called "imageList". Once the xml file has loaded, we're going to assign the data to the array so that it's easier to access later.
(Additional lines: 7,10)
import gs.*;
import gs.easing.*;
var xmlPath = "content.xml";
var photos_xml = new XML();
photos_xml.ignoreWhite = true;
var imageList:Array = new Array();
photos_xml.onLoad = function(success) {
if (success) { // ----------- load successful
imageList = photos_xml.firstChild.childNodes;
} else {
// ----------- problem loading, check path
trace("Error loading photos_xml");
}
}
photos_xml.load(xmlPath);
Step 20 – Build Movieclip Loader Framework
Create an image loader object using the movieClipLoader class and use call backs to initiate commands when the movie starts/finishes loading.
(Additional lines: 17-27)
import gs.*;
import gs.easing.*;
var xmlPath = "content.xml";
var photos_xml = new XML();
photos_xml.ignoreWhite = true;
var imageList:Array = new Array();
photos_xml.onLoad = function(success) {
if (success) { // ----------- load successful
imageList = photos_xml.firstChild.childNodes;
} else {
// ----------- problem loading, check path
trace("Error loading photos_xml");
}
}
var imageLoader:MovieClipLoader = new MovieClipLoader();
var loadListener:Object = new Object();
imageLoader.addListener(loadListener);
loadListener.onLoadInit = function(target_mc:MovieClip, httpStatus:Number):Void {
}
loadListener.onLoadComplete = function(target_mc:MovieClip):Void {
}
photos_xml.load(xmlPath);
Step 21 - Create a Load Function
After the loader object exists we need a function to determine the correct images. We also have to add a variable to keep track of the current image. Inside the "loadImage" function the "loadURL" is set to the XML attribute for the image path. Define a new movieClip (targetClip) for a container to load the image into and set that container to have zero opacity with the _alpha property.
The last step in the function is to load the image into the container (imageLoader.loadClip). We also want to run the "loadImage" command as soon as the XML has successfully finished loading.
(Additional lines: 11,18,31-38)
import gs.*;
import gs.easing.*;
var xmlPath = "content.xml";
var photos_xml = new XML();
photos_xml.ignoreWhite = true;
var imageList:Array = new Array();
photos_xml.onLoad = function(success) {
if (success) { // ----------- load successful
imageList = photos_xml.firstChild.childNodes;
loadImage();
} else {
// ----------- problem loading, check path
trace("Error loading photos_xml");
}
}
var currentImage:Number = 0;
var imageLoader:MovieClipLoader = new MovieClipLoader();
var loadListener:Object = new Object();
imageLoader.addListener(loadListener);
loadListener.onLoadInit = function(target_mc:MovieClip, httpStatus:Number):Void {
}
loadListener.onLoadComplete = function(target_mc:MovieClip):Void {
}
function loadImage(){
var loadURL = imageList[currentImage].attributes.imgurl;
var targetClip = shell_mc.pics_mc.createEmptyMovieClip("pic"+currentImage,shell_mc.pics_mc.getNextHighestDepth());
targetClip._alpha = 0;
// load the new image
imageLoader.loadClip(loadURL,targetClip);
}
photos_xml.load(xmlPath);
Step 22 - Add a Timer Using the setInterval Function
Build a timer function that will call the "loadImage" function every 5000 miliseconds (5 seconds). Initiate the timer when when the image has completed loading, by placing the call in the onLoadComplete callback.
(Additional lines: 29,32-34)
import gs.*;
import gs.easing.*;
var xmlPath = "content.xml";
var photos_xml = new XML();
photos_xml.ignoreWhite = true;
var imageList:Array = new Array();
photos_xml.onLoad = function(success) {
if (success) { // ----------- load successful
imageList = photos_xml.firstChild.childNodes;
loadImage();
} else {
// ----------- problem loading, check path
trace("Error loading photos_xml");
}
}
var currentImage:Number = 0;
var imageLoader:MovieClipLoader = new MovieClipLoader();
var loadListener:Object = new Object();
imageLoader.addListener(loadListener);
loadListener.onLoadInit = function(target_mc:MovieClip, httpStatus:Number):Void {
}
loadListener.onLoadComplete = function(target_mc:MovieClip):Void {
setTimer();
}
function setTimer(){
timer = setInterval(loadImage, 5000);
}
function loadImage(){
var loadURL = imageList[currentImage].attributes.imgurl;
var targetClip = shell_mc.pics_mc.createEmptyMovieClip("pic"+currentImage,shell_mc.pics_mc.getNextHighestDepth());
targetClip._alpha = 0;
imageLoader.loadClip(loadURL,targetClip);
}
photos_xml.load(xmlPath);
Step 23 - Resize the Image Frame
We need to resize the "background_mc", "border_mc" and "mask_mc" to be the size of the loaded image. The TweenMax/TweenLite library is pretty easy to use. The syntax is TweenLite.to(target clip, time in seconds, {properties:value, ease type}); We also want the image to fade in after it has loaded, so set the _alpha to tween to 100% inside the onLoadComplete.
(Additional lines: 25-27,31)
import gs.*;
import gs.easing.*;
var xmlPath = "content.xml";
var photos_xml = new XML();
photos_xml.ignoreWhite = true;
var imageList:Array = new Array();
photos_xml.onLoad = function(success) {
if (success) { // ----------- load successful
imageList = photos_xml.firstChild.childNodes;
loadImage();
} else {
// ----------- problem loading, check path
trace("Error loading photos_xml");
}
}
var currentImage:Number = 0;
var imageLoader:MovieClipLoader = new MovieClipLoader();
var loadListener:Object = new Object();
imageLoader.addListener(loadListener);
loadListener.onLoadInit = function(target_mc:MovieClip, httpStatus:Number):Void {
TweenLite.to(shell_mc.background_mc, 0.25, {_width:target_mc._width + 20, _height:target_mc._height + 20, ease:Quad.easeOut});
TweenLite.to(shell_mc.border_mc, 0.25, {_width:target_mc._width, _height:target_mc._height, ease:Quad.easeOut});
TweenLite.to(shell_mc.mask_mc, 0.25, {_width:target_mc._width, _height:target_mc._height, ease:Quad.easeOut});
}
loadListener.onLoadComplete = function(target_mc:MovieClip):Void {
TweenLite.to(target_mc, 0.25, {autoAlpha:100, delay:0.25});
setTimer();
}
function setTimer(){
timer = setInterval(loadImage, 5000);
}
function removePrevious(){
if(prevImg != undefined){
removeMovieClip(prevImg);
}
// increment the current image
if(currentImage < imageList.length -1){
currentImage = currentImage + 1;
}else{
currentImage = 0;
}
}
function loadImage(){
var loadURL = imageList[currentImage].attributes.imgurl;
var targetClip = shell_mc.pics_mc.createEmptyMovieClip("pic"+currentImage,shell_mc.pics_mc.getNextHighestDepth());
targetClip._alpha = 0;
imageLoader.loadClip(loadURL,targetClip);
}
photos_xml.load(xmlPath);
Step 24 - Center the Image
First find the center of the stage by dividing the stage height by 2 and the stage width by 2. Next, since the registration point of the shell is in the top left, move the clip to the left of the center of the stage by half the shell's width and up by half the shell's height (variables clipXTarg and clipYtarg calculate the numbers for each new image). Its important to use the Math.round() function so that the final number doesn't contain a decimal - this forces the final position to a full pixel.
(Additional lines: 28-30)
import gs.*;
import gs.easing.*;
var xmlPath = "content.xml";
var photos_xml = new XML();
photos_xml.ignoreWhite = true;
var imageList:Array = new Array();
photos_xml.onLoad = function(success) {
if (success) { // ----------- load successful
imageList = photos_xml.firstChild.childNodes;
loadImage();
} else {
// ----------- problem loading, check path
trace("Error loading photos_xml");
}
}
var currentImage:Number = 0;
var imageLoader:MovieClipLoader = new MovieClipLoader();
var loadListener:Object = new Object();
imageLoader.addListener(loadListener);
loadListener.onLoadInit = function(target_mc:MovieClip, httpStatus:Number):Void {
TweenLite.to(shell_mc.background_mc, 0.25, {_width:target_mc._width + 20, _height:target_mc._height + 20, ease:Quad.easeOut});
TweenLite.to(shell_mc.border_mc, 0.25, {_width:target_mc._width, _height:target_mc._height, ease:Quad.easeOut});
TweenLite.to(shell_mc.mask_mc, 0.25, {_width:target_mc._width, _height:target_mc._height, ease:Quad.easeOut});
var clipXTarg = Math.round((Stage.width/2)-((target_mc._width+20)/2));
var clipYTarg = Math.round((Stage.height/2)-((target_mc._height+20)/2));
TweenLite.to(shell_mc, 0.25, {_x:clipXTarg, _y:clipYTarg, ease:Quad.easeOut});
}
loadListener.onLoadComplete = function(target_mc:MovieClip):Void {
TweenLite.to(target_mc, 0.25, {autoAlpha:100, delay:0.25});
setTimer();
}
function setTimer(){
timer = setInterval(loadImage, 5000);
}
function loadImage(){
var loadURL = imageList[currentImage].attributes.imgurl;
var targetClip = shell_mc.pics_mc.createEmptyMovieClip("pic"+currentImage,shell_mc.pics_mc.getNextHighestDepth());
targetClip._alpha = 0;
imageLoader.loadClip(loadURL,targetClip);
}
photos_xml.load(xmlPath);
Step 25 - Identify the Previous Image
We need to find the previously loaded image so that it can be removed. Obviously if the current image is some where in the middle of the list then the previous image is one less than the curentImage number. However, if the currentImage is equal to zero then the previous image (assuming the slideshow has stepped through every image) would be the last image in the array or imageList.length - 1. Take the previous image number and figure out the movieClip path to the previous image shell.
(Additional lines: 32-37)
import gs.*;
import gs.easing.*;
var xmlPath = "content.xml";
var photos_xml = new XML();
photos_xml.ignoreWhite = true;
var imageList:Array = new Array();
photos_xml.onLoad = function(success) {
if (success) { // ----------- load successful
imageList = photos_xml.firstChild.childNodes;
loadImage();
} else {
// ----------- problem loading, check path
trace("Error loading photos_xml");
}
}
var currentImage:Number = 0;
var imageLoader:MovieClipLoader = new MovieClipLoader();
var loadListener:Object = new Object();
imageLoader.addListener(loadListener);
loadListener.onLoadInit = function(target_mc:MovieClip, httpStatus:Number):Void {
TweenLite.to(shell_mc.background_mc, 0.25, {_width:target_mc._width + 20, _height:target_mc._height + 20, ease:Quad.easeOut});
TweenLite.to(shell_mc.border_mc, 0.25, {_width:target_mc._width, _height:target_mc._height, ease:Quad.easeOut});
TweenLite.to(shell_mc.mask_mc, 0.25, {_width:target_mc._width, _height:target_mc._height, ease:Quad.easeOut});
var clipXTarg = Math.round((Stage.width/2)-((target_mc._width+20)/2));
var clipYTarg = Math.round((Stage.height/2)-((target_mc._height+20)/2));
TweenLite.to(shell_mc, 0.25, {_x:clipXTarg, _y:clipYTarg, ease:Quad.easeOut});
if(currentImage == 0){
var prevImgNum = imageList.length -1;
}else{
var prevImgNum = currentImage - 1;
}
var prevImg = shell_mc.pics_mc["pic"+prevImgNum];
}
loadListener.onLoadComplete = function(target_mc:MovieClip):Void {
TweenLite.to(target_mc, 0.25, {autoAlpha:100, delay:0.25});
setTimer();
}
function setTimer(){
timer = setInterval(loadImage, 5000);
}
function loadImage(){
var loadURL = imageList[currentImage].attributes.imgurl;
var targetClip = shell_mc.pics_mc.createEmptyMovieClip("pic"+currentImage,shell_mc.pics_mc.getNextHighestDepth());
targetClip._alpha = 0;
imageLoader.loadClip(loadURL,targetClip);
}
photos_xml.load(xmlPath);
Step 26 - Fade Out and Remove
Next we want to fade out the previous image and then when it gets to zero _alpha we need to remove the clip from the stage entirely. The onComplete:removePrevious waits until the fade has completed and then calls a the "removePrevious". As a safety measure its always a good idea to make sure that the clip we're trying to remove actually exists. Therefore use an "if" statement to check that the clip is not undefined (Flash's word for doesn't exist).
(Additional lines: 38,50-54)
import gs.*;
import gs.easing.*;
var xmlPath = "content.xml";
var photos_xml = new XML();
photos_xml.ignoreWhite = true;
var imageList:Array = new Array();
photos_xml.onLoad = function(success) {
if (success) { // ----------- load successful
imageList = photos_xml.firstChild.childNodes;
loadImage();
} else {
// ----------- problem loading, check path
trace("Error loading photos_xml");
}
}
var currentImage:Number = 0;
var imageLoader:MovieClipLoader = new MovieClipLoader();
var loadListener:Object = new Object();
imageLoader.addListener(loadListener);
loadListener.onLoadInit = function(target_mc:MovieClip, httpStatus:Number):Void {
TweenLite.to(shell_mc.background_mc, 0.25, {_width:target_mc._width + 20, _height:target_mc._height + 20, ease:Quad.easeOut});
TweenLite.to(shell_mc.border_mc, 0.25, {_width:target_mc._width, _height:target_mc._height, ease:Quad.easeOut});
TweenLite.to(shell_mc.mask_mc, 0.25, {_width:target_mc._width, _height:target_mc._height, ease:Quad.easeOut});
var clipXTarg = Math.round((Stage.width/2)-((target_mc._width+20)/2));
var clipYTarg = Math.round((Stage.height/2)-((target_mc._height+20)/2));
TweenLite.to(shell_mc, 0.25, {_x:clipXTarg, _y:clipYTarg, ease:Quad.easeOut});
if(currentImage == 0){
var prevImgNum = imageList.length -1;
}else{
var prevImgNum = currentImage - 1;
}
var prevImg = shell_mc.pics_mc["pic"+prevImgNum];
TweenLite.to(prevImg, 0.25, {autoAlpha:0, onComplete:removePrevious});
}
loadListener.onLoadComplete = function(target_mc:MovieClip):Void {
TweenLite.to(target_mc, 0.25, {autoAlpha:100, delay:0.25});
setTimer();
}
function setTimer(){
timer = setInterval(loadImage, 5000);
}
function removePrevious(){
if(prevImg != undefined){
removeMovieClip(prevImg);
}
}
function loadImage(){
var loadURL = imageList[currentImage].attributes.imgurl;
var targetClip = shell_mc.pics_mc.createEmptyMovieClip("pic"+currentImage,shell_mc.pics_mc.getNextHighestDepth());
targetClip._alpha = 0;
imageLoader.loadClip(loadURL,targetClip);
}
photos_xml.load(xmlPath);
Step 27 - Next Image in the Sequence
Now we need to increment the currentImage so that when the timer completes, Flash knows which image to load next. Just like the previousImage, if the current image is any number except the last image in the list we simply add one to the currentImage number. However, if the current image is the last item in the list then the "next" image would start the list over with the first image in the list (position zero in the array).
(Additional lines: 55-59)
import gs.*;
import gs.easing.*;
var xmlPath = "content.xml";
var photos_xml = new XML();
photos_xml.ignoreWhite = true;
var imageList:Array = new Array();
photos_xml.onLoad = function(success) {
if (success) { // ----------- load successful
imageList = photos_xml.firstChild.childNodes;
loadImage();
} else {
// ----------- problem loading, check path
trace("Error loading photos_xml");
}
}
var currentImage:Number = 0;
var imageLoader:MovieClipLoader = new MovieClipLoader();
var loadListener:Object = new Object();
imageLoader.addListener(loadListener);
loadListener.onLoadInit = function(target_mc:MovieClip, httpStatus:Number):Void {
TweenLite.to(shell_mc.background_mc, 0.25, {_width:target_mc._width + 20, _height:target_mc._height + 20, ease:Quad.easeOut});
TweenLite.to(shell_mc.border_mc, 0.25, {_width:target_mc._width, _height:target_mc._height, ease:Quad.easeOut});
TweenLite.to(shell_mc.mask_mc, 0.25, {_width:target_mc._width, _height:target_mc._height, ease:Quad.easeOut});
var clipXTarg = Math.round((Stage.width/2)-((target_mc._width+20)/2));
var clipYTarg = Math.round((Stage.height/2)-((target_mc._height+20)/2));
TweenLite.to(shell_mc, 0.25, {_x:clipXTarg, _y:clipYTarg, ease:Quad.easeOut});
if(currentImage == 0){
var prevImgNum = imageList.length -1;
}else{
var prevImgNum = currentImage - 1;
}
var prevImg = shell_mc.pics_mc["pic"+prevImgNum];
TweenLite.to(prevImg, 0.25, {autoAlpha:0, onComplete:removePrevious});
}
loadListener.onLoadComplete = function(target_mc:MovieClip):Void {
TweenLite.to(target_mc, 0.25, {autoAlpha:100, delay:0.25});
setTimer();
}
function setTimer(){
timer = setInterval(loadImage, 5000);
}
function removePrevious(){
if(prevImg != undefined){
removeMovieClip(prevImg);
}
if(currentImage < imageList.length -1){
currentImage = currentImage + 1;
}else{
currentImage = 0;
}
}
function loadImage(){
var loadURL = imageList[currentImage].attributes.imgurl;
var targetClip = shell_mc.pics_mc.createEmptyMovieClip("pic"+currentImage,shell_mc.pics_mc.getNextHighestDepth());
targetClip._alpha = 0;
imageLoader.loadClip(loadURL,targetClip);
}
photos_xml.load(xmlPath);
Step 28 - Remove the Timer
Most Actionscript functions occur almost instantly, however loading images requires some amount of time. This amount of time depends on the network connection speed and image size and could therefore be several seconds long. We need to remove the timer until the image has finished loading so that the slide show is a consistent length of time after the image has loaded. One simple line of code (clearInterval) removes the 5 second interval until it is reset by the setInterval running again.
(Additional line: 66)
import gs.*;
import gs.easing.*;
var xmlPath = "content.xml";
var photos_xml = new XML();
photos_xml.ignoreWhite = true;
var imageList:Array = new Array();
photos_xml.onLoad = function(success) {
if (success) { // ----------- load successful
imageList = photos_xml.firstChild.childNodes;
loadImage();
} else {
// ----------- problem loading, check path
trace("Error loading photos_xml");
}
}
var currentImage:Number = 0;
var imageLoader:MovieClipLoader = new MovieClipLoader();
var loadListener:Object = new Object();
imageLoader.addListener(loadListener);
loadListener.onLoadInit = function(target_mc:MovieClip, httpStatus:Number):Void {
TweenLite.to(shell_mc.background_mc, 0.25, {_width:target_mc._width + 20, _height:target_mc._height + 20, ease:Quad.easeOut});
TweenLite.to(shell_mc.border_mc, 0.25, {_width:target_mc._width, _height:target_mc._height, ease:Quad.easeOut});
TweenLite.to(shell_mc.mask_mc, 0.25, {_width:target_mc._width, _height:target_mc._height, ease:Quad.easeOut});
var clipXTarg = Math.round((Stage.width/2)-((target_mc._width+20)/2));
var clipYTarg = Math.round((Stage.height/2)-((target_mc._height+20)/2));
TweenLite.to(shell_mc, 0.25, {_x:clipXTarg, _y:clipYTarg, ease:Quad.easeOut});
if(currentImage == 0){
var prevImgNum = imageList.length -1;
}else{
var prevImgNum = currentImage - 1;
}
var prevImg = shell_mc.pics_mc["pic"+prevImgNum];
TweenLite.to(prevImg, 0.25, {autoAlpha:0, onComplete:removePrevious});
}
loadListener.onLoadComplete = function(target_mc:MovieClip):Void {
TweenLite.to(target_mc, 0.25, {autoAlpha:100, delay:0.25});
setTimer();
}
function setTimer(){
timer = setInterval(loadImage, 5000);
}
function removePrevious(){
if(prevImg != undefined){
removeMovieClip(prevImg);
}
if(currentImage < imageList.length -1){
currentImage = currentImage + 1;
}else{
currentImage = 0;
}
}
function loadImage(){
var loadURL = imageList[currentImage].attributes.imgurl;
var targetClip = shell_mc.pics_mc.createEmptyMovieClip("pic"+currentImage,shell_mc.pics_mc.getNextHighestDepth());
targetClip._alpha = 0;
clearInterval(timer);
imageLoader.loadClip(loadURL,targetClip);
}
photos_xml.load(xmlPath);
Step 29 - Stop the Timeline
Finally, we need to stop the timeline. Flash's default function is to play the timeline continuously unless told otherwise. In the case where there is only one frame on the timeline Flash will continue to attempt to run the same code over and over again, resulting in the same image trying to repeatedly load.
(Additional line: 72)
import gs.*;
import gs.easing.*;
var xmlPath = "content.xml";
var photos_xml = new XML();
photos_xml.ignoreWhite = true;
var imageList:Array = new Array();
photos_xml.onLoad = function(success) {
if (success) { // ----------- load successful
imageList = photos_xml.firstChild.childNodes;
loadImage();
} else {
// ----------- problem loading, check path
trace("Error loading photos_xml");
}
}
var currentImage:Number = 0;
var imageLoader:MovieClipLoader = new MovieClipLoader();
var loadListener:Object = new Object();
imageLoader.addListener(loadListener);
loadListener.onLoadInit = function(target_mc:MovieClip, httpStatus:Number):Void {
TweenLite.to(shell_mc.background_mc, 0.25, {_width:target_mc._width + 20, _height:target_mc._height + 20, ease:Quad.easeOut});
TweenLite.to(shell_mc.border_mc, 0.25, {_width:target_mc._width, _height:target_mc._height, ease:Quad.easeOut});
TweenLite.to(shell_mc.mask_mc, 0.25, {_width:target_mc._width, _height:target_mc._height, ease:Quad.easeOut});
var clipXTarg = Math.round((Stage.width/2)-((target_mc._width+20)/2));
var clipYTarg = Math.round((Stage.height/2)-((target_mc._height+20)/2));
TweenLite.to(shell_mc, 0.25, {_x:clipXTarg, _y:clipYTarg, ease:Quad.easeOut});
if(currentImage == 0){
var prevImgNum = imageList.length -1;
}else{
var prevImgNum = currentImage - 1;
}
var prevImg = shell_mc.pics_mc["pic"+prevImgNum];
TweenLite.to(prevImg, 0.25, {autoAlpha:0, onComplete:removePrevious});
}
loadListener.onLoadComplete = function(target_mc:MovieClip):Void {
TweenLite.to(target_mc, 0.25, {autoAlpha:100, delay:0.25});
setTimer();
}
function setTimer(){
timer = setInterval(loadImage, 5000);
}
function removePrevious(){
if(prevImg != undefined){
removeMovieClip(prevImg);
}
if(currentImage < imageList.length -1){
currentImage = currentImage + 1;
}else{
currentImage = 0;
}
}
function loadImage(){
var loadURL = imageList[currentImage].attributes.imgurl;
var targetClip = shell_mc.pics_mc.createEmptyMovieClip("pic"+currentImage,shell_mc.pics_mc.getNextHighestDepth());
targetClip._alpha = 0;
clearInterval(timer);
imageLoader.loadClip(loadURL,targetClip);
}
photos_xml.load(xmlPath);
stop();
Conclusion
Test your movie (Command + Enter for the Mac, Ctrl + Enter for Windows). You should see a working slideshow that resizes and centers based on the size of the images. I hope you enjoyed following this tut!














User Comments
( ADD YOURS )giackop April 1st
awesome!!
( )Lawrence77 April 1st
The preview works well in InternetExplorer…
( )Check it out guys!
kevin April 1st
AS2 SUCKS
( )Kylio April 1st
right with you, on that 1!
( )sriganesh April 1st
NO IT DOESNT SUCKS, KEVIN….
( )Michel April 2nd
Yes it does suck, sriganesh…
ddz April 2nd
fo shizzle muy nizzle it sucks
( )Giulian April 2nd
Yes…AS2 Suck !!!!!!
( )Vallaris April 3rd
AS 3 is much better and more… maybe convenient. And it also more powerful )
For coding use Flex
Flash is an instrument for designers )
Lawrence77 April 1st
i gonna love flash and AS!
( )Wow!
Flow April 1st
The livepreview doesn’t work
( )dan April 1st
The download files section doesnt work
( )Ian Yates April 2nd
Sorry Dan, more teething problems..
The link is fixed, go ahead and download the source.zip!
( )sike April 1st
Nice article, clean code.
( )curtisallen April 1st
Nice tutorial, keep up the good work.
( )Mike April 1st
The live preview didn’t work for me in Firefox 3.0.8 on Windows XP with Flash Player 10,0,22,87. I just saw the grey background.
It did work in Safari 3 on Windows. I haven’t tested any other browsers.
Personally I’m only interested in investing time to learn AS3.
( )Bryce April 1st
Mike, I noticed that issue as well with Firefox 3/Vista. Looks like it might be an issue with the S3 implementation. I’ve notified the Flash Tuts Editor so hopefully we can get it resolved soon.
While I agree that AS3 is the way to go, the choice was made to produce this tutorial in AS2 since that version is a bit more forgiving/less daunting for people trying to wrap their heads around the code side of Flash. I’m sure there will be a good many AS3 featured here in the future.
( )Ian Yates April 1st
Consider the preview issue resolved, thanks to all who picked up on it..
( )Bart April 1st
That’s right. I doesn’t work on my FF neither. It does work on IE 7 and looks good
. It also works on Opera 9.62, but it’s sooooo tiny…. just look here: http://f.imagehost.org/0468/slideshow.jpg to see what I mean.
( )Matt Radel April 1st
Very nice – thanks! Seeing an as3 version would be swell, especially with some controls. Still though – very handy tut to stuff in the back pocket.
( )Richard S Davies April 1st
Preview not working for me, and pity its not in AS3.
( )Peewee1002 April 1st
Its cool, preview works for me but it would be great if you could add buttons in order to skip images it would be perfect!
( )b00m April 1st
Yeah it’s not working in FF.
( )Guyda April 1st
Nice tutorial.. I did the almost exact same sort of slide show about 2 weeks ago. And not that much different except the transition of resizing content with the tweenlite. Thanks.
( )Guyda April 1st
By the way… thanks for using this script with AS2.. AS IS NOT DEAD! woohooooo \o/
( )Mike April 1st
Definitely a good tutorial, but I don’t see much point in an AS2 tutorial, especially since AS3 has been out for 2 flash versions now.
( )keruchan April 1st
preview doesn’t work for me too, but I love the tutorial. ^_~
( )Diego SA April 1st
LOL! Funny avatar!
( )hobofan April 1st
just go to:
http://flashtuts.s3.amazonaws.com/005_xmlSlideshow/preview/preview.swf
worked fine for me in FF with that link
( )alvin c. April 1st
I dont quite understand why there are still tutorials for AS2 when AS3 overcomes all the obstacles that AS2 had.
( )keruchan April 1st
coz it works, as long as it works then why worry? ^^ in the first place your visitors don’t care about your script, what they see are the end result.
just like how you don’t bother what’s happening on the backstage while watching an stage performance. ^_~
( )szymon April 1st
Preview doesn’t work for me on FF on Mac
( )ateshcek April 1st
On Mac, Safari works
( )pixelMauler April 13th
that would be an HTML issue then.
jhon September 8th
For me it’s ok, FF in mac, I hope the same tut in AS3 in the future
( )carlos April 1st
Link to the preview is not working in Firefox. Need to fix that.
( )Slash April 1st
Small typo at line 56 currentImagecurrentImage should be just currentImage!
( )Ian Yates April 1st
Thanks Slash, that’s an interesting one… It seems to be an error thrown out by the Syntax Highlighter script (you won’t find ‘currentImagecurrentImage ‘ in your page source)
I’ll get onto it..!
( )carlos April 1st
What about user controls for the slideshow?
( )RUGRLN April 1st
I’ve got Flash CS4, Flash Player 10, Firefox 3.0.8 and your preview link don’t work….
( )Lawrence77 April 1st
yes this problem arise for me also Rugrln….
( )I preview that using InternetExplorer!
Diego SA April 1st
I still didn’t learn AS with XML. Indeed, it’s very useful.
I hope see here a tut teaching how to create a news system or a portfolio system using XML and some kind of database.
And great tutorial! Thanks a lot!
( )Bav April 1st
Nice tutorial but as soon as I saw AS2 I stopped being interested. I am currently learning AS 3.0 and would not want do this incase it uses techniques replaced in AS3.0. This isnt like doing a PS CS4 tutorial which uses the same tools of PSCS3.
Is there any chance you could do this tutorial for AS3.0? I just think that any AS related tutorials should use the latest version as it will immediatley put off people new to AS3.0.
Thanks
( )Alex April 1st
Anyone using this should check out the licensing on TweenMax. There are a few catches when using it on commerical projects. I don’t think you can use the library in a component you want to sell, or a service that requires a fee per user. Just something to keep in mind if you decide to use this tut for anything commercial. Might just need to swap the tween engine out for something else.
( )mike April 1st
why AS2 ?????????????
( )Lawrence77 April 1st
If i use this link http://www.flash.tutsplus.com it redirects me to a login screen of tutsplus member….
Why this happen??
anybody reply?
( )Alex April 1st
Try it without the www.
( )david April 1st
take out the www. if you want to bookmark flash tuts
( )sriganesh April 1st
HEY LAWERENCE, ANTHA LINK`U MEMBER AGARATHUKU. OK VA. NO PROBLEM AT ALL
( )Ian Yates April 2nd
All the tuts+ sites use subdomains of tutsplus.com now – Flashtuts+ can be found here:
http://flash.tutsplus.com
(forget the http://www...)
( )samBrown April 1st
appreciate the tut, great real-world, expandable gallery……love the resizing
But right when I saw AS2, I stopped reading a started skimming.
( )Kristian April 1st
Probably a great tut… but hey…. ActionScript 2.0 sucks! Give me AS3… and I’ll spend time with the tuts.
( )VertigoSFX April 1st
Works in firefox for me but takes a helluva long time to switch photos…kinda annoying…it looks like it could be a nice effect though.
( )Ben April 1st
I think most people are trying to transit to AS3 or already using it, even if they’re not, AS3 is the latest in Flash and should be used for Flash tutorials to move people forward, especially if it is an Envato’s tutorial which should lead people to follow the latest trends.
I am an AS3 coder myself and I have no other choice but to completely skipped this tutorial, like most people, if you’re already using AS3, you won’t look back.
The preview is not working too by the way and I am using the latest Firefox browser and Flash plugin. Kinda weird.
( )Bav April 2nd
Yes I agree. I was really looking forward to flatuts launching and I hope this sort of thing doesn’t belong a regular occurence. How do they expect people to sign up for a subscription if they are teaching old techniques that people are trying to get away from doing.
( )Ibesoringola April 1st
Sweet stuff bro!!!
( )Onur ACUN April 1st
thanks for everthing but pls use as3 in yours tutorials…
( )sucreZ April 1st
great tutorial.
( )thanks!
Steve Forbes April 2nd
Nice tutorial bro!
Works fine for me in both IE7 and FF 3.0.8 on Windows XP Pro
( )whatever April 2nd
This should have been in AS3. Plus the new E4X for XML is soooooo much simpler.
( )Philo April 2nd
Nice Tutorial, although i think the code could use a bit more explanation.
( )Franky April 2nd
AS2?????!!!
What the funky am I supposed to do with this!!!!
( )Yikes….
;D:D:D:D:D:D
Jul April 2nd
AS2 ???? So so sad !
( )Sean April 2nd
Thanks for the tutorial. I’m an AE and PS guy looking to learn flash. Stuff like this is aweome.
Lots of people whining about AS2, though. Not knowing much, I will defer to them….but so much complaining about a free tutorial? Seems strange…
( )Mark April 2nd
AS2?????????????????
( )Should be written in AS3 – its much more simpler and way more cleaner and easier for people to understand
Bruno April 3rd
Very good AS2 work !!!! Very good use of the AS2 limitations.
( )Meech April 4th
I am going to agree with Mark here (2nd post above mine here) that this should definitely have been written in AS3. I suppose this is good to have in the drawer if you NEED an AS2 targeted site, but otherwise it is not in keeping up with
( )_Tristan April 4th
Nothing better than to know your history ! ^^
( )Nice tutorial ! Very well done.
gfx April 5th
what about AS 3.0?
( )andre April 5th
AS2 sucks;
( )AS3 Rocks
Angela April 8th
Hi I’ved done this tutorial a number of times and checked my movieclip names and code and each time the images dont seem to change to new images. The first image changes each time to the first image again. I’ve used the exact code. There are no script errors and I am also using Flash8 and actionscript2. I dont know what I am doing wrong.
Below is a link to my swf
http://www.devproject.co.uk/flashslideshow/
( )Ben Rinehart April 8th
Your problem is likely here:
currentImagecurrentImage = currentImage + 1;
that should only be:
currentImage = currentImage + 1;
it’s a typo in the tutorial.
( )Ian Yates April 8th
Quite right, sorry about that. There was an error in the Google Syntax Highlighter which we use to display the code (not a typo by Bryce).
It’s now fixed, the unwanted currentImage is no longer with us, so please give it another go!
( )chasen April 10th
Great tutorial…. hower, what would be a simple way to add controls to this?
( )Jaime alvarez April 10th
Ey gracias viejo. Funciona de marvilla.
( )Nicolás April 10th
looks great, but I have this problem using Flash CS4:
Quad.as, line 1
ERROR 5007: An ActionScript file must hav at least an externally vissible definition
( )Alli April 15th
does anyone know how to make the image cycle in this code random?
( )Joshfromdallas April 21st
any luck on the random? What about a contoller to pause and go forward and back?
( )Stu April 24th
great tutorial, just wondering if anyone knew about adding controls, so rather then taking 5 seconds to load next image, the user could just use a next and previous button?
any ideas please let me know, would be greatly appreciated
( )Ian Yates April 24th
From the wisdom of various Flashtuts+ authors we’ll be covering many aspects of slideshows in the coming months, stay tuned! (and keep the suggestions coming
)
( )rishteria May 14th
You can make a function that increases or decreases “currentImage” counter …
function next(){
currentImage++;
loadImage();
}
function previos(){
currentImage–;
loadImage();
}
And modify the loadImage function of course
( )cado April 24th
i would like to add a link on every images… is it possible?
( )thanks a lot
CgBaran Tuts April 27th
It would be better if it is in as3 but nice work
( )Andre Mourinho May 20th
This tutorial worked out great for me. Struggling for days until I came across it. AS3 would have been nicer, but you wont hear a complaint out of me =)
( )Andre Mourinho May 20th
For those of you asking about a pause feature, add two simple buttons. (pause_mc, and play_mc)
heres the code i added.
pause_mc.onRelease = function() {
( )clearInterval(timer);
pause_mc._visible = false;
play_mc._visible = true;
};
play_mc.onRelease = function() {
timer = setInterval(loadImage, 500);
pause_mc._visible = true;
play_mc._visible = false;
};
Alex May 29th
How would you go about adding the actionscript for back function?
I’m pulling my hair out here! Any help would be incredibly appreciated.
A simple decrement didn’t work for me…
( )Alex June 1st
Anyone good enough to help me with a back button? Any help would be super appreciated!
( )FuFu May 29th
i can’t open the preview.fla – don’t have cs4…can you send me a cs3 version?
( )Tomas Sinkunas June 2nd
Hello Guys.
I’ve took courage to update a script a little to add a captions, if you don’t mind:) It’s not perfect, but at least I try:)
So here it goes.
Create two text boxes (”pos_txt” (this one to display current image out of all images) and “cap_txt” to display a captions).
In ACTION window right before “// increment the current image” text insert these lines:
var my_caption = imageList[currentImage].attributes.Caption;
pos_txt.text = currentImage+1+” / “+imageList.length;
cap_txt.text = my_caption;
and update “content.xml” file in such order
Hope that someone will find it useful.
P.S. All credits still go to Bryce Howitson. If I brake any role with this message, please feel free to delete it. Thanks.
( )Alex June 3rd
Very helpful Tomas, thanks! Shall definitely be including that.
If anyone can send me any pointers on how to make a back button work I would be thoroughly grateful. I’ve tried for a few days now but using the prevImage variable seems to not work, even though I can trace out the correct index of the array for it all to work, still it behaves strangely. I’m sure it’s my own stupidity but I’m close to giving up and going back to basics without the lovely fade this script has… Any help would be super. Cheers in advance, Alex
( )Tomas Sinkunas June 3rd
ups. sorry, it seems I lost one line in my previous post.
“content.xml” should be updated in this manner
“”
hope this will make it work:)
( )Tomas Sinkunas June 3rd
man, … sorry
something seems to not post right. Any ways, in contect.xml update lines inserting “Caption=”YOUR TEXT HERE” after “image imgurl=”xxx”"
“image imgurl=”assets/01.jpg” Caption=”YOUR TEXT HERE”></image”
And yes, action and button to go back would be super awesome as well. I couldn’t make it myself:P
( )Tomas Sinkunas June 5th
please, can someone help making PREVIOUS and NEXT buttons to work with this script? I spent over 4 hours and didn’t succeed:(
any help?
( )design July 8th
hi,please give me sourse of flash cs3
( )dev July 12th
why AS2 appear at Flash tuts, it should only contain AS3, coz AS2 will be drop by majority ActionScript Code
( )Garrett July 15th
I am looking for a way to add text to this. An image description.
( )Zebratan July 23rd
First of all great tutorial.
Secondly I would like to join Alex and several other users asking how to get working back and forward buttons implemented into this.
It would really help me a lot…
( )Jason August 21st
Excellent Tutorial!
Can someone help me randomize the order of the images, but not repeat?
Thanks in advance.
( )Jason August 23rd
I figured it out with lots of searching on the internet. The answer was to add the following two lines below the line:
imageList = photos_xml.firstChild.childNodes;
imageList.sort(function(){return Math.floor(Math.random()*3)-1});
imageList.pop();
These lines essentially randomizes the xml data as it is loaded into the array and keeps the slideshow from repeating any images.
Hope this helps someone else!
( )jorge September 7th
hello, great tutorial, thanks for shearing this, I have some questions, How can I call the image from number, i added to the slideshow some thumbnails and want them to work with the slideshow, like if i click on thumb 5 image 5 loads on stage and the timer continue running, anyone can give me an insight in this one??
( )Nishant Makvana September 18th
Hi,
I am new to flash as2 and i learned a lot from this tutorial
it help me a lot
thanks for this great work.
keep doing great.
( )Kem September 29th
Great Work Bryce Howitson !!!
congratulatione.
( )Brian October 7th
The source file won’t open in Flash CS3. I get an error saying “unexpected file format”.
Otherwise, a great tutorial!
( )sasakae November 6th
lol. nerds. its fine for me to work with.
( )Silvia November 12th
Hello Bryce,
( )great tutorial, thanks!
By the way, the second photo is the Oropa sanctuary, near Biella (my town) in Italy. What a surprise!
Silvia