ChainedTweener class : ChainedTweener.as
package com.yahoo.motion
{
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.events.TimerEvent;
import com.yahoo.motion.easing.Linear;
import flash.utils.Timer;
import flash.utils.ByteArray
import com.yahoo.motion.ChainedTweenerEvent
/**
* @author mr.hichem aka halfrobot
*/
public class ChainedTweener extends BaseTweener{
//Private Properties that are inherited from the BaseTweener class
/*private var _ease:Function = Linear.easeIn;
private var _duration:Number = 1; //in seconds
private var _frameRate:Number = 35;
private var _props:Array;
private var _initValues:Array;
private var _currentValues:Array;
private var _endValues:Array;
private var _propsLength:Number;
private var _targetsLength:Number;
private var _tweenIntervalId:uint;
private var _targets:Array;
private var _timer:Timer;
private var _frameIndex:Number;
private var _totalFrames:Number;
private var _keys:Array;
private var _loop:Boolean;
private var _yoyo:Boolean;
private var _delay:Number = 0*/
/**
* static properties
* */
protected static var _chain:Boolean
protected static var _stack:Array
protected static var _stackIndex:Number = 0
/**
* Constructor
* @param targets : the target display object
* @param props : the properties to tween
* @param duration : the duration , obvious , optional
* @param ease : the ease function , optional
* @param initValues : initial values, optional
* @param endValues : end values , optional
*/
public function ChainedTweener(targets:Object, props:Object, duration:Number = 1, ease:Function = null, initValues:Object = null, endValues:Object = null)
{
super(targets, props, duration, ease, initValues, endValues)
if (_stack == null) _stack = new Array()
if (_stack.length > 0) {
ChainedTweener(_stack[0]).setInitValues()
}
}
/**
* Public functions
*/
public override function stop():void
{
if (!_chain){
this._frameIndex = 0;
this._disposeTimer();
}else if (_chain) {
for (var i:int = 0; i < _stack.length; i++) {
ChainedTweener(_stack[i])._timer.stop()
ChainedTweener(_stack[i])._frameIndex=0
ChainedTweener(_stack[i])._disposeTimer()
}
}
this.dispatchEvent(new TweenerEvent(TweenerEvent.MOTION_STOP))
}
public override function pause(key:String=null):void
{
if (!_chain){
this._keys.push(key);
this._timer.stop();
}else if (_chain) {
for (var i:int = 0; i < _stack.length; i++) {
ChainedTweener(_stack[i])._timer.stop();
ChainedTweener(_stack[i])._keys.push(key);
}
}
}
public override function resume(key:String=null):void
{
if(key == null)
this._keys = new Array();
else
{
var i:Number = this._keys.indexOf(key);
if(i >= 0 )
this._keys.splice(i,1);
}
if (!_chain){
if(this._keys.length == 0)
{
this._timer.start();
this.dispatchEvent(new TweenerEvent(TweenerEvent.MOTION_RESUME));
}
}else if (_chain) {
if(this._keys.length == 0){
for (var j:int = 0; j < _stack.length ; j++) {
ChainedTweener(_stack[j])._timer.start()
this.dispatchEvent(new ChainedTweenerEvent(ChainedTweenerEvent.MOTION_RESUME));
trace(ChainedTweenerEvent.CHAINED_MOTION_FINISH)
this.dispatchEvent(new ChainedTweenerEvent(ChainedTweenerEvent.CHAINED_MOTION_RESUME));
}
}
}
}
public function chainedTweenTo(endValues:Object, delay:Number = 0, duration:Number = -1, ease:Function = null):ChainedTweener
{
if(this._initValues == null)
this._initValues = new Array();
if (_stack.length == 0 ){
for(var u:Number =0; u< this._propsLength;u++)
for(var l:Number =0; l<this._targetsLength; l++)
this._initValues[u] = this._targets[l][this._props[u]];
}
this.delay += delay
this._endValues = this._getValuesArray(endValues, Number);
if(duration >= 0) this._duration = duration;
if(ease != null) this._ease = ease;
this._frameIndex = 0;
if (_stack.length > 0) {
this.delay += (_stack[_stack.length-1].duration * 1000)
}
_stack.push(this)
_chain = true
//_stackIndex++
addEventListener("chainedTween", _chainedTweenHandler)
this.dispatchEvent(new Event("chainedTween"))
var res:ChainedTweener = this._clone(this)
res._initValues = arrayClone(this._endValues)
return _clone(res)
}
public function chainedTweenFromTo(initValues:Object, endValues:Object, delay:Number = 0, duration:Number = -1, ease:Function = null):ChainedTweener
{
this._initValues = this._getValuesArray(initValues, Number)
this.delay += delay
this._endValues = this._getValuesArray(endValues, Number);
if(duration >= 0) this._duration = duration;
if(ease != null) this._ease = ease;
this._frameIndex = 0;
if (_stack.length > 0) {
this.delay += (_stack[_stack.length-1].duration * 1000)
//trace("delay = " + this._delay, "duration = " + this.duration)
//trace(_stack.length)
}
_stack.push(this)
_chain = true
//_stackIndex++
addEventListener("chainedTween", _chainedTweenHandler)
this.dispatchEvent(new Event("chainedTween"))
var res:ChainedTweener = this._clone(this)
res._initValues = arrayClone(this._endValues)
return _clone(res)
}
function arrayClone(source:Object):*
{
var copier:ByteArray = new ByteArray();
copier.writeObject(source);
copier.position = 0;
return(copier.readObject());
}
public override function tweenTo(endValues:Object, duration:Number = -1, ease:Function = null):void {
if (_stack.length > 0) {
//_stackIndex++
this.chainedTweenTo(endValues, 0,duration, ease)
}
else super.tweenTo(endValues, duration, ease);
}
public override function tweenFromTo(initValues:Object, endValues:Object, duration:Number = -1, ease:Function = null):void{
if (_stack.length > 0) {
//_stackIndex++
chainedTweenFromTo(initValues, endValues, 0,duration, ease)
}
else super.tweenFromTo(initValues, endValues, duration, ease);
}
/**
*
* private functions
*/
protected override function _onTweenFinished(event:TimerEvent):void
{
this._lastStepIt();
this._frameIndex = 0;
if(this._loop && !_chain )
{
var temp:Array = (new Array()).concat(this._initValues);
this._initValues = (new Array()).concat(this._endValues);
this._endValues = temp;
this._tween();
this.dispatchEvent(new TweenerEvent(TweenerEvent.MOTION_LOOP));
return;
}
else if(this._yoyo && !_chain)
{
this._tween();
this.dispatchEvent(new TweenerEvent(TweenerEvent.MOTION_LOOP));
return;
}
if (_chain)
{
var tamp:Array
this._disposeTimer();
if (_stack.length > 0) {
_stackIndex--
if(_stack.length > 1)
ChainedTweener(_stack[0]).dispatchEvent(new ChainedTweenerEvent(ChainedTweenerEvent.CHAINED_MOTION_FINISH));
if (_stackIndex== 0){
ChainedTweener(_stack[0]).dispatchEvent(new ChainedTweenerEvent(ChainedTweenerEvent.MOTION_FINISH));
if (_yoyo) {
_stackIndex = _stack.length
for (var i:int = 0; i < _stack.length; i++) {
ChainedTweener(_stack[i])._timer.reset()
_stack[i]._doDelay()
ChainedTweener(_stack[0]).dispatchEvent(new ChainedTweenerEvent(ChainedTweenerEvent.MOTION_LOOP))
}
}
else if (_loop) {
_stackIndex = _stack.length
_reverseDelays()
var temp:Array ;
for (var j:int = 0; j < _stack.length; j++) {
temp = (new Array()).concat(ChainedTweener(_stack[j])._initValues);
ChainedTweener(_stack[j])._initValues = (new Array()).concat(ChainedTweener(_stack[j])._endValues);
ChainedTweener(_stack[j])._endValues = temp;
_stack[j]._doDelay()
ChainedTweener(_stack[0]).dispatchEvent(new ChainedTweenerEvent(ChainedTweenerEvent.MOTION_LOOP))
}
}
}
}
trace(_stackIndex)
return
}
this._disposeTimer();
//this.dispatchEvent(new TweenerEvent(TweenerEvent.MOTION_FINISH));
}
private function _reverseDelays()
{
var temp:Number
for (var i:int = 0; i < Math.floor(_stack.length/2); i++) {
temp = _stack[i].delay
_stack[i].delay = _stack[_stack.length - 1 - i].delay
_stack[_stack.length - 1 - i].delay = temp
}
}
protected static function _chainedTweenHandler(e:Event)
{
_stack[0].setInitValues()
_stack[_stack.length - 1]._doDelay()
_stack[_stack.length - 1].removeEventListener("chainedTween", _chainedTweenHandler)
_stackIndex++
}
protected function setInitValues()
{
for(var u:Number =0; u< this._propsLength;u++)
for(var l:Number =0; l<this._targetsLength; l++)
this._targets[l][this._props[u]] = this._initValues[u];
}
protected function _clone(obj:ChainedTweener):ChainedTweener
{
var res:ChainedTweener ;
res = new ChainedTweener(obj._targets, obj._props, obj.duration, obj.ease, obj._initValues, obj._endValues)
res._delay = obj._delay
res.yoyo = obj.yoyo
res.loop = obj.loop
return res
}
}
}