Accessibility

Table of Contents

Creating a preloader in Flash

Exploring the Timeline

Let me start with a news flash for all you developers out there. The Timeline is not your enemy. The Timeline is your friend. The Timeline is your ally. Use the Timeline.

Wait, the Timeline?

Developers are taught that attaching artwork to the Stage dynamically is better because you can keep the Timeline organized. This concept is sound on paper. In practice, however, it's not as useful as you would think.

In this case, I'm going to put my preloader smack dab in the center of the Stage. Why? Because it saves me time and I don't have to calculate the center of the display area. I don't have to write x = width * stageWidth/2 + someOffset or whatever. Flash has done all the math for me, so that I (or another designer) can focus on positioning the preloader right where I want it.

My preloader is now centered on the Stage, and I've updated the Timeline for the preloader with frame labels (see Figure 1).

Timeline of the preloader including frame labels for each section

Figure 1. Timeline of the preloader including frame labels for each section

Oh dear, first the Timeline; now frame labels? Why would I ever do such a thing?!

Frame labels let me space out the animations. This saves me time because I don't need to keep notes that the animation first appears on Frame 2 and then begins to disappear on Frame 37. I know those activities occur at the frames labeled "IN" and "OUT."

By leveraging the Timeline for animation, artwork, and placement, I've freed myself of all the annoying (albeit simple) quirks of displaying the preloader on the Stage. Further, I've empowered designers to reskin the artwork easily. Do you want to add 10 frames to the "IN" animation? No problem. Do you need to change the preloader from green to purple? Sure, why not? Can you make the preloader look like a wine glass that fills up as the site loads? Can do.

In other words, the Timeline offers flexibility to modify the look and feel of a project without changing the fundamental purpose of the clip itself—to preload content.

Step-by-step overview of the preloader timeline

My preloader must be designed to accommodate many different variations if it's to be easily reused. Here's the order of operations:

  1. When I'm ready to start loading, I'll tell the preloader timeline to play "IN."
  2. Once the preloader is animated in, I'll assume that the movie clip named progress_mc is on the Stage.
  3. As the loading process progresses, I'll calculate the current percent loaded and play progress_mc to a corresponding frame.
  4. The moment progress_mc has reached the end of its timeline (which correlates to 100% loaded), I'll tell the preloader timeline to play "OUT."
  5. At the time that the preloader finishes its "OUT" animation, the site, app, whatever will be alerted that the preloader is finished. The preloader is then reset for reuse later in the project.

Pretty straightforward, right? Except at this point, you may be wondering how to tell when the "IN" and "OUT" animations have resolved. In the next part of this article, we'll take a look at how that works.

Events, listeners, event dispatching, and event hooks

ActionScript 3 is centered around the concept of event dispatching. If you have previous experience working with ActionScript 1.0 or 2.0, you might already know a little bit about this process without even realizing it. Have you ever written code like this?

var mouseListener = new Object();
mouseListener.onMouseDown = function() {
  trace("The mouse button is down.");
};
Mouse.addListener(mouseListener);

In the code above, the mouseListener object is listening for an event (onMouseDown) from the Mouse class. When that event occurs—which we know happens when the user presses the mouse button down—Mouse will dispatch an event, which it calls onMouseDown. Anything listening for that event—in this case, mouseListener—will fire its corresponding onMouseDown().

The beauty of event dispatching is that multiple objects can listen for the same event and react differently as the event occurs. The following example illustrates how two listeners can respond to the same event:

var mouseListener1 = new Object();
var mouseListener2 = new Object();
mouseListener1.onMouseDown = function() {
  trace("the mouse button is down.");
};
mouseListener2.onMouseDown = function() {
  trace("1+1=" + (1+1));
};
Mouse.addListener(mouseListener1);
Mouse.addListener(mouseListener2);

Now Mouse has two listeners. Each is listening for the same event, but doing something different when the event occurs. In the example above, both listeners are tracing messages to the Output panel, but there's no reason mouseListener1 couldn't do one thing while mouseListener2 does something wildly different.

When you get into object-oriented programming, specifically building classes, this is really great because classes can handle the same events independent from one another without "knowing" what the other classes are doing.

Wait, I still don't get it

Let's back away from code for a second. Pretend for a second that your code is a fast-food restaurant (The ActionScript Café), the user (customer) is a patron, and s/he is hungry (mmm, that smells good).

The customer would like to order something. Now there are two ways your restaurant can go from here:

  • Scenario 1: The customer tells a waiter what he/she wants. The waiter or the user then tells the cook. Either the waiter, the customer, or the cook. And on and on. On top of not being particularly efficient, there can be lots of confusion. Who's telling whom what to do?
  • Scenario 2: The customer pushes a button on a touch screen (sorry waiter, you're out of a job). The cashier and cook are alerted. The cook knows how to cook the food, the cashier knows how to handle the cash register. The cook doesn't care about the money; the cook just assumes that the customer is going to pay for the food. The cashier doesn't care about the food; if there's a problem with the food, there's no way it's the cashier's fault.

In programmer-speak, Scenario 1 is the old-fashioned programming methodology you're used to. Bugs are difficult to squash because it's hard to tell keep track of what's happening at any point.

Scenario 2 is much more ideal. If there's a problem with the food, you need to look to fix the Cook class. If there's a problem with the cash flow, it's in the Cashier class. If there's a problem with both, maybe it with the TouchScreen class. Any way you slice it, the code is explicitly more organized and thus easier to manage.

Event handling in ActionScript 3

Let's talk about how events come into play in ActionScript 3.0—and, more specifically, in regards to building this preloader. In ActionScript 3 (and even ActionScript 2), you can define your own events. Furthermore, movie clips extend Event Dispatcher, meaning that movie clips can dispatch events in much the same way that the Mouse example above does.

Why is that strategy useful? I'll show you. Let's use the preloader as an example. If you take a look back at Figure 1, you'll notice there's code on the Timeline at the "IN_IDLE" frame label:

import com.bigspaceship.events.AnimationEvent;
dispatchEvent(new AnimationEvent(AnimationEvent.ANIMATE_IN));
stop();

The import statement grabs an external class (I'll cover that part in a minute) for use in the Timeline. In this case, it's my custom event, AnimationEvent. I'm going to dispatch AnimationEvent.ANIMATE_IN. That event is a simple string. Similar to knowing that the mouse is down by virtue of the occurrence of an onMouseDown event in ActionScript 1.0, my listeners will wait for AnimationEvent.ANIMATE_IN and know that the Timeline has finished animating the section with the "IN" frame label.

The code is very similar for the "OUT_IDLE" frame label:

import com.bigspaceship.events.AnimationEvent;
dispatchEvent(new AnimationEvent(AnimationEvent.ANIMATE_OUT));
stop();

By using dispatchEvent, I know when the Timeline has resolved the "OUT" animation. I call these event hooks. While "IN" and "OUT" are animating, my code simply waits and listens. Once I've reached an event hook, I can program the logic to proceed with the preloading process.

For more information about event handling, check out Trevor McCauley's article, Introduction to event handling in ActionScript 3.