Written by: Devon Wolfgang / www.onebyonedesign.com
Time: 35 minutes
Difficulty Level: advanced
Requirements: Flash mx 2004 or higher
PREFATORY NOTE:

I do not profess to be a writer of the world's cleanest most professional actionscript. Oftentimes, I don't even know what I'm doing, yet it all seems to work out in the end. So, for those who actually know actionscript, please bear with me and try not to cringe too much. In fact, although I'm writing a tutorial on features found only in Flash MX 2004, all my actionscript examples will be presented in AS 1.0. So, sue me.

INTRODUCTION:
While indulging in my favorite pastime of surfing the internet, I came acrosss a couple forum threads which hinted at some undocumented easing features of the latest greatest version of Flash. As hard as I searched, though, I could find no tutorials explaining how to use these features. Perturbed, but undaunted, I dug into the classes folder of my MX 2004 directory and, putting my feeble knowledge of actionscript to use figured it out for myself. To spare others a similar pain in the posterior, I'm documenting my findings here, in the hopes that somebody might find this knowledge useful.

TUTORIAL PROPER:
I. The Tween Class
Flash now supports a shiny new class called Tween which allows for some quick and cool Robert Penner style movie clip easing. In its bare bones, the new class constructor looks like this:
someTweenID = new mx.transitions.Tween(object, property, function, begin, end, duration, useSeconds)
where:
object = reference name of the movie clip you wish to tween
property = a string value of the property you wish to tween
function = name of the easing class to use (more on this to come)
begin = number of above property you'd like to start with
end = number of above property you'd like to end with
duration = number frames or seconds the tween should last
useSeconds = boolean indicating whether the above duration is in frames (false) or seconds (true). If not included, the default is false

That's all good and well, but let's take a look at what types of easing functions (read classes) are available to plug into the "function" slot.

II. The Easing Class
MX 2004 supports a total of 16 different kinds of easing (in reality, there are 19, but since 4 are identical, we'll just call it 16). Broadly speaking, there are 5 categories of easing, each of which support 3 types of easing and finally, there is a 6th category of easing (which, ironically enough, is no easing at all) that supports only 1 kind of easing (that is, none).
Specifically speaking, the 6 categories are:

Strong
Back
Elastic
Regular
Bounce
None

and the 4 types of easing are:

easeIn
easeOut
easeInOut
easeNone

The None and easeNone only work with eachother, so I'll ignore those for the time being. The entire easing function written out looks like this:

mx.transitions.easing.Bounce.easeOut

It is this unruly string of words which is plugged into the "function" placeholder of the Tween class constructor.

III. Putting it Together
So, now that we have all the key ingredients, let's take a look at how they are put together. Assume for a moment that I have a movie clip with an instance name of "ball_mc" I want to tween from an x position of 20 to an x position of 380 in just half a second with a nice little bounce at the end. I now know my constructor looks like this:

ballTween = new mx.transitions.Tween(ball_mc, "_x", mx.transitions.easing.Bounce.easeOut, 20, 380, .5, true);

Holy crap - what a mouthful of AS! Let's make this into a function and break it into smaller code-sized chunks how's about (note: all actionscript presented here is being written in the first frame of the main movie's timeline):

function tweenBall() {
        easeType = mx.transitions.easing.Bounce.easeOut;
        var begin = 20;
        var end = 380;
        var time = .5;
        var mc = ball_mc;
        ballTween = new mx.transitions.Tween(mc, "_x", easeType, begin, end, time, true);
}

Now, that's better. Of course, a function's no good to us unless we actually call it. So, let's make a button named "myButton_btn", and add some script to call the tween function. In the end, we'll have this:

myButton_btn.onRelease = function() {
        tweenBall();
};
function tweenBall() {
        easeType = mx.transitions.easing.Bounce.easeOut;
        var begin = 20;
        var end = 380;
        var time = .5;
        var mc = ball_mc;
        ballTween = new mx.transitions.Tween(mc, "_x", easeType, begin, end, time, true);
}

That appears to be more useful, but what does it give us? Well, this:

Whoa! Not too shabby for just a few lines of pretty simple script. Not very functional yet, though. How about passing on an argument rather than hard coding all of them within the function itself. Let's modify our script just a bit to this:

myButton_btn.onRelease = function() {
        tweenBall(mx.transitions.easing.Bounce.easeOut);
};
function tweenBall(easeType) {
        var begin = 20;
        var end = 380;
        var time = 20;
        var mc = ball_mc;
        ballTween = new mx.transitions.Tween(mc, "_x", easeType, begin, end, time);
}

Note the subtle changes to the time variable. Using a frame rate of 25 fps and a time variable of 20 and no useSeconds boolean, makes a tween nearly one second long rather than the .5 second variable earlier. That fraction of a second aside, however, our new script looks identical to the first. But what, though, if we add 15 more buttons - all with different easing class argurments? Then we get this:

And, voila - all 16 easing classes demonstrated with just a single function. Now, that's more useful.

IV. Additional Tidbits
How much would you pay for all that built in easing goodness? Wait! Before you answer, how about some additional event handlers and and methods at no extra charge. That's right, there's even more goodies Macromedia added but neglected to document. The most useful event handler I've found is onMotionFinished. And for methods, there's yoyo() and rewind().
Say, for example, we want our ball to keep looping/easing back and forth. We simply change our earlier script to:

myButton_btn.onRelease = function() {
        tweenBall(mx.transitions.easing.Bounce.easeOut);
};
function tweenBall(easeType) {
        var begin = 20;
        var end = 380;
        var time = 20;
        var mc = ball_mc;
        ballTween = new mx.transitions.Tween(mc, "_x", easeType, begin, end, time);
        ballTween.onMotionFinished = function() {
                this.yoyo();
        };
}

And we get:

rewind() will simply restore the tweened mc to it's orginal (begin value) state.

CONCLUSION:

All right, I know I left some stuff out. Some on purpose because I didn't find it very useful and some, I'm sure, because I just don't know it. This, though, is certainly enough information to begin using the built in Tween and easing classes with little difficulty.

Please direct any comments, corrections, complaints, or questions to . I may answer them if I happen to get around to it.

d.

POST SCRIPT - some "Real Life" examples:
After receiving a few emails, I've decided to add a couple more examples of the tweening classes in action. After all, who's really going to be just moving balls across the screen? So, here are a couple additional uses that may prove a tad more valuable.

Tabbing menu system (as you may have guessed I really like Bounce.easeOut):

The script:

navText_array = new Array("Home", "About", "Work", "Play", "Contact");
setUpButtons();
stop();
function setUpButtons() {
        var btnCnt = navText_array.length;
        for (i=0; i<btncnt; i++) {>
                var temp = this["tab"+i+"_mc"];
                temp.navText.text = navText_array[i];
                temp.begin = temp._y;
                temp.end = temp._y-100;
                temp.time = 8;
                temp.onRollOver = function() {
                        easeUp(this);
                };
                temp.onRollOut = function() {
                        easeDown(this);
                };
        }
}
function easeUp(what) {
        var tabUp = new mx.transitions.Tween(what, "_y", mx.transitions.easing.Bounce.easeOut, what.begin, what.end, what.time);
}
function easeDown(what) {
        var begin = what._y;
        var tabDown = new mx.transitions.Tween(what, "_y", mx.transitions.easing.Strong.easeIn, begin, what.begin, what.time);
}

Site template:

Hereyou can see a website template I began work on, but quickly lost interest in. Regardless of whether the design is any good or not, it illustrates how properties other than _x and _y values (such as _alpha and scale) can be tweened, as well as how to tween multiple properties of a single object at the same time.

The script:

frame 1 (Loading Frame)

attachmovie("preLoadSymbol", "pls", 99, {_x:325, _y:225});
loadTheBitch();
stop();
function loadTheBitch() {
        createEmptyMovieClip("loader_mc", 666);
        loader_mc.onEnterFrame = function() {
                var done = this._parent.getBytesLoaded();
                var total = this._parent.getBytesTotal();
                pls.percentage.text = Math.round(done/total*100);
                if (done == total) {
                        pls.percentage.text = "";
                        fadePls();
                        this.removeMovieClip();
                }
        };
}
function fadePls() {
        var plsTween = new mx.transitions.Tween(pls, "_alpha", mx.transitions.easing.Strong.easeOut, 100, 0, 1, true);
        plsTween.onMotionFinished = function() {
                pls.removeMovieClip();
                nextFrame();
        };
}

frame 2 (Main Frame)

layOut_mc._xscale = 20;
layOut_mc._yscale = 10;
menu_mc._alpha = 0;
stop();
attachmovie("proceed", "proceed", 99, {_x:325, _y:225});
proceed.onRelease = function() {
        this.enabled = false;
        expandLayOut();
};
function expandLayOut() {
        var loTween_x = new mx.transitions.Tween(layOut_mc, "_xscale", mx.transitions.easing.Bounce.easeOut, 20, 100, 2, true);
        var loTween_y = new mx.transitions.Tween(layOut_mc, "_yscale", mx.transitions.easing.Bounce.easeOut, 10, 100, 2, true);
        var proceedTween = new mx.transitions.Tween(proceed, "_alpha", mx.transitions.easing.Strong.easeOut, 100, 0, 2, true);
        proceedTween.onMotionFinished = function() {
                proceed.removeMovieClip();
        };
        loTween_y.onMotionFinished = function() {
                fadeIn(menu_mc);
        };
}
function fadeIn(object) {
        var fadeTween = new mx.transitions.Tween(object, "_alpha", mx.transitions.easing.Strong.easeIn, 0, 100, 1.5, true);
}