Files
nenya/src/as/com/threerings/flash/AnimationManager.as
T
Ray Greenwell fb1eb6026b Call updateAnimation() immediately on any starting animation.
git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@212 ed5b42cb-e716-0410-a449-f6a68f950b19
2007-04-27 00:51:50 +00:00

125 lines
3.3 KiB
ActionScript

package com.threerings.flash {
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
import flash.utils.getTimer; // func import
/**
* Manages animations.
*/
public class AnimationManager
{
public function AnimationManager ()
{
throw new Error("Static only");
}
/**
* Start (or restart) the specified animation.
*/
public static function start (anim :Animation) :void
{
var dex :int = _anims.indexOf(anim);
if (dex == -1) {
dex = _anims.length;
_anims.push(anim);
}
_anims[dex + 1] = getTimer(); // mark it as starting
// and update it immediately
anim.updateAnimation(0);
if (!_framer) {
_framer = new Sprite();
_framer.addEventListener(Event.ENTER_FRAME, frameHandler);
}
}
/**
* Stop the specified animation.
*/
public static function stop (anim :Animation) :void
{
var dex :int = _anims.indexOf(anim);
if (dex == -1) {
Log.getLog(AnimationManager).warning("Stopping unknown Animation: " + anim);
return;
}
// remove it
_anims.splice(dex, 2);
// See if we should clean up a bit
if (_anims.length == 0) {
_framer.removeEventListener(Event.ENTER_FRAME, frameHandler);
_framer = null;
}
}
/**
* Track a DisplayObject that is also an Animation- it will
* automatically be started when added to the stage and
* stopped when removed.
*/
public static function addDisplayAnimation (disp :DisplayObject) :void
{
if (!(disp is Animation)) {
throw new ArgumentError("Must be an Animation");
}
disp.addEventListener(Event.ADDED_TO_STAGE, startDisplayAnim);
disp.addEventListener(Event.REMOVED_FROM_STAGE, stopDisplayAnim);
if (disp.stage != null) {
// it's on the stage now!
start(Animation(disp));
}
}
/**
* Stop tracking the specified DisplayObject animation.
*/
public static function removeDisplayAnimation (disp :DisplayObject) :void
{
disp.removeEventListener(Event.ADDED_TO_STAGE, startDisplayAnim);
disp.removeEventListener(Event.REMOVED_FROM_STAGE, stopDisplayAnim);
if (disp.stage != null) {
stop(Animation(disp));
}
}
protected static function startDisplayAnim (event :Event) :void
{
start(event.currentTarget as Animation);
}
protected static function stopDisplayAnim (event :Event) :void
{
stop(event.currentTarget as Animation);
}
/**
* Handle the ENTER_FRAME event.
*/
protected static function frameHandler (event :Event) :void
{
var now :Number = getTimer();
var anim :Animation;
var startStamp :Number;
for (var ii :int = _anims.length - 2; ii >= 0; ii -= 2) {
Animation(_anims[ii]).updateAnimation(now - Number(_anims[ii + 1]));
}
}
/** The current timestamp, accessable to all animations. */
protected static var _now :Number;
/** All the currently running animations. */
protected static var _anims :Array = [];
protected static var _framer :Sprite;
}
}