Easing - Page 6
       by Voetsjoeba  |  9 December 2006

We are almost done with this tutorial. In the previous page, you learned how to avoid overwriting a movie's onEnterFrame handler. In this page you will learn one more trick, and then I will conclude this tutorial with a collection of source files used in the various animations you have seen.

5. Applying Function Chaining
When applying this easing method in various projects, you will find that you will often want to call another function after the easing has ended. For example, you may want to slide open a panel by moving it from one side to the either, and when it has, load your content into it. You donít want your content to already start loading before your MovieClip is in place.

To solve this problem, we can use what I like to call function chaining. More accurately Iíd call it function call chaining, but the former sounds better. The idea is to pass along a function to the easing method that is to be called when the easing has completed. That way, you can say: ease this MovieClip to this position at this speed, and when itís done, call this function.

The way weíll be doing this is by using the Function.apply method. The syntax is as follows:


This will call the function myFunction as a method of thisObject, using the set of parameters as indicated by the argumentsObject array. Notice that this allows for a method to be applied as a method of another object rather than the object that defined it. Consider the following example:

var objectA:Object = new Object();
var objectB:Object = new Object();
objectA.myProperty = "property of A!";
objectB.myProperty = "property of B!";
objectA.theProperty = function(){
trace( this.myProperty );

This will apply the method theProperty as defined by objectA to objectB, even though it is was defined in objectA. This allows for great flexibility in calling functions.

To implement this, the code looks like this:

MovieClip.prototype.easeX = function( to:Number , speed:Number , endF:Function , endO:Object , endP:Array ){
if( what._x != to ){
var _this:MovieClip = this;
var aux:MovieClip = this.createEmptyMovieClip( "aux_easeX" , 1337 );
var previousPosition:Number = this._x;
if( isNaN( speed ) || Number(speed) !== speed || speed <= 1 ) speed = 1.2;
aux.onEnterFrame = function(){
_this._x = to - ( to - _this._x ) / speed;
if( _this._x == previousPosition ){
_this._x = to;
if( endF ) endF.apply( endO , endP );
previousPosition = _this._x;
} else {
if( endF ) endF.apply( endO , endP );

We can now optionally pass three more arguments to our easing method: endF ( for endFunction ) refers to a function that will be applied once the easing is complete. Consistently with endF, we pass along endO ( for endObject ) and endP ( for endParameters ) which are respectively the object that endF will be applied to and the set of parameters that will be sent along with the call. Notice that our else clause has now become useful: if our object is already at its destination, we still want our ending function to be called. Before, that else clause was just doing nothing.

We can now chain functions calls one after the other; for example, we can have a MovieClip ease to a certain position and then back at a different speed:

var startX:Number = myMovieClip._x;
var endX:Number = startX + 500;
myMovieClip.easeX(endX, 1.2, myMovieClip.easeX, myMovieClip, [startX, 1.4]);

Again, notice the flexibility of the Function.apply method: the function we are calling is myMovieClip.easeX, but that doesnít necessarily mean we also want to apply it to myMovieClip, we could also have applied it to any other MovieClip to ease that one instead of myMovieClip. And because myMovieClip.ease isnít defined in myMovieClip but in its prototype object, all the following are equivalent:

myMovieClip.easeX(endX, 1.2, myMovieClip.easeX, myMovieClip, [startX, 1.2]);
myMovieClip.easeX(endX, 1.2, MovieClip.prototype.easeX, myMovieClip, [startX, 1.2]);
myMovieClip.easeX(endX, 1.2, myMovieClip.__proto__.easeX, myMovieClip, [startX, 1.2]);
myMovieClip.easeX(endX, 1.2, myMovieClip.createEmptyMovieClip("randomMC", myMovieClip.getNextHighestDepth()).easeX, myMovieClip, [startX, 1.2]);
myMovieClip.easeX(endX, 1.2, _root.easeX, myMovieClip, [startX, 1.2]);

Again, for a closer understanding why this is, please read Senocular's AS1 OOP tutorial.

We can even have it continuously ease it back and forth:

The code I used the call the easeX prototype function is the following:

var startX:Number = myMovieClip._x;
var endX:Number = startX+500;
chain = function () {
myMovieClip.easeX(endX, 1.2, myMovieClip.easeX, myMovieClip, [startX, 1.4, chain, null, []]);

This to illustrate the power of function chaining. In fact, I donít think I have ever been working on a project where I havenít used this easing method. Itís just everywhere, and the function chaining makes it easy to control the exact behavior of your application, with no guessing work involved.

6. Globalizing the Easing Method to other Properties
As I have mentioned earlier, this method of easing can be used to ease all kinds of properties, including but not limited to the _y, _xscale and _yscale, _width, _height, and even _alpha properties. And this is where the power of the function chaining really comes into play: you can control exactly how and when you want your ActionScripted easing animations to take place.
Download proto.as

In the file proto.as you will find easing methods for the most common properties such as _x, _y, _width, _height and the likes, logically called easeX, easeY, easeWidth, easeHeight, and so on. You can easily use these in your movies by placing proto.as in the same folder as your .fla is in, and then include them:

#include "proto.as"

This will import the prototype method definitions into your movie, allowing you to easily use them without having them clutter up your ActionScript panel. Have a look at the example file example7_proto.fla in the following zip file to see them all in action.
Download All Easing Source Files

This concludes this tutorial. If you have any further questions or if you notice something you think is wrong, please donít hesitate to let us know on the forums.

Peace out,



1 | 2 | 3 | 4 | 5 | 6


kirupa.com's fast and reliable hosting provided by Media Temple.