Skip to content

Commit

Permalink
12.0.12
Browse files Browse the repository at this point in the history
- Added new "addPause()" method to TimelineLite that allows you to insert a pause action that will force calibration of the time at that exact spot and optionally call another function.

- Fixed issue that could cause a timeline to render things incorrectly if it was paused and seeked to an earlier time and then resumed.
  • Loading branch information
jackdoyle committed Jul 4, 2013
1 parent c007ce9 commit ef759e8
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 18 deletions.
60 changes: 55 additions & 5 deletions src/com/greensock/TimelineLite.as
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* VERSION: 12.0.11
* DATE: 2013-06-05
* VERSION: 12.0.12
* DATE: 2013-07-03
* AS3 (AS2 version is also available)
* UPDATES AND DOCS AT: http://www.greensock.com/timelinelite/
**/
Expand Down Expand Up @@ -276,7 +276,7 @@ tl.add(nested);
**/
public class TimelineLite extends SimpleTimeline {
/** @private **/
public static const version:String = "12.0.11";
public static const version:String = "12.0.12";
/** @private **/
protected static const _paramProps:Array = ["onStartParams","onUpdateParams","onCompleteParams","onReverseCompleteParams","onRepeatParams"];

Expand Down Expand Up @@ -990,6 +990,55 @@ tl.set(mc, {x:100}, "myLabel+=2"); //places it 2 seconds after "myLabel"
return add( new TweenLite(target, 0, vars), position);
}

/**
* Inserts a special callback that pauses playback of the timeline at a
* particular time or label. This method is more accurate than using a simple callback of your own because
* it ensures that even if the virtual playhead had moved slightly beyond the pause position, it'll get moved
* back to precisely the correct position.
*
* <p>Remember, the virtual playhead moves to a new position on each tick (frame) of the core timing mechanism,
* so it is possible, for example for it to be at 0.99 and then the next render happens at 1.01, so if your
* callback was at exactly 1 second, the playhead would (in this example) move slightly past where you wanted to
* pause. Then, if you reverse(), it would run into that callback again and get paused almost immediately. However,
* if you use the <code>addPause()</code> method, it will calibrate things so that when the callback is
* hit, it'll move the playhead back to <strong>EXACTLY</strong> where it should be. Thus, if you reverse()
* it won't run into the same callback again.</p>
*
* <listing version="3.0">
//insert a pause at exactly 2 seconds into the timeline
timeline.addPause(2);
//insert a pause at "yourLabel"
timeline.addPause("yourLabel");
//insert a pause 3 seconds after "yourLabel" and when that pause occurs, call yourFunction
timeline.addPause("yourLabel+=3", yourFunction);
//insert a pause at exactly 4 seconds and then call yourFunction and pass it 2 parameters, "param1" and "param2"
timeline.addPause(4, yourFunction, ["param1", "param2"]);
</listing>
*
* <p>The special callback is just a zero-duration tween that utilizes an onComplete, so technically
* this callback is just like any other, and it is considered a child of the timeline.</p>
*
* @param position Controls the placement of the pause in the timeline (by default, it's the end of the timeline, like "+=0"). Use a number to indicate an absolute time in terms of seconds (or frames for frames-based timelines), or you can use a string with a "+=" or "-=" prefix to offset the insertion point relative to the END of the timeline. For example, <code>"+=2"</code> would place the tween 2 seconds after the end, leaving a 2-second gap. <code>"-=2"</code> would create a 2-second overlap. You may also use a label like <code>"myLabel"</code> to have the tween inserted exactly at the label or combine a label and a relative offset like <code>"myLabel+=2"</code> to insert the tween 2 seconds after "myLabel" or <code>"myLabel-=3"</code> to insert it 3 seconds before "myLabel". If you define a label that doesn't exist yet, it will <strong>automatically be added to the end of the timeline</strong> before inserting the tween there which can be quite convenient.
* @param callback An optional callback that should be called immediately after the timeline is paused.
* @param params An optional array of parameters to pass the callback.
* @return self (makes chaining easier)
* @see #call()
*/
public function addPause(position:*="+=0", callback:Function=null, params:Array=null):* {
return call(_pauseCallback, ["{self}", callback, params], position);
}

/** @private **/
protected function _pauseCallback(tween:TweenLite, callback:Function=null, params:Array=null):void {
pause(tween._startTime);
if (callback != null) {
callback.apply(null, params);
}
}

