Articles Archive
Articles Search
Director Wiki
 

Creating small-footprint transitions

March 16, 2001
by Peter Sylwester

[Editor's Note: Welcome to the first installment of FlashBrain, our bi-weekly question and answer column covering Flash topics. Send your questions to Peter Sylwester at flashbrain / at / director-online.com! -DP]

Dear FlashBrain,

As my site interface loads, I'd like to have the components move onto the Stage one by one. When I create these tweens, my base timeline becomes a mess, but when I embed the tweens into movie clips, I can't position the instances because the first frame contents of the movie clip are positioned offstage. Is there a better way to do this?

Eamon

Dear Eamon,

I know what you mean -- you want to try something cool, but with all the frames, layers and movie clips you don't want to make a mess of things in the process.

Essentially, all we need to do is move things from some point A to a destination point B. It's also convenient to have everything already at point B while we're in the file doing the authoring -- that way, things look the way they're supposed to while we're positioning them. First, let's focus on doing the routine with one object, and then we'll see about applying the same to anything else we may put on the Stage.

What we'll do is place the instance on the Stage, set an action to toss the object offstage using the load clip event and then reel it back using the enterFrame event. We'll have to establish some parameters first, though, like how far and which way to toss it, and how quickly to reel it back.

Since we're going to position the instance where we want it on the Stage, we can get the destination parameters by accessing the position properties. For the purpose of this example, let's simplify things by just moving along the vertical axis (therefore, the _y property will suffice). Next, we need to determine a distance for offsetting the clip, and then apply that measure to the position property, effectively "tossing" the object off of the Stage:

onClipEvent (load) {destination = _y; offset = 100; _y += offset;}

We could reel the object back in a variety of ways. A simple solution might be to decrement the offset value and constantly reapply it to _y until the destination is reached (offset == 0). A more elegant solution would be ease the object in by continuously splitting the difference between _y and the destination. This not only has a more tween-like playback, but also retains our offset value if we are ever to move things offstage again.

We will require a divisor, ease, for splitting the difference (which will thus determine the speed of the transition), and we will need a method for determining when the destination has been reached so that we can "turn off" the action. With this method, since the difference will never actually reach 0, we'll round off the _y position and the destination value, then compare the two integers. When the values are close enough, we will plant the object at the actual destination value and then flip a boolean, active, to stop the routine:

onClipEvent (load) {

    destination = _y;
    offset =
100;
    _y += offset;
    factor =
2;
    active = true;

}

onClipEvent (enterFrame) {

    if (active) {
        if (Math.round (destination) <> Math.round (_y)) {
            _y -= (_y - destination) / factor;
        } else {
            _y = destination;
            active = false;
        }
    }

}

Click on the button to replay the animation. This movie requires the Flash 5 Player.

That may seem easy enough, but how could we best apply this routine to multiple objects, and how could we do so sequentially?

Since the other instances already possess their respective destinations, we could apply the first step to each instance on the Stage. This is a little bit of work, but gives us the opportunity to variate the direction of travel, and perhaps customize other behaviors if we ever embellish the routine.

onClipEvent (load) {destination = _y; offset = 100; _y += offset;}

We will make the rest of the routine reusable by leaving it right where it is, but just find a way to cycle through the objects needing attention. The _root timeline is actually an array of object instances. This array is sequenced just as the objects are layered (the topmost object is first, and so on) but also includes an initial object refering to the movie version. To distill the objects and simplify accessing the array, we will use the load event to write a new array into the sentry movie clip that possesses the transition routine:

collective = new Array();
for (i in _root) {collective.push ( i );}
collective.shift ();
soldier =
0;
_root.ease =
2;

The for...in loop collects the instance names available within the _root array. The shift method removes the first element of the array (the $version property), leaving us with just the object instances. Finally, the new soldier variable will be our index value to sequence through the array. This sentry movie clip has been arranged to the top, so we can expect it to be the first item moved to the Stage. Note the modification made to the ease variable (we will now store this globally to give the other objects more convenient access).

The rest of the routine works much the same way, with the exception being that the actual movement is applied within a with wrapper which identifies the active array element as the target. Since these actions thus become localized to that target object, note how the active boolean has been given an absolute address (for much the same reason the ease value was stored globally). As each object reaches its destination, soldier increments and the whole routine starts anew (at least until the collective array is exhausted).

onClipEvent (enterFrame) {

    if (active) {
        with (_root[collective[soldier]]) {
            if (Math.round (destination) <> Math.round (_y)) {
                _y -= (_y - destination) / _root.ease;
            } else {
                _y = destination;
                _root.sentry.active = false;
            }
         }
    } else if (soldier < collective.length - 1) {
         soldier ++;
         active = true;
    }

}

Click on any button to replay the animation. This movie requires the Flash 5 Player.

All this within a single keyframe! You must admit that this routine is much simpler than a ton of layers, frames, and tweens (not to mention that all you need to do is place the movie clips in their final positions). Also, with slight modifications, randomness and variability could have the objects arrive along different axes and from different directions. With a bit more elaboration, they could even swoop in along a curve. But, that's another question for another time.

A sample Flash 5 document is available for download in Macintosh or Windows format.

Peter has produced electronic imagery, design, and illustration for advertising firms and interactive media houses since completing studies at the Rhode Island School of Design. As a freelance multimedia developer, Peter latched onto Macromedia Flash before its initial release in 1997. Peter is a contributing author and technical editor to several current multimedia books and Macromedia's online technical resources. Peter has designed, animated, and programmed several high-profile projects using Flash exclusively including his own ptrdo.com. He currently works as an independent multimedia engineer and teacher in Portland, Oregon.

Copyright 1997-2024, Director Online. Article content copyright by respective authors.