Skip to content

Instantly share code, notes, and snippets.

@tzenkner
Last active August 29, 2015 13:57
Show Gist options
  • Save tzenkner/9455392 to your computer and use it in GitHub Desktop.
Save tzenkner/9455392 to your computer and use it in GitHub Desktop.
package{
import org.osflash.signals.Signal;
import starling.animation.DelayedCall;
import starling.animation.IAnimatable;
import starling.animation.Tween;
import starling.core.Starling;
/**
* basic timeline implementation to handle tweens and functions
* time values are handled in seconds
* it's working but not finished yet
* @author Thomas Zenkner
*/
public class TimeLine implements IAnimatable{
public const onComplete:Signal = new Signal();
private var _members:Array = [];
private var _lastMember:Object;
private var _tempCall:DelayedCall;
//TimeLine properties
private var _speed:Number = 1;
private var _totalTime:Number = 0.0;
private var _currentTime:Number = 0.0;
private var _inverted:Boolean = false;
private var _isPlaying:Boolean = false;
public function TimeLine(){
}
/**
* adds an element at the provided time, args are used when adding a function
*/
public function add(target:Object, time:Number = 0, args:Array = null):void{
if (target is LazyTween){
LazyTween(target).setDelay(time);
_members.push(target);
_totalTime = Math.max(Tween(target).delay + Tween(target).totalTime, _totalTime);
}else if (target is Function){
_tempCall = new DelayedCall(Function(target), time, args);
_members.push(_tempCall);
_totalTime = Math.max(_tempCall.totalTime, _totalTime);
}
}
/**
* adds an element at the end of the previous added one, args are used when adding a function
**/
public function addNext(target:Object, args:Array = null):void{
_lastMember = _members[_members.length - 1];
if (target is LazyTween){
if (_lastMember is Tween){
LazyTween(target).setDelay(Tween(_lastMember).delay + Tween(_lastMember).totalTime);
}else if(_lastMember is DelayedCall){
target.delay = DelayedCall(_lastMember).totalTime;
}
_members.push(target);
_totalTime = Math.max(Tween(target).delay + Tween(target).totalTime, _totalTime);
}else if (target is Function){
if (_lastMember is Tween){
_tempCall = new DelayedCall(Function(target), Tween(_lastMember).delay + Tween(_lastMember).totalTime, args);
}else if (_lastMember is DelayedCall){
_tempCall = new DelayedCall(Function(target), DelayedCall(_lastMember).totalTime + 0.02, args);
_totalTime = Math.max(_tempCall.totalTime, _totalTime);
}
_members.push(_tempCall);
}
}
/**
* starts the TimeLine [optional with end value]
**/
public function play(to:Number = 0):void{
if (!_isPlaying){
_isPlaying = true;
Starling.juggler.add(this);
if (to != 0){
stopAt(to);
}
}
}
/**
* stops the TimeLine [optional when the given time is reached]
**/
public function stop(at:Number = -1):void{
if (_isPlaying){
_isPlaying = false;
if (at != -1){
stopAt(at);
}else{
Starling.juggler.remove(this);
}
}
}
public function goTo(time:Number, stopThere:Boolean = false, jump:Boolean = false):void{
if (_inverted || time <= _currentTime){
time = _totalTime - time;
}
if (time <= _currentTime){
invert();
}
_currentTime = time <= _currentTime ? _totalTime - _currentTime : _currentTime;
if (jump){
advanceTime(time);
}else if (!jump && !_isPlaying){
play();
}else if (stopThere){
stopAt(time);
}
}
/**
* plays the TimeLine backwards from it's actual position
**/
public function turnAround():void{
invert();
}
/**
* advanced time is multiplied with this value to increase/decrease playing speed
**/
public function set speed(value:Number):void{
_speed = value;
}
private function stopAt(time:Number):void{
Starling.juggler.delayCall(stop, time - _currentTime);
}
private function invert():void{
for each(var member:LazyTween in _members){
member.invert(_totalTime);
_inverted = member.inverted;
}
_currentTime = _totalTime - _currentTime;
if (!_isPlaying){
play();
}
}
/**
* usually called by the juggler
**/
public function advanceTime(time:Number):void{
for each(var member:IAnimatable in _members){
if (!Tween(member).isComplete){
member.advanceTime(time * _speed);
}
}
_currentTime += time * _speed;
if (_currentTime >= _totalTime){
_currentTime = _totalTime;
stop();
onComplete.dispatch();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment