RSS

Create a AS3 Slideshow with XML

Wed, Jul 23, 2008

Flash, Interfaces, XML

Create a AS3 Slideshow with XML

This tutorial shows you how to create a simple slideshow using as3/flash and xml like this one.

In order to complete this tutorial you can download the source files here.

In our xml file, we want to store the path to the slides and a description for each of it. So let’s take a look at the example file

<?xml version="1.0" encoding="UTF-8"?>

  <slideshow>

<image src="images/fly.jpg" desc="Fly"/>

<image src="images/mouse.jpg" desc="Computer mouse"/>

<image src="images/country.jpg" desc="Country"/>

<image src="images/rope.jpg" desc="Rope"/>

<image src="images/flower.jpg" desc="Flower"/>

</slideshow>

On the first line we describe the version and the encoding of the file. Flash uses UTF-8 for encoding, so we should edit the file in UTF-8 only to avoid character encoding problems.

The first node defines the root node of the xml file and contains further nodes. These are the images with the attributes src and desc. Okey, that’s how the structure of the xml looks like, let’s move on to the flash file.
The stage has a movieclip which contains the textfields which will show us the description of the slides, the loading process and the slide count later. Under it you will find a mask layer which masks an empty movieclip, where our slides will be loaded into. And on our first layer we have the whole script, at wich we’ll take a look now.

As always, we need to import the necessary librarys first. In our case, we only have caurinas tweener engine which will later be used to fade in the slides.

import caurina.transitions.Tweener;

Then we define two constants. One for the delay between the slides in milliseconds and the other one for the fade time between the slides in seconds. You can change them freely according to your needs

const TIMER_DELAY:int = 5000;
const FADE_TIME:int =	1;

Now we need to set some variables for the slideshow. We’re beginning with a variable, that holds a reference to the current container which holds the slide and is in the front

var currentContainer:Sprite;

To know which slide is currently active, we set a integer. We start at -1 because the function switchSlide will go to the first slide, which is 0.

var intCurrentSlide:int = -1;

The total count of the slides will be stored in a integer variable

var intSlideCount:int;

Then we need to define a timer, which calls the switchSlide function after the delay time we set in the constant

var slideTimer:Timer;

To have a nice fade effect, we need two containers for the slides. Each one will contain one slide

var sprContainer1:Sprite;
var sprContainer2:Sprite;

Next we set a variable for loading our slides

var slideLoader:Loader;

The next variable defines the path to the xml file

var strXMLPath:String = "slideshow-data.xml";

xmlLoader will be used to load the xml file

var xmlLoader:URLLoader;

And finally we need a variable to store the xml stuff

var xmlSlideshow:XML;

Now we need to initialize the whole slideshow. First, we create a new urlloader for the slideshow xml file, add an event listener when it’s completly and load it

xmlLoader = new URLLoader();
xmlLoader.addEventListener(Event.COMPLETE, onXMLLoadComplete);
xmlLoader.load(new URLRequest(strXMLPath));

Then we create the time with the delay from the constant and add an event listener for the timer event

slideTimer = new Timer(TIMER_DELAY);
slideTimer.addEventListener(TimerEvent.TIMER, switchSlide);

Next we create 2 container sprite which will hold the slides and add them to the masked movieclip

sprContainer1 = new Sprite();
sprContainer2 = new Sprite();
mcSlideHolder.addChild(sprContainer1);
mcSlideHolder.addChild(sprContainer2);

And last of all, we keep a reference of the container which is currently in the front

currentContainer = sprContainer2;

Once our xml file is fully loaded, the function onXMLLoadComplete will be called. This function assigns the received data to xmlSlideshow, gets the total slide count and stores it in the variable intSlideCount. Then it’ll call the function switchSlide which will immadiately load the next slide without waiting on the timer event.

xmlSlideshow = new XML(e.target.data);
intSlideCount = xmlSlideshow..image.length();
switchSlide(null);

Ok, let’s move on to the switchSlide function. This function will be called every time the timer has reached the delay and fires the timer event. First of all, we check, if the timer is running and stop it, because we need to wait until the next slide will be loaded and faded in. Then we check if there are any slides left. If not, we go back to the beginning. Now we need to figure out, wich container is currently in the front and assign currentContainer to the one, that’s in the back containing the old slide. Next we hide the old slide and bring it to the front.

if(slideTimer.running)
	slideTimer.stop();

if(intCurrentSlide + 1 < intSlideCount)
	intCurrentSlide++;
else
	intCurrentSlide = 0;

if(currentContainer == sprContainer2)
	currentContainer = sprContainer1;
else
	currentContainer = sprContainer2;

currentContainer.alpha = 0;
mcSlideHolder.swapChildren(sprContainer2, sprContainer1);

Then we create a new loader for the slide. We add an event listener when it’s loaded and an event listener for the progress of the loading. Next we load the picture with a urlrequest that contains the source path to the current image. And last of all, we show the description of the slide on the lbl_description and update the current number of the slide on lbl_count.

slideLoader = new Loader();
slideLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, fadeSlideIn);
slideLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, showProgress);
slideLoader.load(new URLRequest(xmlSlideshow..image[intCurrentSlide].@src));

mcInfo.lbl_description.text = xmlSlideshow..image[intCurrentSlide].@desc;
mcInfo.lbl_count.text = (intCurrentSlide + 1) + ” / ” + intSlideCount + ” Slides”;

The showProgress function is quite small. It’s just one line that calculates the percentage of the bytes loaded from the current slide and displays it on the lbl_loading

mcInfo.lbl_loading.text = "Loading..." + Math.ceil(e.bytesLoaded * 100 / e.bytesTotal) + "%";

The last function is fadeSlideIn and will be called once the picture is fully loaded. First, we add the loaded slide from the slideLoader to the current container. Then we clear the preloader text. And finally, we fade the current container in with caurinas tweener engine and start the slide timer when the tween is finished. Like this, we’ll have an endless loop, which will switch the slides.

currentContainer.addChild(slideLoader.content);
mcInfo.lbl_loading.text = "";
Tweener.addTween(currentContainer, {alpha:1, time:FADE_TIME, onComplete:function(){ slideTimer.start();} });
}

That was already it. I hope you enjoyed reading the tutorial. Please feel free to ask questions or leave a feedback.

Full code with comments

// import tweener
import caurina.transitions.Tweener;

// delay between slides
const TIMER_DELAY:int = 5000;
// fade time between slides
const FADE_TIME:int =	1;

// reference to the current slider container
var currentContainer:Sprite;
// index of the current slide
var intCurrentSlide:int = -1;
// total slides
var intSlideCount:int;
// timer for switching slides
var slideTimer:Timer;
// slides holder
var sprContainer1:Sprite;
var sprContainer2:Sprite;
// slides loader
var slideLoader:Loader;
// url to slideshow xml
var strXMLPath:String = "slideshow-data.xml";
// slideshow xml loader
var xmlLoader:URLLoader;
// slideshow xml
var xmlSlideshow:XML;

function init():void {
	// create new urlloader for xml file
	xmlLoader = new URLLoader();
	// add listener for complete event
	xmlLoader.addEventListener(Event.COMPLETE, onXMLLoadComplete);
	// load xml file
	xmlLoader.load(new URLRequest(strXMLPath));

	// create new timer with delay from constant
	slideTimer = new Timer(TIMER_DELAY);
	// add event listener for timer event
	slideTimer.addEventListener(TimerEvent.TIMER, switchSlide);

	// create 2 container sprite which will hold the slides and
	// add them to the masked movieclip
	sprContainer1 = new Sprite();
	sprContainer2 = new Sprite();
	mcSlideHolder.addChild(sprContainer1);
	mcSlideHolder.addChild(sprContainer2);

	// keep a reference of the container which is currently
	// in the front
	currentContainer = sprContainer2;

}

function onXMLLoadComplete(e:Event):void {
	// create new xml with the received data
	xmlSlideshow = new XML(e.target.data);
	// get total slide count
	intSlideCount = xmlSlideshow..image.length();
	// switch the first slide without a delay
	switchSlide(null);
}

function fadeSlideIn(e:Event):void {
	// add loaded slide from slide loader to the
	// current container
	currentContainer.addChild(slideLoader.content);
	// clear preloader text
	mcInfo.lbl_loading.text = "";
	// fade the current container in and start the slide timer
	// when the tween is finished
	Tweener.addTween(currentContainer, {alpha:1, time:FADE_TIME, onComplete:function() { slideTimer.start(); }});
}

