Simple Progressive Download Flash Slideshow – Part 1

27 Sep 09

In this 3 Part tutorial we are going to be creating a progressive download flash slideshow. The benefit of progressive download is the slide show will only download one image at a time. Doing so keeps bandwidth down and keeps the slideshow visible.

This is in response a flash slideshow I created last year. It read the XML file and created each slide at the same time. It worked fine locally and with small files, but when placed into production, we noticed it was incredibly slow.

This tutorial will cover a simple XML file, reading XML with ActionScript 3, custom ActionScript 3 events, and a handful of common ActionScript 3 classes and techniques.

Set up

First we start with our file structure:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/slideshow
    /gs
        TweenMax.as (and supporting files)
    /events
        SlideshowEvent.as
    /images
        image-001.jpg
        image-002.jpg
        image-003.jpg
        image-004.jpg
    /xml
        slides.xml
    Slide.as
    Slideshow.as
    SlideshowState.as
    SlideshowLoader.as
    SlideshowLoader.fla
    SlideshowLoader.swf

A closer look at the structure, you can see we have a gs directory. This is for the Greensock TweenMax library. I am a huge fan of Greensock’s TweenMax library. I have found it to be extremely light weight and super fast.

Further we find the custom events file as SlideshowEvent.as. This will allow us to know when the image is loaded so we know when to go to the next image. Next is the images directory and xml directory. Nothing special with these files. A few images to test out with and a xml file to load into the flash file.

In the root of the slideshow directory, we find Slide.as, Slideshow.as, SlideshowState.as, SlideshowLoader.as/fla/swf. We will discuss the role of each of these files as we start going through the tutorial.

Creating the XML

Laying out our XML file is rather simple. It’s just a list of image sources, nothing else. Remember the source is relative from the SWF that is loading the images, not relative to the XML.

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8" ?>
<slides>
    <slide src="./images/image-001.jpg"/>
    <slide src="./images/image-002.jpg"/>
    <slide src="./images/image-003.jpg"/>
    <slide src="./images/image-004.jpg"/>
</slides>

Custom Events

There are a few tutorials out there if you are interested in understanding a bit more of how the flash.events.Event class is built and how events work. I recommend looking at these if you are unfamiliar with bubbling and cancellation of events.

We will add a few constants as events types to be dispatched. This will prevent us from having to keep up with variants in coding styles. Plus if you use an intelligent IDE for ActionScript development, you will get a list of events available.

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
package events
{
    import flash.events.Event;

    public class SlideshowEvent extends Event
    {
        public static const XML_COMPLETE:String = 'xmlComplete';
        public static const IMAGE_LOADED:String = 'imageLoaded';
        public static const IMAGE_FAILED:String = 'imageFailed';
       
        protected var _data:Array;

        public function SlideshowEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false, data:Array = null)
        {
            super(type, bubbles, cancelable);
            this._data = data;
        }

        public function get data():Array
        {
            return this._data;
        }

        override public function clone():Event
        {
            return new SlideshowEvent(type, bubbles, cancelable, this._data);
        }
    }
}

Static States

Just like in the SlideshowEvents.as we used a static constant to prevent us from misspelling or converting cases when doing string comparison, we will do the same for the SlideshowStates.as file. This will hold any states we are wanting to have for the slideshow. Just a few come to mind – initializing, loading, playing, paused, complete. Let’s look at this class.

1
2
3
4
5
6
7
8
9
10
11
package
{
    public class SlideshowState
    {      
        public static const INITIALIZING:String = 'initializing';
        public static const LOADING:String = 'loading';
        public static const PLAYING:String = 'playing';
        public static const PAUSED:String = 'paused';
        public static const COMPLETE:String = 'complete';
    }
}

Now “complete” may sound silly because we typically never want a slideshow to stop, but there if you ever need it, it’s there. That’s it for the short and sweet files. Let’s do some class development working from the inside out, starting with the Slide.as class.

Build a Slide

In Slide.as we need to import our custom slideshow events and a few provided classes from flash to handle the loading of the file These will be explained when we start to use them. We also will extend the Sprite class so we have a display object without the frames the Movieclip class contains. Here’s the stub code of the class.

1
2
3
4
5
6
7
8
9
10
11
12
13
package
{
    import Events.SlideshowEvent;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.net.URLRequest;

    public class Slide extends Sprite
    {
    }
}

The rest of our code will go between the interior braces on lines 11 and 12. We will only need two properties for the slide. I like making most of my properties and methods protected; this way if you need to sterilize input, you have that option. We will also create an empty constructor.

1
2
3
4
5
6
        protected var _loader:Loader;
        protected var _src:String;

        public function Slide()
        {
        }

We don’t need to initialize any properties as they will be initialized just before they are used.

