Easing - Page 3
       by Voetsjoeba  |  9 December 2006

In the previous page, we reviewed what we want our easing function to do in three statements. We can write those 3 statements inside the onEnterFrame handler’s body as a single statement like this:

var speed:Number = 2;
ease = function( what:MovieClip , to:Number ){
what.onEnterFrame = function(){
this._x = to( tothis._x ) / speed;
}
}

And there we go ! We have achieved a function that will easy any MovieClip to any point on the x axis, in just these 6 lines of ActionScript ! Excellent, but we have been ignoring something up till now: this onEnterFrame handler has not been told to ever stop, which means it will still be calculating even long after the destination has been ‘reached’.

Theoretically, it can never reach its destination, much like 0.9999999…. will never reach 1. But, computers have limitations in calculating floating point numbers, and therefore so does Flash, and so do screens. At a certain point you’ll end up calculating these insanely small numbers, and moving the MovieClip on the stage by that distance won’t have any effect, because those amounts won’t even add up to a hundredth of an actual pixel to move.

So, we have to build in some kind of a check to see when the MovieClip has very closely neared its destination, and then remove the onEnterFrame handler. That way, the onEnterFrame handler won’t keep calculating values that have no effect anyway. This is important in big projects where CPU load is an issue. Trust me, you do not want an onEnterFrame stalling in the background for every MovieClip you’ve ever eased around.

Therein lies a problem: because the MovieClip will never actually reach its destination, it is pointless to check if it has. What we could do is set some kind of ‘null distance’ that will determine how far the MovieClip needs to be away from its destination to be considered ‘there’. This method works well if you stick to a certain speed and ease all MovieClips using that speed, but unfortunately it does not make for a good general solution. This is because the null distance depends on the speed of the easing. The slower the speed, the slower the object will be moving towards its destination, and the finer the dividing of the distances. The finer the dividing of the distances, the more MovieClip positioning limitations will take effect. This makes the null distance method fairly unreliable.

A better solution is to keep track of the previous positions of the MovieClip, and compare them to each other. There will always be a certain point where the difference between the distances will be so small that Flash won’t bother to update the MovieClip to that position because moving a MovieClip over such a small distance is either meaningless or simply impossible. When that happens, two consequent positions will be the same, indicating that Flash has reached its limitation of MovieClip positioning and that further calculations will have no effect anymore. This is when we want our loop to end.

Fortunately, performing this check is easy. All we need is an extra variable that holds the previous position. When we move the MovieClip to its new position, we check if this new position is the same as the last one. If it is, then we have reached our limit and we can safely kill the loop because further calculations are pointless as they will all result in the same position. And to ensure maximum positioning accuracy, we can set our MovieClip to its exact destination once this happens. Just to be sure.

With that in mind, we can redefine our easing function like this:

var speed:Number = 2;
ease = function( what:MovieClip , to:Number ){
var previousPosition:Number = what._x;
what.onEnterFrame = function(){
this._x = to( tothis._x ) / speed;
if( this._x == previousPosition ){
this._x = to;
delete this.onEnterFrame;
}
previousPosition = this._x;
}
}

Onwards to the next page!
 

1 | 2 | 3 | 4 | 5 | 6




SUPPORTERS:

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