function switchSlide(e:Event):void {
	// check, if the timer is running (needed for the
	// very first switch of the slide)
	if(slideTimer.running)
		slideTimer.stop();

	// check if we have any slides left and increment
	// current slide index
	if(intCurrentSlide + 1 < intSlideCount)
		intCurrentSlide++;
	// if not, start slideshow from beginning
	else
		intCurrentSlide = 0;

	// check which container is currently in the front and
	// assign currentContainer to the one that's in the back with
	// the old slide
	if(currentContainer == sprContainer2)
		currentContainer = sprContainer1;
	else
		currentContainer = sprContainer2;

	// hide the old slide
	currentContainer.alpha = 0;
	// bring the old slide to the front
	mcSlideHolder.swapChildren(sprContainer2, sprContainer1);

	// create a new loader for the slide
	slideLoader = new Loader();
	// add event listener when slide is loaded
	slideLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, fadeSlideIn);
	// add event listener for the progress
	slideLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, showProgress);
	// load the next slide
	slideLoader.load(new URLRequest(xmlSlideshow..image[intCurrentSlide].@src));

	// show description of the next slide
	mcInfo.lbl_description.text = xmlSlideshow..image[intCurrentSlide].@desc;
	// show current slide and total slides
	mcInfo.lbl_count.text = (intCurrentSlide + 1) + ” / ” + intSlideCount + ” Slides”;
}

function showProgress(e:ProgressEvent):void {
	// show percentage of the bytes loaded from the current slide
	mcInfo.lbl_loading.text = “Loading…” + Math.ceil(e.bytesLoaded * 100 / e.bytesTotal) + “%”;
}

// init slideshow
init();

Share/Save/Bookmark

, , , , , , ,

This post was written by:

Rafael Nuenlist - who has written 6 posts on The Tech Labs.

Rafael Nünlist is currently working at orange8 as a Richmedia Developer. He will complete his apprenticeship with a swiss federal vocational diploma in information technology this summer. His strengths are Flash, Flex, Actionscript, Php/MySQL and AIR. He is also a member of the dreaminginflash team.