/** @private **/
protected static function _prepVars(vars:Object):Object { //to accommodate TweenLiteVars and TweenMaxVars instances for strong data typing and code hinting
return (vars._isGSVars) ? vars.vars : vars;
Expand Down Expand Up @@ -1464,8 +1513,6 @@ myAnimation.seek("myLabel");
override public function render(time:Number, suppressEvents:Boolean=false, force:Boolean=false):void {
if (_gc) {
_enabled(true, false);
} else if (!_active && !_paused) {
_active = true;
}
var totalDur:Number = (!_dirty) ? _totalDuration : totalDuration(),
prevTime:Number = _time,
Expand Down Expand Up @@ -1514,6 +1561,9 @@ myAnimation.seek("myLabel");
} else if (!_initted) {
_initted = true;
}
if (!_active) if (!_paused && _time !== prevTime && time > 0) {
_active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example.
}
if (prevTime == 0) if (vars.onStart) if (_time != 0) if (!suppressEvents) {
vars.onStart.apply(null, vars.onStartParams);
}
Expand Down
11 changes: 7 additions & 4 deletions src/com/greensock/TimelineMax.as
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* VERSION: 12.0.11
* DATE: 2013-06-05
* VERSION: 12.0.12
* DATE: 2013-07-03
* AS3 (AS2 version is also available)
* UPDATES AND DOCS AT: http://www.greensock.com/timelinemax/
**/
Expand Down Expand Up @@ -361,7 +361,7 @@ tl.add(nested);
**/
public class TimelineMax extends TimelineLite implements IEventDispatcher {
/** @private **/
public static const version:String = "12.0.11";
public static const version:String = "12.0.12";
/** @private **/
protected static var _listenerLookup:Object = {onCompleteListener:TweenEvent.COMPLETE, onUpdateListener:TweenEvent.UPDATE, onStartListener:TweenEvent.START, onRepeatListener:TweenEvent.REPEAT, onReverseCompleteListener:TweenEvent.REVERSE_COMPLETE};
/** @private **/
Expand Down Expand Up @@ -786,7 +786,6 @@ tl.add( myTimeline.tweenFromTo("myLabel2", 0) );
if (_gc) {
_enabled(true, false);
}
_active = !_paused;
var totalDur:Number = (!_dirty) ? _totalDuration : totalDuration(),
prevTime:Number = _time,
prevTotalTime:Number = _totalTime,
Expand Down Expand Up @@ -925,6 +924,10 @@ tl.add( myTimeline.tweenFromTo("myLabel2", 0) );
_initted = true;
}

if (!_active) if (!_paused && _totalTime !== prevTotalTime && time > 0) {
_active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example.
}

if (prevTotalTime == 0) if (_totalTime != 0) if (!suppressEvents) {
if (vars.onStart) {
vars.onStart.apply(this, vars.onStartParams);
Expand Down
8 changes: 4 additions & 4 deletions src/com/greensock/TweenLite.as
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* VERSION: 12.0.11
* DATE: 2013-06-05
* VERSION: 12.0.12
* DATE: 2013-07-03
* AS3 (AS2 version is also available)
* UPDATES AND DOCS AT: http://www.greensock.com
**/
Expand Down Expand Up @@ -304,7 +304,7 @@ package com.greensock {
public class TweenLite extends Animation {

/** @private **/
public static const version:String = "12.0.11";
public static const version:String = "12.0.12";

/** Provides An easy way to change the default easing equation. Choose from any of the GreenSock eases in the <code>com.greensock.easing</code> package. @default Power1.easeOut **/
public static var defaultEase:Ease = new Ease(null, null, 1, 1);
Expand Down Expand Up @@ -709,7 +709,7 @@ package com.greensock {
}
}

if (!_active) if (!_paused) {
if (!_active) if (!_paused && _time !== prevTime && time >= 0) {
_active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done.
}
if (prevTime == 0) {
Expand Down
10 changes: 5 additions & 5 deletions src/com/greensock/TweenMax.as
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* VERSION: 12.0.11
* DATE: 2013-06-05
* VERSION: 12.0.12
* DATE: 2013-07-03
* AS3 (AS2 version is also available)
* UPDATES AND DOCS AT: http://www.greensock.com
**/
Expand Down Expand Up @@ -530,7 +530,7 @@ package com.greensock {
*/
public class TweenMax extends TweenLite implements IEventDispatcher {
/** @private **/
public static const version:String = "12.0.11";
public static const version:String = "12.0.12";

TweenPlugin.activate([

Expand Down Expand Up @@ -973,8 +973,8 @@ tween.updateTo({x:300, y:0}, false);
ratio = _ease.getRatio((_time === 0) ? 0 : 1);
}
}
if (!_active) if (!_paused) {
_active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done.
if (!_active) if (!_paused && _time !== prevTime && time >= 0) {
_active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done.
}
if (prevTotalTime == 0) {
if (_startAt != null) {
Expand Down

0 comments on commit ef759e8

Please sign in to comment.