📄 transition.as
字号:
package flare.animate
{
import flare.util.Maths;
import flash.events.EventDispatcher;
[Event(name="start", type="flare.animate.TransitionEvent")]
[Event(name="step", type="flare.animate.TransitionEvent")]
[Event(name="end", type="flare.animate.TransitionEvent")]
[Event(name="cancel", type="flare.animate.TransitionEvent")]
/**
* Base class representing an animated transition. Provides support for
* tracking animation progress over a time duration. The Transition class
* also issues events whenever the transition is started, stepped, or
* ended. Register event listeners for <code>TransitionEvents</code> to
* track and respond to a transition's progress.
*
* <p>Useful subclasses of <code>Transition</code> include the
* <code>Tween</code>, <code>Parallel</code>, <code>Sequence</code>,
* <code>Pause</code>, and <code>Transitioner</code> classes.</p>
*/
public class Transition extends EventDispatcher implements ISchedulable
{
/** Default easing function: a cubic slow-in slow-out. */
public static var DEFAULT_EASING:Function = Easing.easeInOutPoly(3);
/** Constant indicating this Transition needs initialization. */
protected static const SETUP:int = 0;
/** Constant indicating this Transition has been initialized. */
protected static const INIT:int = 1;
/** Constant indicating this Transition is currently running. */
protected static const RUN:int = 2;
// -- Properties ------------------------------------------------------
private var _easing:Function = DEFAULT_EASING; // easing function
private var _id:String = null; // transition id, default null
private var _duration:Number; // duration, in seconds
private var _delay:Number; // delay, in seconds
private var _frac:Number; // animation fraction
private var _state:int = SETUP; // initialization flag
/** @private */
protected var _start:Number; // start time
/** Flag indicating this Transition is currently running. */
protected var _running:Boolean = false;
/** Flag indicating this Transition is running in reverse. */
protected var _reverse:Boolean = false;
/** Flag indicating if step events should be processed. */
public var enabled:Boolean = true;
/** @inheritDoc */
public function get id():String { return _id; }
public function set id(s:String):void
{
if (_running) {
throw new Error(
"The id can't be changed while a transition is running.");
} else {
_id = s;
}
}
/** The total duration, including both delay and active duration. */
public function get totalDuration():Number { return duration + delay; }
/** The duration (length) of this Transition, in seconds. */
public function get duration():Number { return _duration; }
public function set duration(d:Number):void {
if (d<0) throw new ArgumentError("Negative duration not allowed.");
_duration = d;
}
/** The delay between a call to play and the actual start
* of the transition, in seconds. */
public function get delay():Number { return _delay; }
public function set delay(d:Number):void {
if (d<0) throw new ArgumentError("Negative delay not allowed.");
_delay = d;
}
/** Fraction between 0 and 1 indicating the current progress
* of this transition. */
public function get progress():Number { return _frac; }
internal function set progress(f:Number):void { _frac = f; }
/** Easing function used to pace this Transition. */
public function get easing():Function { return _easing; }
public function set easing(f:Function):void { _easing = f; }
/** Indicates if this Transition is currently running. */
public function get running():Boolean { return _running; }
/** Indicates if this Transition is running in reverse. */
public function get reverse():Boolean { return _reverse; }
// -- Methods ---------------------------------------------------------
/**
* Creates a new Transition.
* @param duration the duration, in seconds
* @param delay the delay, in seconds
* @param easing the easing function
*/
public function Transition(duration:Number=1, delay:Number=0,
easing:Function=null)
{
_duration = duration;
_delay = delay;
_easing = (easing==null ? DEFAULT_EASING : easing);
}
/**
* Starts running the transition.
* @param reverse if true, the transition is played in reverse,
* if false (the default), it is played normally.
*/
public function play(reverse:Boolean = false):void
{
_reverse = reverse;
init();
Scheduler.instance.add(this);
_running = true;
}
/**
* Stops the transition and completes it.
* Any end-of-transition actions will still be taken.
* Calling play() after stop() will result in the transition
* starting over from the beginning.
*/
public function stop():void
{
Scheduler.instance.remove(this);
doEnd();
}
/**
* Informs this transition that it was cancelled by the scheduler.
* Assumes that the scheduler has already removed the transition.
* Clients should not call this method, but should use the
* <code>stop()</code> method to end a transition early.
*/
public function cancelled():void
{
doEnd(TransitionEvent.CANCEL);
}
/**
* Resets the transition, so that any cached starting values are
* cleared and reset the next time this transition is played.
*/
public function reset():void
{
_state = SETUP;
}
/**
* Pauses the transition at its current position.
* Calling play() after pause() will resume the transition.
*/
public function pause():void
{
Scheduler.instance.remove(this);
_running = false;
}
private function init():void
{
if (_state == SETUP) doSetup();
if (_state == RUN) {
var f:Number = _reverse ? (1-_frac) : _frac;
_start = new Date().time - f * 1000 * (duration + delay);
} else {
_start = new Date().time;
doStart(_reverse);
}
_state = RUN;
}
/** @private */
internal function doSetup():void
{
setup();
_state = INIT;
}
/** @private */
internal function doStart(reverse:Boolean):void
{
_reverse = reverse;
_running = true;
_frac = _reverse ? 1 : 0;
start();
if (hasEventListener(TransitionEvent.START)) {
dispatchEvent(new TransitionEvent(TransitionEvent.START, this));
}
}
/** @private */
internal function doStep(frac:Number):void
{
if (!enabled) return;
_frac = frac;
var f:Number = delay==0 || frac==0 ? frac :
Maths.invLinearInterp(frac, delay/totalDuration, 1);
if (f >= 0) step(_easing(f));
if (hasEventListener(TransitionEvent.STEP)) {
dispatchEvent(new TransitionEvent(TransitionEvent.STEP, this));
}
}
/** @private */
internal function doEnd(evtType:String=TransitionEvent.END):void
{
_frac = _reverse ? 0 : 1;
end();
_state = INIT;
_running = false;
if (hasEventListener(evtType)) {
dispatchEvent(new TransitionEvent(evtType, this));
}
}
/**
* Evaluates the Transition, stepping the transition forward.
* @param time the current time in milliseconds
* @return true if this item should be removed from the scheduler,
* false if it should continue to be run.
*/
public function evaluate(time:Number):Boolean
{
var t:Number = time - _start;
if (t < 0) return false;
// step the transition forward
var d:Number = 1000 * (duration + delay);
t = (d==0 ? 1.0 : t/d);
if (t > 1) t = 1; // clamp
doStep(_reverse ? 1-t : t);
// check if we're done
var _done:Boolean = (t >= 1.0);
if (_done) { doEnd(); }
return _done;
}
/**
* Disposes of this transition, freeing up any resources held. This
* method is optional, but calling it when a transition is no longer
* needed can help improve overall performance.
*/
public function dispose():void
{
// for sub-classes to implement
}
// -- abstract methods ------------------------------------------------
/**
* Transition setup routine. Subclasses should override this function
* to perform custom setup actions.
*/
protected function setup():void
{
// for sub-classes to implement
}
/**
* Transition start routine. Subclasses should override this function
* to perform custom start actions.
*/
protected function start():void
{
// for sub-classes to implement
}
/**
* Transition step routine. Subclasses should override this function
* to perform custom step actions.
*/
internal function step(ef:Number):void
{
// for sub-classes to implement
}
/**
* Transition end routine. Subclasses should override this function
* to perform custom ending actions.
*/
protected function end():void
{
// for sub-classes to implement
}
} // end of class Transition
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -