Accessibility

Flash Article

 

Building Preloaders and Progress Bars in Macromedia Flash

Joshua Hirsch

Minister of Technology
www.bigspaceship.com

One of the unique features of web content built with Macromedia Flash is the ability to control when and how the content loads. When loading a heavy HTML page, the user is usually stuck looking at a blank window until the content starts appearing. Flash allows for the creation of animated preloaders, which give the user precise information about the progress of the loading process.

A simple rectangular progress bar or percentage indicator will do the job, but why stop there? A preloader should be given just as much love and consideration as the rest of the site content, especially on a site that is trying to evoke a mood, or create an immersive experience. If a preloader is engaging enough, the user won't mind waiting for content, and the time it takes to load will seem shorter.

The preloader is the first element someone will see when visiting your site. You can make a good first impression by welcoming your visitors with a snappy preloader.

Requirements

To complete this tutorial you will need to install the following software and files:

Macromedia Flash MX 2004

Tutorials and sample files:

Prerequisite knowledge

Basic knowledge of ActionScript 2.0

What to Think About When Designing Your Preloader

As I mentioned above, the Flash preloader does not always have to be a rectangular bar moving from left to right. However, there are some guidelines that you need to keep in mind when creating your custom preloader.

Progress Animation

The progress animation is the meat of the preloader. This animation needs to communicate graphically the progress of the load by indicating the following information:

To be truly effective, the animation needs to have a clear beginning and an end. For example, if your animation is a shape that gradually changes color from red to green as the file loads, the user won't know that they are waiting for green or how far from red they have come. Anyone should be able to know what the load status is at any point in the preloader’s progress animation. There are ways to achieve this without restricting yourself to the standard rectangular bar.

Here are some examples of sites that Big Spaceship has built, which feature interesting preloaders:

If you are especially tied to something like the color change idea, or some looping animation, then you should include a text field that displays the percentage of the load that is complete. I've included an example that features both an animation and a percentage indicator later in this article.

File Size

Macromedia Flash Player will not display the contents of a frame until everything on that frame is completely loaded. If there is a movie clip on a frame of the main Timeline, the frame will not display until that entire clip, and every other clip on that frame, has loaded. This is very important to keep in mind when creating your preloader and placing it in your file. The preloader needs to be the first item that appears in the Timeline, and it needs to be alone on the Timeline for at least one frame to ensure that it will load completely and be ready to display before other content starts loading.

It is also important to keep the byte size of your preloader as low as possible. Otherwise, the user will be looking at a blank screen before the preloader loads. When testing the movie in Flash, use the Bandwidth Profiler to check the byte size of each frame of the main Timeline to make sure that the frame where the preloading will occur is light.

This file size rule does not necessarily apply to preloaders that are used within a site to load additional content. The example code included with this article creates a preloader that can be used for the initial load of the site, and then easily reused to load additional content. On sites where the preloader idea just couldn’t be made small enough, I use a very simple loader for the initial load, and then the more elaborate version later in the site to load additional content.

Putting Theory into Practice: An Example

If you haven't already downloaded the sample files, download and open them now. There is an FLA file containing a preloader movie clip, some "site content," and an ActionSript file defining a class called Preloader.

The Preloader Movie Clip

The preloader movie clip is on the first frame of the main Timeline of the example FLA, and has an instance name of preloader_mc. The first frame of preloader_mc has only a stop() action on it. The animation that reveals the preloader, the in animation, starts on a frame labeled IN. After the in animation, there is a movie clip containing the progress animation with an instance name of progress_mc. This clip can be as long as you want. However, it is important that it contains only the progress animation and has no extra frames at the beginning or end. The preloader code use the _totalframes property of this clip to determine whether the preloader has played all the way through. The out animation begins on the frame labeled OUT.

The Class

Take a look at the Preloader class that extends the existing MovieClip class. The preloader movie clip must be set as a member of this class in the Linkage dialog box accessed from the library.

    function Preloader(){
        mx.events.EventDispatcher.initialize(this);
    }

The constructor is called when the movie clip appears on the Stage. The only code in the constructor gives this instance the ability to broadcast events to listeners using the EventDispatcher class (for more details see "Creating Events Using the EventDispatcher Class").

    public function startPreload(t:MovieClip){
        target_mc = t;
        this.gotoAndPlay("IN");
    }

The next method definition in the class file, startPreload, is the only public method of the class. The parameter is the movie clip whose load progress this instance is reporting on. The target_mc variable is set to reference the target clip, and the preloader clip is told to play the in animation.

    private function onAnimateIn(){
        this.stop();
        this.onEnterFrame = this.checkLoadProgress;
    }

