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 TransitionEvents
to
* track and respond to a transition's progress.
*
*
Useful subclasses of Transition
include the
* Tween
, Parallel
, Sequence
,
* Pause
, and Transitioner
classes.
stop()
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
}