35 Comments For This Post

  1. Andy Says:

    So the only .as file I need is the Tweener?

  2. Chris Says:

    Getting this error:

    “Error with autoFormat near line:intCurrentSlide = 0;

  3. Rafael Nünlist Says:

    @Andy: No, the Tweener class will import all the necessary ones. Don’t delete any of the files if you want to stay on the save side.

    @Chris: Remove the comment on the line #85

    83. if(intCurrentSlide + 1 < intSlideCount)
    84. intCurrentSlide++;
    85. // REMOVE THIS ONE! if not, start slideshow from beginning
    86. else
    87. intCurrentSlide = 0;

  4. mike Says:

    I’m having issues using the caurina classes. I tried adding them as a document class to the movie, linking to the transitions folder through as3 preferences, taking them out of the folders and changing the package names, etc., and of course using it the way it expanded. can you give more details on how to use them?

    thanks.

  5. Rafael Nünlist Says:

    @mike: Your problem isn’t related with the slideshow. You can’t set the Tweener engine as a document class. I think, this should help you out:
    http://www.adobe.com/devnet/flash/quickstart/external_files_as3/

  6. mike Says:

    the problem turned out to be a corrupted program. once I re-installed flash, all connections began to work. I couldn’t connect to any external actionscripts it turned out. all’s well! thanks for your prompt reply and excellent tutorial!

  7. Aloysio Says:

    Hi Rafael! First I want to say thats you do a good work. Congrats. Well.. when slides begin and it will change to next image I see all images loaded when it changes. Do you know what I need to do to fix it?

    Thanks!

  8. Rafael Nünlist Says:

    Hey Aloysio

    Thanks for your feedback. Did you made any changes to the code? The example ( http://www.thetechlabs.com/tutorials/files/flash/rnunlist/slideshow/slideshow.html ) should be working fine.

    Greetings

  9. Tom Says:

    Thanks for sharing your excellent code and also amazed by your good quality pictures. Wondering how can I enable mouse function, for example, when double-click any image, it would load a corresponding website as defined in the xml file. Also wondering how can I add some button functions, for example, for your 5 pictures, when click button#1, the movie would stop at image#1, etc., and you can also pause/continue to auto play the movie. Thanks a lot in advance.

  10. Aloysio Says:

    Hey, No.. i’m not change the code.I note that when slides begin I see the firs image that is a Bee, the next is a Mouse, but when it changes I see the previous image that is Bee and it to the nexts images, I only see the previous images when the slides load new image! Understand?

    Sorry my bad english! :D

  11. Aloysio Says:

    I note that when holder swap the image the last image not desapear. I think that when the images changes the last needs to desapear to apear the new loaded image!

  12. Rafael Nünlist Says:

    Hey,

    @ Aloysio
    No, this is actually the right behaviour.
    We have 2 holders. On in the front, and one in the back. Then we load the first slide in the container that’s in the back. Once it’s loaded, we switch the order and bring it to the front and fade it in. Without this, you wouldn’t have a nice fade in effect of your slides. You need to have the two containers in order to do that ;)

    @Tom
    It’s quite simple to implement your functions. Maybe there will be another part of this tutorial that will cover these. Be sure to check back later ;)

    cheers

  13. Tom Says:

    Thanks for your quick response. Can you show me how to enable the mouse? I added the following code, but the HandCursor does not appear.

    import flash.events.MouseEvent;
    currentContainer.buttonMode = true;
    currentContainer.useHandCursor = true;
    currentContainer.mouseChildren = false;
    currentContainer.addEventListener(MouseEvent.DOUBLE_CLICK, gotoWebside);
    Thanks.

  14. Rafael Nünlist Says:

    @ Tom: Easiest way to to that: Create a new button, add a key frame to the “active” frame, draw a rectangle as big as your wished button area. Drag the button on the stage on top of everything. Give it an instance name and add the following to the init() function of the slideshow:

    your_invisible_button.doubleClickEnabled = true;
    your_invisible_button.addEventListener(MouseEvent.DOUBLE_CLICK, function():void {trace(”YO”);navigateToURL(new URLRequest(”http://www.google.com”), “_blank”);});

    Replace your_invisible_button with the instance name of course ;)

    cheers

  15. Tom Says:

    Thank you. The invisible button works.

  16. Jan Says:

    Rafael: Wondering how to avoid xml cache issue. The IE and/or Firefox browser would still show the old images even after the slideshow-data.xml file has been updated.

  17. Rafael Nünlist Says:

    Hey Jan
    Yes, that’s a cache issue. You can easily solve this problem by adding a parameter to the loaded images/xml files.

    Like this:

    var strXMLPath:String = “slideshow-data.xml?d=” + String(new Date().time);

    And of the image loading:

    slideLoader.load(new URLRequest(xmlSlideshow..image[intCurrentSlide].@src + “?d=” + String(new Date().time)));

    Greetings

  18. Jan Says:

    Thank you. Following above suggestion to resolve the cache issue, I got the following error message:
    Error #2044: Unhandled ioError:. text=Error #2032: Stream Error. URL: file:///D|/SlideShow/slideshow-data.xml?d=1219846606983
    at slideshow_fla::MainTimeline/init()
    at slideshow_fla::MainTimeline/frame1()
    Wondering if you have any idea. Regards.

  19. Rafael Nünlist Says:

    Hey Jan

    Try putting your files online and request them from your browser. Like this, it should work just fine.
    For developing, you don’t have to use the caching ;)

    greetings
    Rafael

  20. Aloysio Chagas Says:

    Hello Rafael. I’m back. Well, i take two printscreen to show you what I say times ago. If you look to these images you will see the transitions.

    http://img144.imageshack.us/my.php?image=slideshowui9.jpg
    http://img262.imageshack.us/my.php?image=slideshow2sj5.jpg

    When I load all images and it start again I see all images in background.
    You know how do I fix it? =)

    Thanks a lot! :)

  21. alex Says:

    I added a resize image to the fadeSlideIn function but the image in the background stays so yo see 2 images one on top of the other. how I can send the background image alpha to 0? by the way nice component
    ty

  22. Rusty Says:

    Rafael, thanks for posting your code, this looks GREAT!! However; I’ve implemented the code and left the browser open and went to lunch, when I returned FF had crashed… didn’t think much of it at the time but did investigate further… it seems that I’m getting a memory and/or cpu leak from the slideshow.

    I have no idea if it’s your code causing the memory leak or the tweener class. I have moved the slideshow to it’s own fla and indeed it is sucking memory/cpu at a constant rate. I don’t know if it’s holding onto the images, the tweens or both….. I’m stumped so just figured I’d ask if anyone else had run into this and if a solution had been found.

    Any ideas of how to remedy this?

    Thanks,

    rusty

  23. Brian Says:

    Rafael,

    Great code! Is there a way to have it unload the images after transition? Firefox and IE processes are increasing the longer the slideshow is viewed. Anyone else have this issue as well?

    Thanks,

    Brian

  24. Jarne Says:

    Hi Rafael, thanks for the code.
    But I’m having one major problem with it: after a while, it begins to lag. It has to do something with the ‘addchild’ I think.
    It must remove the previous images after the fade in of the new image is complete… but how? Any help would be greatly appreciated!

    Cheers.

  25. Rafael Nünlist Says:

    Hey guys

    There seem to be a memory leak in the slideshow. This will be fixed in the next part of the tutorial which will come very soon.

    Greetings
    Rafael

  26. r Says:

    yeah..

    this slide show has a memory leak.

    any thoughts on how to troubleshoot it? i’ve spent 6 hours trying to fix it and nothing is working. has to be the use of the loader?

  27. Carlos Pinho Says:

    Hi,

    The next part of the tutorial will have the solution for the memory leak. It will be published within the next week. So stay tuned…

  28. Joe Says:

    If you change the images so they are not all the same size, it breaks the slideshow. Once it cycles through the images once, then they start to overlap and two or three images appear at once.

    I am assuming this is because the code does not removeChild from the currentContainer? So the images just keep getting attached, is that correct? I am no AS3 genius, so I could be wrong about the problem, but I do know that it is happening.

    Could you email me if you come up with a solution? The email for this comment is the correct one.

    Thanks

  29. Rafael Nünlist Says:

    Hey Joe

    Yes, that’s right. But this problem will be fixed in the next part of the tutorial.

    Or you can add this line on top of the fadeSlideIn() function:

    while(currentContainer.numChildren){currentContainer.removeChildAt(0);}

    Greetings
    Rafael

  30. alessandro Says:

    Dear Rafael thanks for this excellent tutorial. Please when you will workout the second part, can you take a look at the problem of previous images appearing below, as shown here:

    http://img144.imageshack.us/my.php?image=slideshowui9.jpg
    http://img262.imageshack.us/my.php?image=slideshow2sj5.jpg

    thank you very much !

  31. alessandro Says:

    ok I figured out myself: just add the following instruction at the beginning of the fadeSlideIn function, like this:

    function fadeSlideIn(e:Event):void {
    if (currentContainer.numChildren>0) currentContainer.removeChildAt(0);

    Didn’t test much more, so I can’t be sure 100% but after this modification I’m not having anymore memory leaks …

  32. JNigon Says:

    Nice program.

    I’m new to flash and AS3, so I’m probably missing something…Where can I resize the show width and height - preferably to full-screen?

    I’ve tried modifying the included .html file - no luck.

    Thanks!

  33. Lydian Says:

    Hey guys,

    I’ve created an advanced XML news slider. Check the following link. http://www.flashden.net/item/xml-driven-news-slide-show/20094/?ref=cpinho

  34. Renato Says:

    Hi there,

    I tried to use Alessandro´s idea to solve the memory leak issue, but continues the same thing here.

    Any other ideas?

    PS: Gongratz for the nice tutorial Rafael!

  35. sonic22 Says:

    Hi, i’m trying to add a Zoom FX to each image after the fade in, in the “Stealth Time” while the image is shown, i need to add a zoom FX, and after that the fadeIn from the next image (wich is done in the tutorial), could you help me a little??? i’m new in AS3 and i could’n reach it yet.

    Thks.

3 Trackbacks For This Post

  1. Tecinfor » Blog Archive » Criando slideshow com xml em AS3 Says:

    [...] hoje lendo meus rss vi um tutorial muito intereçante sobre flash as3 criando um slideshow com xml com um visual muito fixe. Este tutorial é do site The Tech Labs. ver tutorial [...]

  2. Flash Tutorials | 18 AS3 Image Gallery Tutorials Roundup | Lemlinh.com Says:

    [...] Create a AS3 Slideshow with XML [...]

  3. Extending the AS3/Flash9 Slideshow with XML | The Tech Labs Says:

    [...] Those would be forwarding and rewinding slides, play and pause the slideshow and linkable slides. If you haven’t read the first part tutorial yet, you should do it before continue. You can read it here. [...]

Leave a Reply