On the final frame of the in animation, the onAnimateIn method is called from the preloader clip's Timeline. This method stops the animation and starts checking the load progress on every frame.

    private function checkLoadProgress(){
        var bl = target_mc.getBytesLoaded();
        var bt = target_mc.getBytesTotal();

        var pct = bl/bt;

        var cf = progress_mc._currentframe;
        var tf = progress_mc._totalframes;

        var f = Math.ceil(tf * pct);

        if(f > cf){
            progress_mc.play();
        }else{
            progress_mc.stop();
        }

        this.pct_str = (Math.round(cf/tf * 100)).toString();

        if(bt > 20 && bl == bt && cf == tf && progress_mc){
            onPreloadComplete();
        }
    }

The checkLoadProgress method contains the code that tracks the load progress of the target movie clip and updates the preloader movie clip as necessary. This method is called on each frame until the loading is complete.

The first few lines of code get the values for total bytes and loaded bytes of the target movie clip and calculate the percentage that has already loaded.

The next two lines get the current frame and the total number of frames in the progress animation movie clip. I then multiply the total frames by the load percent to find the corresponding frame in the progress animation clip. Because the progress animation is so glorious, I don't want to deprive the user of any part of its beauty. I want to ensure that the animation plays through, nice and smooth, without skipping any frames. So, instead of jumping to the frame I just calculated from the load percentage, I compare this value with the current frame of the progress clip. If the progress clip has outrun the loading progress—if the current frame is beyond the frame that corresponds with the load percentage—I make the clip stop and wait for the load to catch up. If the target frame is beyond the current frame of the clip, I let the progress animation play.

The preloading is complete when the loaded bytes equal the total bytes, and the progress clip has played all the way to the end (the current frame is equal to the total frames). At this point, the onPreloadComplete method is called.

    private function onPreloadComplete(){
        this.onEnterFrame = null;
        this.gotoAndPlay("OUT");
    }

Here the onEnterFrame method is cleared, and the preloader is sent to the out animation. At the end of the out animation, the onAnimateOut method is called from the Timeline.

    private function onAnimateOut(){
        this.stop();
        dispatchEvent({target:this, type:'onPreloaderOut'});
    }

An onPreloaderOut event is broadcast by this method. On the first frame of the main Timeline, the Timeline is added as a listener for events broadcast by the preloader. So when the preloader dispatches the onPreloaderOut event, the onPreloaderOut function on the main Timeline is called, which sends the Timeline to the SITE frame.

Testing

The Simulate Download feature available when testing in the Flash authoring tool is very useful when testing a preloader. You can find this on the View menu when testing a movie. It is a good idea to try Simulate Download at different bandwidth settings, so you can get an idea of how the preloader looks on different types of connections. Use the Bandwidth Profiler to ensure that your preloader clip is small enough, and to compare the actual load progress with the progress reported by your preloader. Sometimes, I throw a gigantic bitmap into the file just to make sure my preloader is working properly.

Although the Simulate Download feature is very useful, it doesn’t duplicate loading something from a remote location. Always be sure to test preloaders by loading the content from a remote server (ideally the same server that the live content will eventually go on) before going live with your content.

Loading Additional Content

If you want to reuse this preloader to load additional content once the user is in the site, all you have to do is make sure the preloader movie clip, or another preloader clip also registered to the Preloader class, is on the Timeline, and call the startLoad method with the parameter being the movie clip that the new movie will be loaded into.

Loading Multiple Files as Part of the Initial Load

For most of the sites that I build, it is necessary to load multiple files as part of the initial site load. This makes things a little bit trickier. The Preloader class could be extended by modifying the checkLoadProgress method so that it can accommodate multiple files.

When checking the load of multiple files, it is not a good idea to get a grand total by adding the result of getBytesTotal and getBytesTotal on all of the clips being loaded. I have noticed that Flash will only load three or four external files at once, and the getBytesTotal method will not return the proper value until a clip has started loading. For example, if you are loading five SWF files at once, and try to get a total bytes value in this way, you will only get the totals for the first three that start loading. As soon as one finishes, another will start loading, making your total value change, which will change the result of the percent loaded calculation. You will end up with an inaccurate loading animation.

Here are a couple of options for showing progress of multiple file loads:

You will have to experiment with these methods and decide which works best for your situation.

About the author

Joshua Hirsch is the Minister of Technology at Big Spaceship, an award-winning creative firm with a focus on entertainment and consumer lifestyle brands. During his time at Big Spaceship, he has developed Flash sites and games for clients, including 20th Century Fox, Dreamworks, Paramount, Miramax, Sony Pictures Entertainment, Warner Brothers, Universal Pictures, Sony Electronics, and Gucci.