vendor/assets/javascripts/greensock/TweenMax.js in greensock-rails-1.12.1.0 vs vendor/assets/javascripts/greensock/TweenMax.js in greensock-rails-1.13.1.0
- old
+ new
@@ -1,26 +1,32 @@
/*!
- * VERSION: 1.12.1
- * DATE: 2014-06-26
+ * VERSION: 1.13.1
+ * DATE: 2014-07-19
* UPDATES AND DOCS AT: http://www.greensock.com
*
* Includes all of the following: TweenLite, TweenMax, TimelineLite, TimelineMax, EasePack, CSSPlugin, RoundPropsPlugin, BezierPlugin, AttrPlugin, DirectionalRotationPlugin
*
* @license Copyright (c) 2008-2014, GreenSock. All rights reserved.
* This work is subject to the terms at http://www.greensock.com/terms_of_use.html or for
* Club GreenSock members, the software agreement that was issued with your membership.
*
* @author: Jack Doyle, jack@greensock.com
**/
+var _gsScope = (typeof(module) !== "undefined" && module.exports && typeof(global) !== "undefined") ? global : this || window; //helps ensure compatibility with AMD/RequireJS and CommonJS/Node
+(_gsScope._gsQueue || (_gsScope._gsQueue = [])).push( function() {
-(window._gsQueue || (window._gsQueue = [])).push( function() {
-
"use strict";
- window._gsDefine("TweenMax", ["core.Animation","core.SimpleTimeline","TweenLite"], function(Animation, SimpleTimeline, TweenLite) {
+ _gsScope._gsDefine("TweenMax", ["core.Animation","core.SimpleTimeline","TweenLite"], function(Animation, SimpleTimeline, TweenLite) {
- var _slice = [].slice,
+ var _slice = function(a) { //don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
+ var b = [],
+ l = a.length,
+ i;
+ for (i = 0; i !== l; b.push(a[i++]));
+ return b;
+ },
TweenMax = function(target, duration, vars) {
TweenLite.call(this, target, duration, vars);
this._cycle = 0;
this._yoyo = (this.vars.yoyo === true);
this._repeat = this.vars.repeat || 0;
@@ -33,11 +39,11 @@
_isSelector = TweenLiteInternals.isSelector,
_isArray = TweenLiteInternals.isArray,
p = TweenMax.prototype = TweenLite.to({}, 0.1, {}),
_blankArray = [];
- TweenMax.version = "1.12.1";
+ TweenMax.version = "1.13.1";
p.constructor = TweenMax;
p.kill()._gc = false;
TweenMax.killTweensOf = TweenMax.killDelayedCallsTo = TweenLite.killTweensOf;
TweenMax.getTweensOf = TweenLite.getTweensOf;
TweenMax.lagSmoothing = TweenLite.lagSmoothing;
@@ -278,11 +284,11 @@
}
}
if (this._cycle !== prevCycle) if (!suppressEvents) if (!this._gc) if (this.vars.onRepeat) {
this.vars.onRepeat.apply(this.vars.onRepeatScope || this, this.vars.onRepeatParams || _blankArray);
}
- if (callback) if (!this._gc) { //check gc because there's a chance that kill() could be called in an onUpdate
+ if (callback) if (!this._gc || force) { //check gc because there's a chance that kill() could be called in an onUpdate
if (time < 0 && this._startAt && !this._onUpdate && this._startTime) { //if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values.
this._startAt.render(time, suppressEvents, force);
}
if (isComplete) {
if (this._timeline.autoRemoveChildren) {
@@ -331,11 +337,11 @@
if (!_isArray(targets)) {
if (typeof(targets) === "string") {
targets = TweenLite.selector(targets) || targets;
}
if (_isSelector(targets)) {
- targets = _slice.call(targets, 0);
+ targets = _slice(targets);
}
}
l = targets.length;
for (i = 0; i < l; i++) {
copy = {};
@@ -429,11 +435,11 @@
a, curParent, p, i, l;
if (typeof(parent) === "string") {
parent = TweenLite.selector(parent) || parent;
}
if (_isSelector(parent)) {
- parent = _slice.call(parent, 0);
+ parent = _slice(parent);
}
if (_isArray(parent)) {
i = parent.length;
while (--i > -1) {
TweenMax.killChildTweensOf(parent[i], complete);
@@ -585,11 +591,11 @@
/*
* ----------------------------------------------------------------
* TimelineLite
* ----------------------------------------------------------------
*/
- window._gsDefine("TimelineLite", ["core.Animation","core.SimpleTimeline","TweenLite"], function(Animation, SimpleTimeline, TweenLite) {
+ _gsScope._gsDefine("TimelineLite", ["core.Animation","core.SimpleTimeline","TweenLite"], function(Animation, SimpleTimeline, TweenLite) {
var TimelineLite = function(vars) {
SimpleTimeline.call(this, vars);
this._labels = {};
this.autoRemoveChildren = (this.vars.autoRemoveChildren === true);
@@ -607,14 +613,17 @@
if (_isArray(v.tweens)) {
this.add(v.tweens, 0, v.align, v.stagger);
}
},
_tinyNum = 0.0000000001,
- _isSelector = TweenLite._internals.isSelector,
- _isArray = TweenLite._internals.isArray,
+ TweenLiteInternals = TweenLite._internals,
+ _isSelector = TweenLiteInternals.isSelector,
+ _isArray = TweenLiteInternals.isArray,
+ _lazyTweens = TweenLiteInternals.lazyTweens,
+ _lazyRender = TweenLiteInternals.lazyRender,
_blankArray = [],
- _globals = window._gsDefine.globals,
+ _globals = _gsScope._gsDefine.globals,
_copy = function(vars) {
var copy = {}, p;
for (p in vars) {
copy[p] = vars[p];
}
@@ -624,17 +633,45 @@
tween._timeline.pause(tween._startTime);
if (callback) {
callback.apply(scope || tween._timeline, params || _blankArray);
}
},
- _slice = _blankArray.slice,
+ _slice = function(a) { //don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
+ var b = [],
+ l = a.length,
+ i;
+ for (i = 0; i !== l; b.push(a[i++]));
+ return b;
+ },
p = TimelineLite.prototype = new SimpleTimeline();
- TimelineLite.version = "1.12.1";
+ TimelineLite.version = "1.13.1";
p.constructor = TimelineLite;
p.kill()._gc = false;
+ /* might use later...
+ //translates a local time inside an animation to the corresponding time on the root/global timeline, factoring in all nesting and timeScales.
+ function localToGlobal(time, animation) {
+ while (animation) {
+ time = (time / animation._timeScale) + animation._startTime;
+ animation = animation.timeline;
+ }
+ return time;
+ }
+
+ //translates the supplied time on the root/global timeline into the corresponding local time inside a particular animation, factoring in all nesting and timeScales
+ function globalToLocal(time, animation) {
+ var scale = 1;
+ time -= localToGlobal(0, animation);
+ while (animation) {
+ scale *= animation._timeScale;
+ animation = animation.timeline;
+ }
+ return time * scale;
+ }
+ */
+
p.to = function(target, duration, vars, position) {
var Engine = (vars.repeat && _globals.TweenMax) || TweenLite;
return duration ? this.add( new Engine(target, duration, vars), position) : this.set(target, vars, position);
};
@@ -652,11 +689,11 @@
i;
if (typeof(targets) === "string") {
targets = TweenLite.selector(targets) || targets;
}
if (_isSelector(targets)) { //senses if the targets object is a selector. If it is, we should translate it into an array.
- targets = _slice.call(targets, 0);
+ targets = _slice(targets);
}
stagger = stagger || 0;
for (i = 0; i < targets.length; i++) {
if (vars.startAt) {
vars.startAt = _copy(vars.startAt);
@@ -908,11 +945,11 @@
callback = "onReverseComplete";
isComplete = this._reversed;
}
if (time < 0) {
this._active = false;
- if (this._duration === 0) if (this._rawPrevTime >= 0 && this._first) { //zero-duration timelines 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.
+ if (this._rawPrevTime >= 0 && this._first) { //when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state.
internalForce = true;
}
this._rawPrevTime = time;
} else {
this._rawPrevTime = (this._duration || !suppressEvents || time || this._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.
@@ -971,15 +1008,21 @@
tween = next;
}
}
if (this._onUpdate) if (!suppressEvents) {
+ if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values.
+ _lazyRender();
+ }
this._onUpdate.apply(this.vars.onUpdateScope || this, this.vars.onUpdateParams || _blankArray);
}
if (callback) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) { //if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate
if (isComplete) {
+ if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values.
+ _lazyRender();
+ }
if (this._timeline.autoRemoveChildren) {
this._enabled(false, false);
}
this._active = false;
}
@@ -1213,11 +1256,11 @@
/*
* ----------------------------------------------------------------
* TimelineMax
* ----------------------------------------------------------------
*/
- window._gsDefine("TimelineMax", ["TimelineLite","TweenLite","easing.Ease"], function(TimelineLite, TweenLite, Ease) {
+ _gsScope._gsDefine("TimelineMax", ["TimelineLite","TweenLite","easing.Ease"], function(TimelineLite, TweenLite, Ease) {
var TimelineMax = function(vars) {
TimelineLite.call(this, vars);
this._repeat = this.vars.repeat || 0;
this._repeatDelay = this.vars.repeatDelay || 0;
@@ -1225,16 +1268,19 @@
this._yoyo = (this.vars.yoyo === true);
this._dirty = true;
},
_tinyNum = 0.0000000001,
_blankArray = [],
+ TweenLiteInternals = TweenLite._internals,
+ _lazyTweens = TweenLiteInternals.lazyTweens,
+ _lazyRender = TweenLiteInternals.lazyRender,
_easeNone = new Ease(null, null, 1, 0),
p = TimelineMax.prototype = new TimelineLite();
p.constructor = TimelineMax;
p.kill()._gc = false;
- TimelineMax.version = "1.12.1";
+ TimelineMax.version = "1.13.1";
p.invalidate = function() {
this._yoyo = (this.vars.yoyo === true);
this._repeat = this.vars.repeat || 0;
this._repeatDelay = this.vars.repeatDelay || 0;
@@ -1341,11 +1387,11 @@
callback = "onReverseComplete";
isComplete = this._reversed;
}
if (time < 0) {
this._active = false;
- if (dur === 0) if (prevRawPrevTime >= 0 && this._first) { //zero-duration timelines 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.
+ if (prevRawPrevTime >= 0 && this._first) { //when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state.
internalForce = true;
}
this._rawPrevTime = time;
} else {
this._rawPrevTime = (dur || !suppressEvents || time || this._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.
@@ -1481,14 +1527,20 @@
tween = next;
}
}
if (this._onUpdate) if (!suppressEvents) {
+ if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values.
+ _lazyRender();
+ }
this._onUpdate.apply(this.vars.onUpdateScope || this, this.vars.onUpdateParams || _blankArray);
}
if (callback) if (!this._locked) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) { //if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate
if (isComplete) {
+ if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values.
+ _lazyRender();
+ }
if (this._timeline.autoRemoveChildren) {
this._enabled(false, false);
}
this._active = false;
}
@@ -1947,14 +1999,14 @@
return {length:total, lengths:lengths, segments:segments};
},
- BezierPlugin = window._gsDefine.plugin({
+ BezierPlugin = _gsScope._gsDefine.plugin({
propName: "bezier",
priority: -1,
- version: "1.3.2",
+ version: "1.3.3",
API: 2,
global:true,
//gets called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
init: function(target, vars, tween) {
@@ -2142,11 +2194,11 @@
BezierPlugin.quadraticToCubic = function(a, b, c) {
return new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c);
};
BezierPlugin._cssRegister = function() {
- var CSSPlugin = window._gsDefine.globals.CSSPlugin;
+ var CSSPlugin = _gsScope._gsDefine.globals.CSSPlugin;
if (!CSSPlugin) {
return;
}
var _internals = CSSPlugin._internals,
_parseToProxy = _internals._parseToProxy,
@@ -2241,11 +2293,11 @@
/*
* ----------------------------------------------------------------
* CSSPlugin
* ----------------------------------------------------------------
*/
- window._gsDefine("plugins.CSSPlugin", ["plugins.TweenPlugin","TweenLite"], function(TweenPlugin, TweenLite) {
+ _gsScope._gsDefine("plugins.CSSPlugin", ["plugins.TweenPlugin","TweenLite"], function(TweenPlugin, TweenLite) {
/** @constructor **/
var CSSPlugin = function() {
TweenPlugin.call(this, "css");
this._overwriteProps.length = 0;
@@ -2257,11 +2309,11 @@
_overwriteProps, //alias to the currently instantiating CSSPlugin's _overwriteProps array. We use this closure in order to avoid having to pass a reference around from method to method and aid in minification.
_specialProps = {},
p = CSSPlugin.prototype = new TweenPlugin("css");
p.constructor = CSSPlugin;
- CSSPlugin.version = "1.12.1";
+ CSSPlugin.version = "1.13.1";
CSSPlugin.API = 2;
CSSPlugin.defaultTransformPerspective = 0;
CSSPlugin.defaultSkewType = "compensated";
p = "px"; //we'll reuse the "p" variable to keep file size down
CSSPlugin.suffixMap = {top:p, right:p, bottom:p, left:p, width:p, height:p, fontSize:p, padding:p, margin:p, perspective:p, lineHeight:""};
@@ -3160,11 +3212,11 @@
//creates a placeholder special prop for a plugin so that the property gets caught the first time a tween of it is attempted, and at that time it makes the plugin register itself, thus taking over for all future tweens of that property. This allows us to not mandate that things load in a particular order and it also allows us to log() an error that informs the user when they attempt to tween an external plugin-related property without loading its .js file.
_registerPluginProp = function(p) {
if (!_specialProps[p]) {
var pluginName = p.charAt(0).toUpperCase() + p.substr(1) + "Plugin";
_registerComplexSpecialProp(p, {parser:function(t, e, p, cssp, pt, plugin, vars) {
- var pluginClass = (window.GreenSockGlobals || window).com.greensock.plugins[pluginName];
+ var pluginClass = (_gsScope.GreenSockGlobals || _gsScope).com.greensock.plugins[pluginName];
if (!pluginClass) {
_log("Error: " + pluginName + " js file not loaded.");
return pt;
}
pluginClass._cssRegister();
@@ -3275,11 +3327,11 @@
//transform-related methods and properties
- var _transformProps = ("scaleX,scaleY,scaleZ,x,y,z,skewX,skewY,rotation,rotationX,rotationY,perspective").split(","),
+ var _transformProps = ("scaleX,scaleY,scaleZ,x,y,z,skewX,skewY,rotation,rotationX,rotationY,perspective,xPercent,yPercent").split(","),
_transformProp = _checkPropPrefix("transform"), //the Javascript (camelCase) transform property, like msTransform, WebkitTransform, MozTransform, or OTransform.
_transformPropCSS = _prefixCSS + "transform",
_transformOriginProp = _checkPropPrefix("transformOrigin"),
_supports3D = (_checkPropPrefix("perspective") !== null),
Transform = _internals.Transform = function() {
@@ -3311,155 +3363,160 @@
} else if (t.currentStyle) {
//for older versions of IE, we need to interpret the filter portion that is in the format: progid:DXImageTransform.Microsoft.Matrix(M11=6.123233995736766e-17, M12=-1, M21=1, M22=6.123233995736766e-17, sizingMethod='auto expand') Notice that we need to swap b and c compared to a normal matrix.
s = t.currentStyle.filter.match(_ieGetMatrixExp);
s = (s && s.length === 4) ? [s[0].substr(4), Number(s[2].substr(4)), Number(s[1].substr(4)), s[3].substr(4), (tm.x || 0), (tm.y || 0)].join(",") : "";
}
- //split the matrix values out into an array (m for matrix)
- m = (s || "").match(/(?:\-|\b)[\d\-\.e]+\b/gi) || [];
- i = m.length;
- while (--i > -1) {
- n = Number(m[i]);
- m[i] = (dec = n - (n |= 0)) ? ((dec * rnd + (dec < 0 ? -0.5 : 0.5)) | 0) / rnd + n : n; //convert strings to Numbers and round to 5 decimal places to avoid issues with tiny numbers. Roughly 20x faster than Number.toFixed(). We also must make sure to round before dividing so that values like 0.9999999999 become 1 to avoid glitches in browser rendering and interpretation of flipped/rotated 3D matrices. And don't just multiply the number by rnd, floor it, and then divide by rnd because the bitwise operations max out at a 32-bit signed integer, thus it could get clipped at a relatively low value (like 22,000.00000 for example).
- }
- if (m.length === 16) {
+ if (!s || s === "none" || s === "matrix(1, 0, 0, 1, 0, 0)") { //if no transforms are applied, just use the defaults to optimize performance (no need to parse).
+ tm = {x:0, y:0, z:0, scaleX:1, scaleY:1, scaleZ:1, skewX:0, perspective:0, rotation:0, rotationX:0, rotationY:0, zOrigin:0};
+ } else {
+ //split the matrix values out into an array (m for matrix)
+ m = (s || "").match(/(?:\-|\b)[\d\-\.e]+\b/gi) || [];
+ i = m.length;
+ while (--i > -1) {
+ n = Number(m[i]);
+ m[i] = (dec = n - (n |= 0)) ? ((dec * rnd + (dec < 0 ? -0.5 : 0.5)) | 0) / rnd + n : n; //convert strings to Numbers and round to 5 decimal places to avoid issues with tiny numbers. Roughly 20x faster than Number.toFixed(). We also must make sure to round before dividing so that values like 0.9999999999 become 1 to avoid glitches in browser rendering and interpretation of flipped/rotated 3D matrices. And don't just multiply the number by rnd, floor it, and then divide by rnd because the bitwise operations max out at a 32-bit signed integer, thus it could get clipped at a relatively low value (like 22,000.00000 for example).
+ }
+ if (m.length === 16) {
- //we'll only look at these position-related 6 variables first because if x/y/z all match, it's relatively safe to assume we don't need to re-parse everything which risks losing important rotational information (like rotationX:180 plus rotationY:180 would look the same as rotation:180 - there's no way to know for sure which direction was taken based solely on the matrix3d() values)
- var a13 = m[8], a23 = m[9], a33 = m[10],
- a14 = m[12], a24 = m[13], a34 = m[14];
+ //we'll only look at these position-related 6 variables first because if x/y/z all match, it's relatively safe to assume we don't need to re-parse everything which risks losing important rotational information (like rotationX:180 plus rotationY:180 would look the same as rotation:180 - there's no way to know for sure which direction was taken based solely on the matrix3d() values)
+ var a13 = m[8], a23 = m[9], a33 = m[10],
+ a14 = m[12], a24 = m[13], a34 = m[14];
- //we manually compensate for non-zero z component of transformOrigin to work around bugs in Safari
- if (tm.zOrigin) {
- a34 = -tm.zOrigin;
- a14 = a13*a34-m[12];
- a24 = a23*a34-m[13];
- a34 = a33*a34+tm.zOrigin-m[14];
- }
+ //we manually compensate for non-zero z component of transformOrigin to work around bugs in Safari
+ if (tm.zOrigin) {
+ a34 = -tm.zOrigin;
+ a14 = a13*a34-m[12];
+ a24 = a23*a34-m[13];
+ a34 = a33*a34+tm.zOrigin-m[14];
+ }
- //only parse from the matrix if we MUST because not only is it usually unnecessary due to the fact that we store the values in the _gsTransform object, but also because it's impossible to accurately interpret rotationX, rotationY, rotationZ, scaleX, and scaleY if all are applied, so it's much better to rely on what we store. However, we must parse the first time that an object is tweened. We also assume that if the position has changed, the user must have done some styling changes outside of CSSPlugin, thus we force a parse in that scenario.
- if (!rec || parse || tm.rotationX == null) {
- var a11 = m[0], a21 = m[1], a31 = m[2], a41 = m[3],
- a12 = m[4], a22 = m[5], a32 = m[6], a42 = m[7],
- a43 = m[11],
- angle = Math.atan2(a32, a33),
- xFlip = (angle < -minPI || angle > minPI),
- t1, t2, t3, cos, sin, yFlip, zFlip;
- tm.rotationX = angle * _RAD2DEG;
- //rotationX
- if (angle) {
- cos = Math.cos(-angle);
- sin = Math.sin(-angle);
- t1 = a12*cos+a13*sin;
- t2 = a22*cos+a23*sin;
- t3 = a32*cos+a33*sin;
- a13 = a12*-sin+a13*cos;
- a23 = a22*-sin+a23*cos;
- a33 = a32*-sin+a33*cos;
- a43 = a42*-sin+a43*cos;
- a12 = t1;
- a22 = t2;
- a32 = t3;
+ //only parse from the matrix if we MUST because not only is it usually unnecessary due to the fact that we store the values in the _gsTransform object, but also because it's impossible to accurately interpret rotationX, rotationY, rotationZ, scaleX, and scaleY if all are applied, so it's much better to rely on what we store. However, we must parse the first time that an object is tweened. We also assume that if the position has changed, the user must have done some styling changes outside of CSSPlugin, thus we force a parse in that scenario.
+ if (!rec || parse || tm.rotationX == null) {
+ var a11 = m[0], a21 = m[1], a31 = m[2], a41 = m[3],
+ a12 = m[4], a22 = m[5], a32 = m[6], a42 = m[7],
+ a43 = m[11],
+ angle = Math.atan2(a32, a33),
+ xFlip = (angle < -minPI || angle > minPI),
+ t1, t2, t3, cos, sin, yFlip, zFlip;
+ tm.rotationX = angle * _RAD2DEG;
+ //rotationX
+ if (angle) {
+ cos = Math.cos(-angle);
+ sin = Math.sin(-angle);
+ t1 = a12*cos+a13*sin;
+ t2 = a22*cos+a23*sin;
+ t3 = a32*cos+a33*sin;
+ a13 = a12*-sin+a13*cos;
+ a23 = a22*-sin+a23*cos;
+ a33 = a32*-sin+a33*cos;
+ a43 = a42*-sin+a43*cos;
+ a12 = t1;
+ a22 = t2;
+ a32 = t3;
+ }
+ //rotationY
+ angle = Math.atan2(a13, a11);
+ tm.rotationY = angle * _RAD2DEG;
+ if (angle) {
+ yFlip = (angle < -minPI || angle > minPI);
+ cos = Math.cos(-angle);
+ sin = Math.sin(-angle);
+ t1 = a11*cos-a13*sin;
+ t2 = a21*cos-a23*sin;
+ t3 = a31*cos-a33*sin;
+ a23 = a21*sin+a23*cos;
+ a33 = a31*sin+a33*cos;
+ a43 = a41*sin+a43*cos;
+ a11 = t1;
+ a21 = t2;
+ a31 = t3;
+ }
+ //rotationZ
+ angle = Math.atan2(a21, a22);
+ tm.rotation = angle * _RAD2DEG;
+ if (angle) {
+ zFlip = (angle < -minPI || angle > minPI);
+ cos = Math.cos(-angle);
+ sin = Math.sin(-angle);
+ a11 = a11*cos+a12*sin;
+ t2 = a21*cos+a22*sin;
+ a22 = a21*-sin+a22*cos;
+ a32 = a31*-sin+a32*cos;
+ a21 = t2;
+ }
+
+ if (zFlip && xFlip) {
+ tm.rotation = tm.rotationX = 0;
+ } else if (zFlip && yFlip) {
+ tm.rotation = tm.rotationY = 0;
+ } else if (yFlip && xFlip) {
+ tm.rotationY = tm.rotationX = 0;
+ }
+
+ tm.scaleX = ((Math.sqrt(a11 * a11 + a21 * a21) * rnd + 0.5) | 0) / rnd;
+ tm.scaleY = ((Math.sqrt(a22 * a22 + a23 * a23) * rnd + 0.5) | 0) / rnd;
+ tm.scaleZ = ((Math.sqrt(a32 * a32 + a33 * a33) * rnd + 0.5) | 0) / rnd;
+ tm.skewX = 0;
+ tm.perspective = a43 ? 1 / ((a43 < 0) ? -a43 : a43) : 0;
+ tm.x = a14;
+ tm.y = a24;
+ tm.z = a34;
}
- //rotationY
- angle = Math.atan2(a13, a11);
- tm.rotationY = angle * _RAD2DEG;
- if (angle) {
- yFlip = (angle < -minPI || angle > minPI);
- cos = Math.cos(-angle);
- sin = Math.sin(-angle);
- t1 = a11*cos-a13*sin;
- t2 = a21*cos-a23*sin;
- t3 = a31*cos-a33*sin;
- a23 = a21*sin+a23*cos;
- a33 = a31*sin+a33*cos;
- a43 = a41*sin+a43*cos;
- a11 = t1;
- a21 = t2;
- a31 = t3;
+
+ } else if ((!_supports3D || parse || !m.length || tm.x !== m[4] || tm.y !== m[5] || (!tm.rotationX && !tm.rotationY)) && !(tm.x !== undefined && _getStyle(t, "display", cs) === "none")) { //sometimes a 6-element matrix is returned even when we performed 3D transforms, like if rotationX and rotationY are 180. In cases like this, we still need to honor the 3D transforms. If we just rely on the 2D info, it could affect how the data is interpreted, like scaleY might get set to -1 or rotation could get offset by 180 degrees. For example, do a TweenLite.to(element, 1, {css:{rotationX:180, rotationY:180}}) and then later, TweenLite.to(element, 1, {css:{rotationX:0}}) and without this conditional logic in place, it'd jump to a state of being unrotated when the 2nd tween starts. Then again, we need to honor the fact that the user COULD alter the transforms outside of CSSPlugin, like by manually applying new css, so we try to sense that by looking at x and y because if those changed, we know the changes were made outside CSSPlugin and we force a reinterpretation of the matrix values. Also, in Webkit browsers, if the element's "display" is "none", its calculated style value will always return empty, so if we've already recorded the values in the _gsTransform object, we'll just rely on those.
+ var k = (m.length >= 6),
+ a = k ? m[0] : 1,
+ b = m[1] || 0,
+ c = m[2] || 0,
+ d = k ? m[3] : 1;
+ tm.x = m[4] || 0;
+ tm.y = m[5] || 0;
+ scaleX = Math.sqrt(a * a + b * b);
+ scaleY = Math.sqrt(d * d + c * c);
+ rotation = (a || b) ? Math.atan2(b, a) * _RAD2DEG : tm.rotation || 0; //note: if scaleX is 0, we cannot accurately measure rotation. Same for skewX with a scaleY of 0. Therefore, we default to the previously recorded value (or zero if that doesn't exist).
+ skewX = (c || d) ? Math.atan2(c, d) * _RAD2DEG + rotation : tm.skewX || 0;
+ difX = scaleX - Math.abs(tm.scaleX || 0);
+ difY = scaleY - Math.abs(tm.scaleY || 0);
+ if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) {
+ if (invX) {
+ scaleX *= -1;
+ skewX += (rotation <= 0) ? 180 : -180;
+ rotation += (rotation <= 0) ? 180 : -180;
+ } else {
+ scaleY *= -1;
+ skewX += (skewX <= 0) ? 180 : -180;
+ }
}
- //rotationZ
- angle = Math.atan2(a21, a22);
- tm.rotation = angle * _RAD2DEG;
- if (angle) {
- zFlip = (angle < -minPI || angle > minPI);
- cos = Math.cos(-angle);
- sin = Math.sin(-angle);
- a11 = a11*cos+a12*sin;
- t2 = a21*cos+a22*sin;
- a22 = a21*-sin+a22*cos;
- a32 = a31*-sin+a32*cos;
- a21 = t2;
+ difR = (rotation - tm.rotation) % 180; //note: matching ranges would be very small (+/-0.0001) or very close to 180.
+ difS = (skewX - tm.skewX) % 180;
+ //if there's already a recorded _gsTransform in place for the target, we should leave those values in place unless we know things changed for sure (beyond a super small amount). This gets around ambiguous interpretations, like if scaleX and scaleY are both -1, the matrix would be the same as if the rotation was 180 with normal scaleX/scaleY. If the user tweened to particular values, those must be prioritized to ensure animation is consistent.
+ if (tm.skewX === undefined || difX > min || difX < -min || difY > min || difY < -min || (difR > -minAngle && difR < minAngle && (difR * rnd) | 0 !== 0) || (difS > -minAngle && difS < minAngle && (difS * rnd) | 0 !== 0)) {
+ tm.scaleX = scaleX;
+ tm.scaleY = scaleY;
+ tm.rotation = rotation;
+ tm.skewX = skewX;
}
-
- if (zFlip && xFlip) {
- tm.rotation = tm.rotationX = 0;
- } else if (zFlip && yFlip) {
- tm.rotation = tm.rotationY = 0;
- } else if (yFlip && xFlip) {
- tm.rotationY = tm.rotationX = 0;
+ if (_supports3D) {
+ tm.rotationX = tm.rotationY = tm.z = 0;
+ tm.perspective = parseFloat(CSSPlugin.defaultTransformPerspective) || 0;
+ tm.scaleZ = 1;
}
-
- tm.scaleX = ((Math.sqrt(a11 * a11 + a21 * a21) * rnd + 0.5) | 0) / rnd;
- tm.scaleY = ((Math.sqrt(a22 * a22 + a23 * a23) * rnd + 0.5) | 0) / rnd;
- tm.scaleZ = ((Math.sqrt(a32 * a32 + a33 * a33) * rnd + 0.5) | 0) / rnd;
- tm.skewX = 0;
- tm.perspective = a43 ? 1 / ((a43 < 0) ? -a43 : a43) : 0;
- tm.x = a14;
- tm.y = a24;
- tm.z = a34;
}
+ tm.zOrigin = zOrigin;
- } else if ((!_supports3D || parse || !m.length || tm.x !== m[4] || tm.y !== m[5] || (!tm.rotationX && !tm.rotationY)) && !(tm.x !== undefined && _getStyle(t, "display", cs) === "none")) { //sometimes a 6-element matrix is returned even when we performed 3D transforms, like if rotationX and rotationY are 180. In cases like this, we still need to honor the 3D transforms. If we just rely on the 2D info, it could affect how the data is interpreted, like scaleY might get set to -1 or rotation could get offset by 180 degrees. For example, do a TweenLite.to(element, 1, {css:{rotationX:180, rotationY:180}}) and then later, TweenLite.to(element, 1, {css:{rotationX:0}}) and without this conditional logic in place, it'd jump to a state of being unrotated when the 2nd tween starts. Then again, we need to honor the fact that the user COULD alter the transforms outside of CSSPlugin, like by manually applying new css, so we try to sense that by looking at x and y because if those changed, we know the changes were made outside CSSPlugin and we force a reinterpretation of the matrix values. Also, in Webkit browsers, if the element's "display" is "none", its calculated style value will always return empty, so if we've already recorded the values in the _gsTransform object, we'll just rely on those.
- var k = (m.length >= 6),
- a = k ? m[0] : 1,
- b = m[1] || 0,
- c = m[2] || 0,
- d = k ? m[3] : 1;
- tm.x = m[4] || 0;
- tm.y = m[5] || 0;
- scaleX = Math.sqrt(a * a + b * b);
- scaleY = Math.sqrt(d * d + c * c);
- rotation = (a || b) ? Math.atan2(b, a) * _RAD2DEG : tm.rotation || 0; //note: if scaleX is 0, we cannot accurately measure rotation. Same for skewX with a scaleY of 0. Therefore, we default to the previously recorded value (or zero if that doesn't exist).
- skewX = (c || d) ? Math.atan2(c, d) * _RAD2DEG + rotation : tm.skewX || 0;
- difX = scaleX - Math.abs(tm.scaleX || 0);
- difY = scaleY - Math.abs(tm.scaleY || 0);
- if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) {
- if (invX) {
- scaleX *= -1;
- skewX += (rotation <= 0) ? 180 : -180;
- rotation += (rotation <= 0) ? 180 : -180;
- } else {
- scaleY *= -1;
- skewX += (skewX <= 0) ? 180 : -180;
+ //some browsers have a hard time with very small values like 2.4492935982947064e-16 (notice the "e-" towards the end) and would render the object slightly off. So we round to 0 in these cases. The conditional logic here is faster than calling Math.abs(). Also, browsers tend to render a SLIGHTLY rotated object in a fuzzy way, so we need to snap to exactly 0 when appropriate.
+ for (i in tm) {
+ if (tm[i] < min) if (tm[i] > -min) {
+ tm[i] = 0;
}
}
- difR = (rotation - tm.rotation) % 180; //note: matching ranges would be very small (+/-0.0001) or very close to 180.
- difS = (skewX - tm.skewX) % 180;
- //if there's already a recorded _gsTransform in place for the target, we should leave those values in place unless we know things changed for sure (beyond a super small amount). This gets around ambiguous interpretations, like if scaleX and scaleY are both -1, the matrix would be the same as if the rotation was 180 with normal scaleX/scaleY. If the user tweened to particular values, those must be prioritized to ensure animation is consistent.
- if (tm.skewX === undefined || difX > min || difX < -min || difY > min || difY < -min || (difR > -minAngle && difR < minAngle && (difR * rnd) | 0 !== 0) || (difS > -minAngle && difS < minAngle && (difS * rnd) | 0 !== 0)) {
- tm.scaleX = scaleX;
- tm.scaleY = scaleY;
- tm.rotation = rotation;
- tm.skewX = skewX;
- }
- if (_supports3D) {
- tm.rotationX = tm.rotationY = tm.z = 0;
- tm.perspective = parseFloat(CSSPlugin.defaultTransformPerspective) || 0;
- tm.scaleZ = 1;
- }
}
- tm.zOrigin = zOrigin;
-
- //some browsers have a hard time with very small values like 2.4492935982947064e-16 (notice the "e-" towards the end) and would render the object slightly off. So we round to 0 in these cases. The conditional logic here is faster than calling Math.abs(). Also, browsers tend to render a SLIGHTLY rotated object in a fuzzy way, so we need to snap to exactly 0 when appropriate.
- for (i in tm) {
- if (tm[i] < min) if (tm[i] > -min) {
- tm[i] = 0;
- }
- }
//DEBUG: _log("parsed rotation: "+(tm.rotationX)+", "+(tm.rotationY)+", "+(tm.rotation)+", scale: "+tm.scaleX+", "+tm.scaleY+", "+tm.scaleZ+", position: "+tm.x+", "+tm.y+", "+tm.z+", perspective: "+tm.perspective);
if (rec) {
t._gsTransform = tm; //record to the object's _gsTransform which we use so that tweens can control individual properties independently (we need all the properties to accurately recompose the matrix in the setRatio() method)
}
+ tm.xPercent = tm.yPercent = 0;
return tm;
},
//for setting 2D transforms in IE6, IE7, and IE8 (must use a "filter" to emulate the behavior of modern day browser transforms)
_setIETransformRatio = function(v) {
@@ -3484,12 +3541,12 @@
style.filter = ""; //remove filters so that we can accurately measure offsetWidth/offsetHeight
var w = this.t.offsetWidth,
h = this.t.offsetHeight,
clip = (cs.position !== "absolute"),
m = "progid:DXImageTransform.Microsoft.Matrix(M11=" + a + ", M12=" + b + ", M21=" + c + ", M22=" + d,
- ox = t.x,
- oy = t.y,
+ ox = t.x + (w * t.xPercent / 100),
+ oy = t.y + (h * t.yPercent / 100),
dx, dy;
//if transformOrigin is being used, adjust the offset x and y
if (t.ox != null) {
dx = ((t.oxp) ? w * t.ox * 0.01 : t.ox) - w / 2;
@@ -3545,14 +3602,17 @@
style = this.t.style,
angle = t.rotation * _DEG2RAD,
sx = t.scaleX,
sy = t.scaleY,
sz = t.scaleZ,
+ x = t.x,
+ y = t.y,
+ z = t.z,
perspective = t.perspective,
a11, a12, a13, a14, a21, a22, a23, a24, a31, a32, a33, a34, a41, a42, a43,
zOrigin, rnd, cos, sin, t1, t2, t3, t4;
- if (v === 1 || v === 0) if (t.force3D === "auto") if (!t.rotationY && !t.rotationX && sz === 1 && !perspective && !t.z) { //on the final render (which could be 0 for a from tween), if there are no 3D aspects, render in 2D to free up memory and improve performance especially on mobile devices
+ if (v === 1 || v === 0) if (t.force3D === "auto") if (!t.rotationY && !t.rotationX && sz === 1 && !perspective && !z) { //on the final render (which could be 0 for a from tween), if there are no 3D aspects, render in 2D to free up memory and improve performance especially on mobile devices
_set2DTransformRatio.call(this, v);
return;
}
if (_isFirefox) {
var n = 0.0001;
@@ -3584,11 +3644,11 @@
}
a12 = -sin;
a22 = cos;
} else if (!t.rotationY && !t.rotationX && sz === 1 && !perspective) { //if we're only translating and/or 2D scaling, this is faster...
- style[_transformProp] = "translate3d(" + t.x + "px," + t.y + "px," + t.z +"px)" + ((sx !== 1 || sy !== 1) ? " scale(" + sx + "," + sy + ")" : "");
+ style[_transformProp] = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) translate3d(" : "translate3d(") + x + "px," + y + "px," + z +"px)" + ((sx !== 1 || sy !== 1) ? " scale(" + sx + "," + sy + ")" : "");
return;
} else {
a11 = a22 = 1;
a12 = a21 = 0;
}
@@ -3650,40 +3710,44 @@
a14 = a13*a34;
a24 = a23*a34;
a34 = a33*a34+zOrigin;
}
//we round the x, y, and z slightly differently to allow even larger values.
- a14 = (t1 = (a14 += t.x) - (a14 |= 0)) ? ((t1 * rnd + (t1 < 0 ? -0.5 : 0.5)) | 0) / rnd + a14 : a14;
- a24 = (t1 = (a24 += t.y) - (a24 |= 0)) ? ((t1 * rnd + (t1 < 0 ? -0.5 : 0.5)) | 0) / rnd + a24 : a24;
- a34 = (t1 = (a34 += t.z) - (a34 |= 0)) ? ((t1 * rnd + (t1 < 0 ? -0.5 : 0.5)) | 0) / rnd + a34 : a34;
- style[_transformProp] = "matrix3d(" + [ (((a11 * rnd) | 0) / rnd), (((a21 * rnd) | 0) / rnd), (((a31 * rnd) | 0) / rnd), (((a41 * rnd) | 0) / rnd), (((a12 * rnd) | 0) / rnd), (((a22 * rnd) | 0) / rnd), (((a32 * rnd) | 0) / rnd), (((a42 * rnd) | 0) / rnd), (((a13 * rnd) | 0) / rnd), (((a23 * rnd) | 0) / rnd), (((a33 * rnd) | 0) / rnd), (((a43 * rnd) | 0) / rnd), a14, a24, a34, (perspective ? (1 + (-a34 / perspective)) : 1) ].join(",") + ")";
+ a14 = (t1 = (a14 += x) - (a14 |= 0)) ? ((t1 * rnd + (t1 < 0 ? -0.5 : 0.5)) | 0) / rnd + a14 : a14;
+ a24 = (t1 = (a24 += y) - (a24 |= 0)) ? ((t1 * rnd + (t1 < 0 ? -0.5 : 0.5)) | 0) / rnd + a24 : a24;
+ a34 = (t1 = (a34 += z) - (a34 |= 0)) ? ((t1 * rnd + (t1 < 0 ? -0.5 : 0.5)) | 0) / rnd + a34 : a34;
+ style[_transformProp] = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix3d(" : "matrix3d(") + [ (((a11 * rnd) | 0) / rnd), (((a21 * rnd) | 0) / rnd), (((a31 * rnd) | 0) / rnd), (((a41 * rnd) | 0) / rnd), (((a12 * rnd) | 0) / rnd), (((a22 * rnd) | 0) / rnd), (((a32 * rnd) | 0) / rnd), (((a42 * rnd) | 0) / rnd), (((a13 * rnd) | 0) / rnd), (((a23 * rnd) | 0) / rnd), (((a33 * rnd) | 0) / rnd), (((a43 * rnd) | 0) / rnd), a14, a24, a34, (perspective ? (1 + (-a34 / perspective)) : 1) ].join(",") + ")";
},
_set2DTransformRatio = _internals.set2DTransformRatio = function(v) {
var t = this.data, //refers to the element's _gsTransform object
targ = this.t,
style = targ.style,
+ x = t.x,
+ y = t.y,
+ prefix = "",
ang, skew, rnd, sx, sy;
if (t.rotationX || t.rotationY || t.z || t.force3D === true || (t.force3D === "auto" && v !== 1 && v !== 0)) { //if a 3D tween begins while a 2D one is running, we need to kick the rendering over to the 3D method. For example, imagine a yoyo-ing, infinitely repeating scale tween running, and then the object gets rotated in 3D space with a different tween.
this.setRatio = _set3DTransformRatio;
_set3DTransformRatio.call(this, v);
return;
}
+
if (!t.rotation && !t.skewX) {
- style[_transformProp] = "matrix(" + t.scaleX + ",0,0," + t.scaleY + "," + t.x + "," + t.y + ")";
+ style[_transformProp] = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + t.scaleX + ",0,0," + t.scaleY + "," + x + "," + y + ")";
} else {
ang = t.rotation * _DEG2RAD;
skew = ang - t.skewX * _DEG2RAD;
rnd = 100000;
sx = t.scaleX * rnd;
sy = t.scaleY * rnd;
//some browsers have a hard time with very small values like 2.4492935982947064e-16 (notice the "e-" towards the end) and would render the object slightly off. So we round to 5 decimal places.
- style[_transformProp] = "matrix(" + (((Math.cos(ang) * sx) | 0) / rnd) + "," + (((Math.sin(ang) * sx) | 0) / rnd) + "," + (((Math.sin(skew) * -sy) | 0) / rnd) + "," + (((Math.cos(skew) * sy) | 0) / rnd) + "," + t.x + "," + t.y + ")";
+ style[_transformProp] = ((t.xPercent || t.yPercent) ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + (((Math.cos(ang) * sx) | 0) / rnd) + "," + (((Math.sin(ang) * sx) | 0) / rnd) + "," + (((Math.sin(skew) * -sy) | 0) / rnd) + "," + (((Math.cos(skew) * sy) | 0) / rnd) + "," + x + "," + y + ")";
}
};
- _registerComplexSpecialProp("transform,scale,scaleX,scaleY,scaleZ,x,y,z,rotation,rotationX,rotationY,rotationZ,skewX,skewY,shortRotation,shortRotationX,shortRotationY,shortRotationZ,transformOrigin,transformPerspective,directionalRotation,parseTransform,force3D,skewType", {parser:function(t, e, p, cssp, pt, plugin, vars) {
+ _registerComplexSpecialProp("transform,scale,scaleX,scaleY,scaleZ,x,y,z,rotation,rotationX,rotationY,rotationZ,skewX,skewY,shortRotation,shortRotationX,shortRotationY,shortRotationZ,transformOrigin,transformPerspective,directionalRotation,parseTransform,force3D,skewType,xPercent,yPercent", {parser:function(t, e, p, cssp, pt, plugin, vars) {
if (cssp._transform) { return pt; } //only need to parse the transform once, and only if the browser supports it.
var m1 = cssp._transform = _getTransform(t, _cs, true, vars.parseTransform),
style = t.style,
min = 0.000001,
i = _transformProps.length,
@@ -3703,10 +3767,12 @@
scaleY:_parseVal((v.scaleY != null) ? v.scaleY : v.scale, m1.scaleY),
scaleZ:_parseVal(v.scaleZ, m1.scaleZ),
x:_parseVal(v.x, m1.x),
y:_parseVal(v.y, m1.y),
z:_parseVal(v.z, m1.z),
+ xPercent:_parseVal(v.xPercent, m1.xPercent),
+ yPercent:_parseVal(v.yPercent, m1.yPercent),
perspective:_parseVal(v.transformPerspective, m1.perspective)};
dr = v.directionalRotation;
if (dr != null) {
if (typeof(dr) === "object") {
for (copy in dr) {
@@ -3714,10 +3780,19 @@
}
} else {
v.rotation = dr;
}
}
+ if (typeof(v.x) === "string" && v.x.indexOf("%") !== -1) {
+ m2.x = 0;
+ m2.xPercent = _parseVal(v.x, m1.xPercent);
+ }
+ if (typeof(v.y) === "string" && v.y.indexOf("%") !== -1) {
+ m2.y = 0;
+ m2.yPercent = _parseVal(v.y, m1.yPercent);
+ }
+
m2.rotation = _parseAngle(("rotation" in v) ? v.rotation : ("shortRotation" in v) ? v.shortRotation + "_short" : ("rotationZ" in v) ? v.rotationZ : m1.rotation, m1.rotation, "rotation", endRotations);
if (_supports3D) {
m2.rotationX = _parseAngle(("rotationX" in v) ? v.rotationX : ("shortRotationX" in v) ? v.shortRotationX + "_short" : m1.rotationX || 0, m1.rotationX, "rotationX", endRotations);
m2.rotationY = _parseAngle(("rotationY" in v) ? v.rotationY : ("shortRotationY" in v) ? v.shortRotationY + "_short" : m1.rotationY || 0, m1.rotationY, "rotationY", endRotations);
}
@@ -4544,11 +4619,11 @@
* RoundPropsPlugin
* ----------------------------------------------------------------
*/
(function() {
- var RoundPropsPlugin = window._gsDefine.plugin({
+ var RoundPropsPlugin = _gsScope._gsDefine.plugin({
propName: "roundProps",
priority: -1,
API: 2,
//called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
@@ -4617,14 +4692,14 @@
/*
* ----------------------------------------------------------------
* AttrPlugin
* ----------------------------------------------------------------
*/
- window._gsDefine.plugin({
+ _gsScope._gsDefine.plugin({
propName: "attr",
API: 2,
- version: "0.3.2",
+ version: "0.3.3",
//called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
init: function(target, value, tween) {
var p, start, end;
if (typeof(target.setAttribute) !== "function") {
@@ -4670,14 +4745,14 @@
/*
* ----------------------------------------------------------------
* DirectionalRotationPlugin
* ----------------------------------------------------------------
*/
- window._gsDefine.plugin({
+ _gsScope._gsDefine.plugin({
propName: "directionalRotation",
+ version: "0.2.1",
API: 2,
- version: "0.2.0",
//called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
init: function(target, value, tween) {
if (typeof(value) !== "object") {
value = {rotation:value};
@@ -4749,13 +4824,13 @@
/*
* ----------------------------------------------------------------
* EasePack
* ----------------------------------------------------------------
*/
- window._gsDefine("easing.Back", ["easing.Ease"], function(Ease) {
+ _gsScope._gsDefine("easing.Back", ["easing.Ease"], function(Ease) {
- var w = (window.GreenSockGlobals || window),
+ var w = (_gsScope.GreenSockGlobals || _gsScope),
gs = w.com.greensock,
_2PI = Math.PI * 2,
_HALF_PI = Math.PI / 2,
_class = gs._class,
_create = function(n, f) {
@@ -5077,31 +5152,33 @@
return Back;
}, true);
-});
+});
+if (_gsScope._gsDefine) { _gsScope._gsQueue.pop()(); } //necessary in case TweenLite was already loaded separately.
+
/*
* ----------------------------------------------------------------
* Base classes like TweenLite, SimpleTimeline, Ease, Ticker, etc.
* ----------------------------------------------------------------
*/
-(function(window) {
+(function(window, moduleName) {
"use strict";
- var _globals = window.GreenSockGlobals || window;
+ var _globals = window.GreenSockGlobals = window.GreenSockGlobals || window;
if (_globals.TweenLite) {
return; //in case the core set of classes is already loaded, don't instantiate twice.
}
var _namespace = function(ns) {
var a = ns.split("."),
@@ -5111,11 +5188,17 @@
}
return p;
},
gs = _namespace("com.greensock"),
_tinyNum = 0.0000000001,
- _slice = [].slice,
+ _slice = function(a) { //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
+ var b = [],
+ l = a.length,
+ i;
+ for (i = 0; i !== l; b.push(a[i++]));
+ return b;
+ },
_emptyFunc = function() {},
_isArray = (function() { //works around issues in iframe environments where the Array global isn't shared, thus if the object originates in a different window/iframe, "(obj instanceof Array)" will evaluate false. We added some speed optimizations to avoid Object.prototype.toString.call() unless it's absolutely necessary because it's VERY slow (like 20x slower)
var toString = Object.prototype.toString,
array = toString.call([]);
return function(obj) {
@@ -5143,11 +5226,11 @@
* <script>
* var gs = window.GreenSockGlobals = {}; //the newer version we're about to load could now be referenced in a "gs" object, like gs.TweenLite.to(...). Use whatever alias you want as long as it's unique, "gs" or "banner" or whatever.
* </script>
* <script src="js/greensock/v1.7/TweenMax.js"></script>
* <script>
- * window.GreenSockGlobals = null; //reset it back to null so that the next load of TweenMax affects the window and we can reference things directly like TweenLite.to(...)
+ * window.GreenSockGlobals = window._gsQueue = null; //reset it back to null (along with the special _gsQueue variable) so that the next load of TweenMax affects the window and we can reference things directly like TweenLite.to(...)
* </script>
* <script src="js/greensock/v1.6/TweenMax.js"></script>
* <script>
* gs.TweenLite.to(...); //would use v1.7
* TweenLite.to(...); //would use v1.6
@@ -5183,12 +5266,12 @@
//exports to multiple environments
if (global) {
_globals[n] = cl; //provides a way to avoid global namespace pollution. By default, the main classes like TweenLite, Power1, Strong, etc. are added to window unless a GreenSockGlobals is defined. So if you want to have things added to a custom object instead, just do something like window.GreenSockGlobals = {} before loading any GreenSock files. You can even set up an alias like window.GreenSockGlobals = windows.gs = {} so that you can access everything like gs.TweenLite. Also remember that ALL classes are added to the window.com.greensock object (in their respective packages, like com.greensock.easing.Power1, com.greensock.TweenLite, etc.)
if (typeof(define) === "function" && define.amd){ //AMD
- define((window.GreenSockAMDPath ? window.GreenSockAMDPath + "/" : "") + ns.split(".").join("/"), [], function() { return cl; });
- } else if (typeof(module) !== "undefined" && module.exports){ //node
+ define((window.GreenSockAMDPath ? window.GreenSockAMDPath + "/" : "") + ns.split(".").pop(), [], function() { return cl; });
+ } else if (ns === moduleName && typeof(module) !== "undefined" && module.exports){ //node
module.exports = cl;
}
}
for (i = 0; i < this.sc.length; i++) {
this.sc[i].check();
@@ -5845,11 +5928,10 @@
p._remove = function(tween, skipDisable) {
if (tween.timeline === this) {
if (!skipDisable) {
tween._enabled(false, true);
}
- tween.timeline = null;
if (tween._prev) {
tween._prev._next = tween._next;
} else if (this._first === tween) {
this._first = tween._next;
@@ -5857,10 +5939,11 @@
if (tween._next) {
tween._next._prev = tween._prev;
} else if (this._last === tween) {
this._last = tween._prev;
}
+ tween._next = tween._prev = tween.timeline = null;
if (this._timeline) {
this._uncache(true);
}
}
@@ -5911,11 +5994,11 @@
i, targ, targets;
this._overwrite = overwrite = (overwrite == null) ? _overwriteLookup[TweenLite.defaultOverwrite] : (typeof(overwrite) === "number") ? overwrite >> 0 : _overwriteLookup[overwrite];
if ((isSelector || target instanceof Array || (target.push && _isArray(target))) && typeof(target[0]) !== "number") {
- this._targets = targets = _slice.call(target, 0);
+ this._targets = targets = _slice(target); //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
this._propLookup = [];
this._siblings = [];
for (i = 0; i < targets.length; i++) {
targ = targets[i];
if (!targ) {
@@ -5927,11 +6010,11 @@
targets.splice(i+1, 1); //to avoid an endless loop (can't imagine why the selector would return a string, but just in case)
}
continue;
} else if (targ.length && targ !== window && targ[0] && (targ[0] === window || (targ[0].nodeType && targ[0].style && !targ.nodeType))) { //in case the user is passing in an array of selector objects (like jQuery objects), we need to check one more level and pull things out if necessary. Also note that <select> elements pass all the criteria regarding length and the first child having style, so we must also check to ensure the target isn't an HTML node itself.
targets.splice(i--, 1);
- this._targets = targets = targets.concat(_slice.call(targ, 0));
+ this._targets = targets = targets.concat(_slice(targ));
continue;
}
this._siblings[i] = _register(targ, this, false);
if (overwrite === 1) if (this._siblings[i].length > 1) {
_applyOverwrite(targ, this, null, 1, this._siblings[i]);
@@ -5973,31 +6056,39 @@
p.ratio = 0;
p._firstPT = p._targets = p._overwrittenProps = p._startAt = null;
p._notifyPluginsOfEnabled = p._lazy = false;
- TweenLite.version = "1.12.1";
+ TweenLite.version = "1.13.1";
TweenLite.defaultEase = p._ease = new Ease(null, null, 1, 1);
TweenLite.defaultOverwrite = "auto";
TweenLite.ticker = _ticker;
TweenLite.autoSleep = true;
TweenLite.lagSmoothing = function(threshold, adjustedLag) {
_ticker.lagSmoothing(threshold, adjustedLag);
};
- TweenLite.selector = window.$ || window.jQuery || function(e) { if (window.$) { TweenLite.selector = window.$; return window.$(e); } return window.document ? window.document.getElementById((e.charAt(0) === "#") ? e.substr(1) : e) : e; };
+ TweenLite.selector = window.$ || window.jQuery || function(e) {
+ var selector = window.$ || window.jQuery;
+ if (selector) {
+ TweenLite.selector = selector;
+ return selector(e);
+ }
+ return (typeof(document) === "undefined") ? e : (document.querySelectorAll ? document.querySelectorAll(e) : document.getElementById((e.charAt(0) === "#") ? e.substr(1) : e));
+ };
+
var _lazyTweens = [],
_lazyLookup = {},
_internals = TweenLite._internals = {isArray:_isArray, isSelector:_isSelector, lazyTweens:_lazyTweens}, //gives us a way to expose certain private values to other GreenSock classes without contaminating tha main TweenLite object.
_plugins = TweenLite._plugins = {},
_tweenLookup = _internals.tweenLookup = {},
_tweenLookupNum = 0,
_reservedProps = _internals.reservedProps = {ease:1, delay:1, overwrite:1, onComplete:1, onCompleteParams:1, onCompleteScope:1, useFrames:1, runBackwards:1, startAt:1, onUpdate:1, onUpdateParams:1, onUpdateScope:1, onStart:1, onStartParams:1, onStartScope:1, onReverseComplete:1, onReverseCompleteParams:1, onReverseCompleteScope:1, onRepeat:1, onRepeatParams:1, onRepeatScope:1, easeParams:1, yoyo:1, immediateRender:1, repeat:1, repeatDelay:1, data:1, paused:1, reversed:1, autoCSS:1, lazy:1},
_overwriteLookup = {none:0, all:1, auto:2, concurrent:3, allOnStart:4, preexisting:5, "true":1, "false":0},
_rootFramesTimeline = Animation._rootFramesTimeline = new SimpleTimeline(),
_rootTimeline = Animation._rootTimeline = new SimpleTimeline(),
- _lazyRender = function() {
+ _lazyRender = _internals.lazyRender = function() {
var i = _lazyTweens.length;
_lazyLookup = {};
while (--i > -1) {
a = _lazyTweens[i];
if (a && a._lazy !== false) {
@@ -6191,16 +6282,13 @@
} else if (this._time === 0) {
return;
}
}
}
- if (!ease) {
- this._ease = TweenLite.defaultEase;
- } else if (ease instanceof Ease) {
- this._ease = (v.easeParams instanceof Array) ? ease.config.apply(ease, v.easeParams) : ease;
- } else {
- this._ease = (typeof(ease) === "function") ? new Ease(ease, v.easeParams) : _easeMap[ease] || TweenLite.defaultEase;
+ this._ease = ease = (!ease) ? TweenLite.defaultEase : (ease instanceof Ease) ? ease : (typeof(ease) === "function") ? new Ease(ease, v.easeParams) : _easeMap[ease] || TweenLite.defaultEase;
+ if (v.easeParams instanceof Array && ease.config) {
+ this._ease = ease.config.apply(ease, v.easeParams);
}
this._easeType = this._ease._type;
this._easePower = this._ease._power;
this._firstPT = null;
@@ -6395,11 +6483,11 @@
this.ratio = this._ease.getRatio(this._time / duration);
} else if (isComplete && this._ease._calcEnd) {
this.ratio = this._ease.getRatio((this._time === 0) ? 0 : 1);
}
}
- if (this._lazy !== false) { //in case a lazy render is pending, we should flush it because the new render is occuring now (imagine a lazy tween instantiating and then immediately the user calls tween.seek(tween.duration()), skipping to the end - the end render would be forced, and then if we didn't flush the lazy render, it'd fire AFTER the seek(), rendering it at the wrong time.
+ if (this._lazy !== false) { //in case a lazy render is pending, we should flush it because the new render is occurring now (imagine a lazy tween instantiating and then immediately the user calls tween.seek(tween.duration()), skipping to the end - the end render would be forced, and then if we didn't flush the lazy render, it'd fire AFTER the seek(), rendering it at the wrong time.
this._lazy = false;
}
if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) {
this._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.
}
@@ -6413,11 +6501,10 @@
}
if (this.vars.onStart) if (this._time !== 0 || duration === 0) if (!suppressEvents) {
this.vars.onStart.apply(this.vars.onStartScope || this, this.vars.onStartParams || _blankArray);
}
}
-
pt = this._firstPT;
while (pt) {
if (pt.f) {
pt.t[pt.p](pt.c * this.ratio + pt.s);
} else {
@@ -6433,11 +6520,11 @@
if (!suppressEvents) if (this._time !== prevTime || isComplete) {
this._onUpdate.apply(this.vars.onUpdateScope || this, this.vars.onUpdateParams || _blankArray);
}
}
- if (callback) if (!this._gc) { //check _gc because there's a chance that kill() could be called in an onUpdate
+ if (callback) if (!this._gc || force) { //check _gc because there's a chance that kill() could be called in an onUpdate
if (time < 0 && this._startAt && !this._onUpdate && this._startTime) { //if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values.
this._startAt.render(time, suppressEvents, force);
}
if (isComplete) {
if (this._timeline.autoRemoveChildren) {
@@ -6450,11 +6537,10 @@
}
if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) { //the onComplete or onReverseComplete could trigger movement of the playhead and for zero-duration tweens (which must discern direction) that land directly back on their start time, we don't want to fire again on the next render. Think of several addPause()'s in a timeline that forces the playhead to a certain spot, but what if it's already paused and another tween is tweening the "time" of the timeline? Each time it moves [forward] past that spot, it would move back, and since suppressEvents is true, it'd reset _rawPrevTime to _tinyNum so that when it begins again, the callback would fire (so ultimately it could bounce back and forth during that tween). Again, this is a very uncommon scenario, but possible nonetheless.
this._rawPrevTime = 0;
}
}
-
};
p._kill = function(vars, target) {
if (vars === "all") {
vars = null;
@@ -6806,6 +6892,6 @@
}
}
_tickerActive = false; //ensures that the first official animation forces a ticker.tick() to update the time when it is instantiated
-})(window);
+})((typeof(module) !== "undefined" && module.exports && typeof(global) !== "undefined") ? global : this || window, "TweenMax");
\ No newline at end of file