Skip to content

Commit

Permalink
12.1.4
Browse files Browse the repository at this point in the history
- Fixed issue that could cause an addPause() pause to be skipped in a very uncommon scenario when running in reverse.

- Fixed an issue that could cause an addPause() or other call() that's positioned exactly at the very end of a timeline to be called upon reverse().

- Enhanced BezierPlugin so that it records the initial rotational values when autoRotate is applied so that when the parent timeline is rewound past the beginning of the Bezier tween, the original values get re-applied.
  • Loading branch information
jackdoyle committed Mar 27, 2014
1 parent 1e7dc5c commit 8f54b77
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 33 deletions.
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "gsap",
"version": "12.1.3",
"version": "12.1.4",
"description": "GreenSock Animation Platform (GSAP) is a suite of high-performance AS3 classes for scripted animation (also available in JavaScript and AS2), including TweenLite, TweenMax, TimelineLite, TimelineMax, various easing equations, and plugins for things like animating along Bezier paths, filters, etc. See http://www.greensock.com/ for details.",
"author": {
"name": "Jack Doyle",
Expand Down
12 changes: 6 additions & 6 deletions src/com/greensock/TimelineLite.as
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* VERSION: 12.1.3
* DATE: 2014-02-20
* VERSION: 12.1.4
* DATE: 2014-03-21
* AS3 (AS2 version is also available)
* UPDATES AND DOCS AT: http://www.greensock.com/timelinelite/
**/
Expand Down Expand Up @@ -303,7 +303,7 @@ tl.add(nested);
**/
public class TimelineLite extends SimpleTimeline {
/** @private **/
public static const version:String = "12.1.3";
public static const version:String = "12.1.4";

/** @private **/
protected var _labels:Object;
Expand Down Expand Up @@ -1555,12 +1555,12 @@ myAnimation.seek("myLabel");
}
}
}
_rawPrevTime = (_duration !== 0 || !suppressEvents || time !== 0) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
_rawPrevTime = (_duration !== 0 || !suppressEvents || time !== 0 || _rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
time = totalDur + 0.0001; //to avoid occasional floating point rounding errors in Flash - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when Flash performed _time - tween._startTime, floating point errors would return a value that was SLIGHTLY off)

} else if (time < 0.0000001) { //to work around occasional floating point math artifacts, round super small values to 0.
_totalTime = _time = 0;
if (prevTime != 0 || (_duration == 0 && (_rawPrevTime > _tinyNum || (time < 0 && _rawPrevTime >= 0)))) {
if (prevTime !== 0 || (_duration === 0 && _rawPrevTime !== _tinyNum && (_rawPrevTime > 0 || (time < 0 && _rawPrevTime >= 0)))) {
callback = "onReverseComplete";
isComplete = _reversed;
}
Expand All @@ -1571,7 +1571,7 @@ myAnimation.seek("myLabel");
}
_rawPrevTime = time;
} else {
_rawPrevTime = (_duration || !suppressEvents || time !== 0) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
_rawPrevTime = (_duration || !suppressEvents || time !== 0 || _rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
if (!_initted) {
internalForce = true;
Expand Down
12 changes: 6 additions & 6 deletions src/com/greensock/TimelineMax.as
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* VERSION: 12.1.3
* DATE: 2014-02-20
* VERSION: 12.1.4
* DATE: 2014-03-21
* AS3 (AS2 version is also available)
* UPDATES AND DOCS AT: http://www.greensock.com/timelinemax/
**/
Expand Down Expand Up @@ -388,7 +388,7 @@ tl.add(nested);
**/
public class TimelineMax extends TimelineLite implements IEventDispatcher {
/** @private **/
public static const version:String = "12.1.3";
public static const version:String = "12.1.4";
/** @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 @@ -839,7 +839,7 @@ tl.add( myTimeline.tweenFromTo("myLabel2", 0) );
}
}
}
_rawPrevTime = (_duration || !suppressEvents || time !== 0) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
_rawPrevTime = (_duration || !suppressEvents || time !== 0 || _rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
if (_yoyo && (_cycle & 1) != 0) {
_time = time = 0;
} else {
Expand All @@ -852,7 +852,7 @@ tl.add( myTimeline.tweenFromTo("myLabel2", 0) );
_totalTime = _cycle = 0;
}
_time = 0;
if (prevTime != 0 || (_duration == 0 && (_rawPrevTime > _tinyNum || (time < 0 && _rawPrevTime >= 0)) && !_locked)) {
if (prevTime !== 0 || (_duration === 0 && _rawPrevTime !== _tinyNum && (_rawPrevTime > 0 || (time < 0 && _rawPrevTime >= 0)) && !_locked)) {
callback = "onReverseComplete";
isComplete = _reversed;
}
Expand All @@ -863,7 +863,7 @@ tl.add( myTimeline.tweenFromTo("myLabel2", 0) );
}
_rawPrevTime = time;
} else {
_rawPrevTime = (_duration || !suppressEvents || time !== 0) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
_rawPrevTime = (_duration || !suppressEvents || time !== 0 || _rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
if (!_initted) {
internalForce = true;
Expand Down
17 changes: 10 additions & 7 deletions src/com/greensock/TweenLite.as
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* VERSION: 12.1.3
* DATE: 2014-02-20
* VERSION: 12.1.4
* DATE: 2014-03-19
* 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.1.3";
public static const version:String = "12.1.4";

/** 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 @@ -631,19 +631,22 @@ package com.greensock {
}
if (_duration == 0) { //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered.
rawPrevTime = _rawPrevTime;
if (_startTime === _timeline._duration) { //if a zero-duration tween is at the VERY end of a timeline and that timeline renders at its end, it will typically add a tiny bit of cushion to the render time to prevent rounding errors from getting in the way of tweens rendering their VERY end. If we then reverse() that timeline, the zero-duration tween will trigger its onReverseComplete even though technically the playhead didn't pass over it again. It's a very specific edge case we must accommodate.
time = 0;
}
if (time === 0 || rawPrevTime < 0 || rawPrevTime === _tinyNum) if (rawPrevTime !== time) {
force = true;
if (rawPrevTime > _tinyNum) {
if (rawPrevTime > 0 && rawPrevTime !== _tinyNum) {
callback = "onReverseComplete";
}
}
_rawPrevTime = rawPrevTime = (!suppressEvents || time !== 0) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
_rawPrevTime = rawPrevTime = (!suppressEvents || time !== 0 || _rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
}

} else if (time < 0.0000001) { //to work around occasional floating point math artifacts, round super small values to 0.
_totalTime = _time = 0;
ratio = _ease._calcEnd ? _ease.getRatio(0) : 0;
if (prevTime != 0 || (_duration == 0 && _rawPrevTime > _tinyNum)) {
if (prevTime !== 0 || (_duration === 0 && _rawPrevTime > 0 && _rawPrevTime !== _tinyNum)) {
callback = "onReverseComplete";
isComplete = _reversed;
}
Expand All @@ -653,7 +656,7 @@ package com.greensock {
if (_rawPrevTime >= 0) {
force = true;
}
_rawPrevTime = rawPrevTime = (!suppressEvents || time !== 0) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
_rawPrevTime = rawPrevTime = (!suppressEvents || time !== 0 || _rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
}
} else if (!_initted) { //if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately.
force = true;
Expand Down
Loading

0 comments on commit 8f54b77

Please sign in to comment.