I am often asked about the Flash banners and interface objects I create and embed into websites. Most of the time, the Flash animations I create don’t really need to be modified all that often and if they do, can be done in the source FLA with a minimal amount of work. However, sometimes you need a little more control over the Flash animation without needing to A.) recompile the SWF, B.) increase the filesize of the SWF, and C.) be a Flash developer (for those of you who will be developing for others). Enter the wonderful world of data-driven Flash animations.

Loading content into a Flash animation from an external source is not a new trick. Developers have been doing it for years. What is different about today’s data-driven Flash objects though, is its ability to import and manipulate the data derived from external XML files (for more info on XML, click here). The information I am providing below is not intended for the timid developer, but should provide enough of a working example that even the most novice developer should be able to create their own data-driven animation.

What we need to make this work is 3 components; the animation container, the data-source, and the content. The animation container is the SWF that will perform some sort of action to the data that is passed to it from the data-source. The data-source is a simple XML file that tells the animation what content needs to be animated. The content is the information passed to the animation container that needs to have some sort of action or effect applied to it. In the example below, we will be making a small banner rotation script.

Step 1: Setup your directory structure
Create a folder somewhere on your computer, we will call it “banners”. Inside that folder, create a sub-folder called “images” and a sub-folder called “source”. Obviously, the banner images are going to be placed into the “images” folder. The “source” folder will contain our source FLA when we are done with our project.

Step 2: Create your data-source (XML File)
Using a text editor (NotePad, Dreamweaver, BBEdit, or VI for you UNIX types), create a file called xmldata.xml. In that XML file, add the following lines:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<images>
  <banner>
    <image>images/banner1.jpg</image>
    <text>This is a description of the image</text>
  </banner>
</images>

The first line tells an interpreter what type of file this is, what character set to use and if this should be treated as a standalone object. I will describe the next parts by using the parent/child relational jargon. If you are not familiar with this, please click the link above to learn about XML prior to reading on. The reason I describe this XML file using the parent/child approach is because Flash uses that same concept when identifying the various pieces of the data-source, also called “Nodes”. The second line opens the “images” parent object, which has a child “banner”. That child “banner” has two children; “image” (the relative path to an image) and “text” (the text that will be displayed in our banner engine). “Image” and “text” are considered siblings since they are both grouped under the same parent. The code above is for one (1) banner to be displayed. I we want more than one banner, we could create another child node (“banner”) under the “images” parent node.

Step 3: Create your animation container
Crack open Flash and create a new ActionScript 2.0 document. I usually set the frame-rate to 30fps because it gives smoother transitions between images. On the main timeline, create and label the following layers: Action, Text, Banner.

Layer Setup

In the first frame of the main timeline, create a dynamic text object in the “Text” layer and name it “text”.

Dynamic Text Object

In the first frame of the “Banner” layer, create a new (empty) MovieClip symbol and name it “image” and place it at coordinates 0,0.

Empty MovieClip Object

Now comes the fun part — ActionScript. In the first frame of the “Action” layer, open up the Actions window and add the following code:

// --------------------------------------------------
// Define and instantiate the XML object
// --------------------------------------------------
xmlData = new XML();
xmlData.ignoreWhite = true;
xmlData.onLoad = loadXML;
xmlData.load("xmldata.xml");

// --------------------------------------------------
// Define variables
// --------------------------------------------------
s = 0;                                                // Global counter variable
duration = 15000;                                    // Duration in milliseconds between slides

// --------------------------------------------------
// loadXML: Load all data from the XML file for use by the script
// --------------------------------------------------
function loadXML(loaded) {
    if (loaded) {
        xmlNode = this.firstChild;                    // This is the parent
        image = [];                                    // The array for the Image paths
        btext = [];                                    // The array for the text
        total = xmlNode.childNodes.length;            // The total number of images
        for (i=0;i<total;i++) {
            image[i] = xmlNode.childNodes[i].childNodes[0].firstChild.nodeValue;
            btext[i] = xmlNode.childNodes[i].childNodes[1].firstChild.nodeValue;
        }
        firstImage();                                // Load the first banner
    } else {
                                                    // No image was found
    }
}

// --------------------------------------------------
// defineContainers: Define and create empty MovieClips (MCs) to be used as containers
// --------------------------------------------------
function defineContainers() {
    for (z=0;z<total;z++) {
        banner.createEmptyMovieClip("sid_"+z,z);        // Load the banner array with empty MCs for containers
    }
}

// --------------------------------------------------
// firstbanner: Display the first banner from the list of stories to start the slideshow
// --------------------------------------------------
function firstImage() {
    defineContainers();                                // Initialize the empty MCs
    banner["sid_"+s].loadMovie(image[s], s);        // Load images into empty MCs
    banner["sid_"+s]._alpha = 0;                    // Set initial transparency
    setInterval(function () {                        // Load next image
        nextImage();
    }, duration, this);
}

// --------------------------------------------------
// nextImage: Display the next banner from the list of stories
// --------------------------------------------------
function nextImage() {
    if (s<(total-1)) {                                // Check to see if the loop needs to start over
        s++;                                        // If not, set initial transparency and load image
        banner["sid_"+s]._alpha = 0;
        banner["sid_"+s].loadMovie(image[s], s);
    } else {
        s = 0;                                        // If so, start over at the beginning
        restart = 1;
        banner["sid_"+s]._alpha = 0;
        banner["sid_"+s].loadMovie(image[s], s);
    }
}

// --------------------------------------------------
// Initialize entire process and start slideshow
// --------------------------------------------------
this.onEnterFrame = function() {                    // Every time the playhead hits this frame, execute these commands
    filesize = banner["sid_"+s].getBytesTotal();        // Get total bytes of image
    loaded = banner["sid_"+s].getBytesLoaded();        // Get loaded bytes of image
    if (loaded != filesize) {                        // If image is not loaded completely, display preloader
        // Insert your preloader here
    } else {                                        // If so, do the following
        text = btext[s];                            // Set the text on the description to the text from the XML file
        if (banner["sid_"+s]._alpha<100) {            // If the transparency of the image is not 100%, increment it by 10
            banner["sid_"+s]._alpha += 10;
        }
        if (s == 0) {                                // Check to see if this is the first image
            if (restart == 1) {                        // If so, has the loop been restarted?
                q = total-1;                        // If so, change all depths back to original and fade image out
                banner["sid_"+q].swapDepths(0);
                if (banner["sid_"+q]._alpha>0) {
                    banner["sid_"+q]._alpha -= 10;
                }
                restart = 0;
            }
        } else if (s>0) {                            // If not, load next image and fade the previous out
            q = s-1;
            if (banner["sid_"+q]._alpha>0) {
                banner["sid_"+q]._alpha -= 10;
            }
        }
    }
};

Step 4: Save, Publish, Test
If all went well, you should be able to save your FLA into the “source” folder, publish the SWF to the main “banners” folder, and then test the SWF.

Good luck and happy flashing!

Source Files and Working Example