Keyframe
Keyframe · The log

Tweening Without a Library: Easing in Pure ActionScript

August 7, 2011 · Uncategorized

You can install a tweening library, and honestly a lot of people should. But you owe it to yourself to build ease-out by hand exactly once, because the entire concept fits inside a single line of arithmetic, and understanding that line will quietly ruin every cheap linear animation you ever see again. You will be at a bus stop watching a loading bar and thinking, that is a fixed pixel step, amateurs.

package {
    import flash.display.Sprite;
    import flash.events.Event;

    public class EaseDemo extends Sprite {
        private var box:Sprite;
        private var targetX:Number = 400;
        private var easing:Number = 0.15;

        public function EaseDemo() {
            box = new Sprite();
            box.graphics.beginFill(0xff3d7f);
            box.graphics.drawRect(0, 0, 60, 60);
            box.graphics.endFill();
            box.x = 20;
            box.y = 120;
            addChild(box);

            addEventListener(Event.ENTER_FRAME, onFrame);
        }

        private function onFrame(event:Event):void {
            var dx:Number = targetX - box.x;
            box.x += dx * easing;

            if (Math.abs(dx) < 0.5) {
                box.x = targetX;
                removeEventListener(Event.ENTER_FRAME, onFrame);
            }
        }
    }
}

The one line that matters

Everything interesting happens in box.x += dx * easing. The trick is to move a fraction of the way to the target every frame, not a fixed number of pixels. A fixed step is linear motion, and linear motion is the thing your eye instantly files under cheap, because nothing in the physical world starts and stops at a constant speed. A fraction of the remaining distance is different. As the box gets closer, the distance left shrinks, so the step shrinks with it. Fast at the start, gentle at the arrival. That deceleration is ease-out, and you just wrote it with one subtraction and one multiply.

Event.ENTER_FRAME is the engine underneath. It fires once per frame, at whatever frame rate the movie runs, which makes it the closest thing AS3 has to a heartbeat. Every beat, you recompute the remaining distance and take another fractional step. No timers, no schedules, just the movie breathing and the box chasing a number.

Why the stop condition is not optional

Here is the part people forget, and their CPUs pay for it. The box never mathematically reaches the target. It asymptotes, always a sliver away, so dx gets absurdly small but never actually zero. Without the check, ENTER_FRAME runs every frame forever, nudging the box by a millionth of a pixel and gently warming the room. When you are close enough, snap to the target and remove the listener. Unhooking ENTER_FRAME is the tweening equivalent of turning the stove off before you leave the house.

Now play with one number. Set easing to 0.05 and the box glides in like it has somewhere nice to be. Set it to 0.4 and it snaps, all business. Set it to 1.0 and congratulations, you have reinvented no animation at all. One variable holds the entire personality of the motion. Nature does not move at a constant speed, and after this, neither will your rectangles.

← Back to the log