The first method we will need is the loadImage method. This will take the file source as a string and will return void and is the only method that is public. Place this just after the constructor.

1
2
3
4
5
6
7
8
9
        public function loadImage(src:String):void
        {
            this._src = src;

            this._loader = new Loader();
            this._loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
            this._loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
            this._loader.load(new URLRequest(this._src));
        }

It may look like we did a lot here, but it’s really quite simple. On line 3 we assign the source passed to the method to the protected _src property of the Slide. This will be used later on line 8, but we have something else to do first.

On line 4 we initialize the _loader property as a new Loader(). We then add a few event listeners on lines 5,6 and 7. Notice these event listeners are added to the contentLoaderInfo property of the _loader, not directly to the _loader object. If you miss that, you wont get any errors, you just wont see what you are looking for and will probably end up scratching your head for a few minutes.

After the event listeners are added, we need to load the file. We do this with the load method of the _loader object. The load method requires a URLRequest, but we haven’t established one just yet. We do that by creating a new URLRequest and passing the _src property to it directly in the load method. And because parens are worked from the inside out, think back to your order of operations, the URLRequest is created first thus fulfilling the load() requirements.

To finish up this first part of the tutorial we need to create the event listener methods. These methods will be called when the event is dispatched from the _loader object.

The first is the onError method. This method is a one liner, that dispatches one of the custom events we created in the SlideshowEvent.as class. We pass an IOErrorEvent to the method and it returns void.

1
2
3
4
        protected function onError(e:IOErrorEvent):void
        {
            dispatchEvent(new SlideshowEvent(SlideshowEvent.IMAGE_FAILED, true));
        }

You can see the only thing we need to do here is dispatch the IMAGE_FAILED event. I’ve left false as the cancelable parameter as a personal preference. Anytime an error is thrown you never know what’s going to be listening for it later on, so I never feel it’s needed to cancel an error dispatch.

For the last method, onComplete, we need to dispatch the IMAGE_LOADED event and also add the _loader as a child to the Slide object. It’s vary similar to the onError method with the exception that we pass a standard Event versus the IOErrorEvent.

1
2
3
4
5
        protected function onComplete(e:Event):void
        {
            dispatchEvent(new SlideshowEvent(SlideshowEvent.IMAGE_LOADED, true, true));
            addChild(_loader);
        }

You will notice this time we allow the IMAGE_LOADED event to be canceled.

Here is the full class.

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
38
39
40
41
42
package
{
    import Events.SlideshowEvent;

    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.net.URLRequest;

    public class Slide extends Sprite
    {
        protected var _loader:Loader;
        protected var _src:String;

        public function Slide()
        {
        }

        public function loadImage(src:String):void
        {
            this._src = src;

            this._loader = new Loader();
            this._loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
            this._loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
            this._loader.load(new URLRequest(this._src));
        }

        protected function onError(e:IOErrorEvent):void
        {
            dispatchEvent(new SlideshowEvent(SlideshowEvent.IMAGE_FAILED, true, false));
        }

        protected function onComplete(e:Event):void
        {
            dispatchEvent(new SlideshowEvent(SlideshowEvent.IMAGE_LOADED, true, false));
            addChild(_loader);
        }

    }
}

What’s Next

In the next step we will set up the Slideshow.as class. This class will take the XML file and generate Slides for each entry with the class we have just made.

Tags: , , ,

3 Responses to “Simple Progressive Download Flash Slideshow – Part 1”

  1. [...] This post was mentioned on Twitter by Anthony Pipkin. Anthony Pipkin said: w00t!! just finished the first part of the first post on @fusingtheweb http://bit.ly/5Dmaw [...]

  2. BRUCE says:


    Pillspot.org. Canadian Health&Care.No prescription online pharmacy.Special Internet Prices.Best quality drugs. High quality drugs. Order pills online

    Buy:Retin-A.Arimidex.Lumigan.Accutane.Synthroid.Actos.Mega Hoodia.100% Pure Okinawan Coral Calcium.Valtrex.Human Growth Hormone.Petcam (Metacam) Oral Suspension.Prevacid.Zyban.Nexium.Prednisolone.Zovirax….

  3. SHANE says:


    PillSpot.org. Canadian Health&Care.Special Internet Prices.No prescription online pharmacy.Best quality drugs. No prescription drugs. Buy drugs online

    Buy:VPXL.Viagra.Propecia.Cialis Professional.Cialis Super Active+.Viagra Soft Tabs.Cialis Soft Tabs.Tramadol.Viagra Super Active+.Super Active ED Pack.Viagra Super Force.Soma.Viagra Professional.Maxaman.Zithromax.Cialis.Levitra….

Leave a Reply