UNPKG

56.9 kBJavaScriptView Raw
1/*!
2 * CSSPlugin 3.10.3
3 * https://greensock.com
4 *
5 * Copyright 2008-2022, GreenSock. All rights reserved.
6 * Subject to the terms at https://greensock.com/standard-license or for
7 * Club GreenSock members, the agreement issued with that membership.
8 * @author: Jack Doyle, jack@greensock.com
9*/
10
11/* eslint-disable */
12import { gsap, _getProperty, _numExp, _numWithUnitExp, getUnit, _isString, _isUndefined, _renderComplexString, _relExp, _forEachName, _sortPropTweensByPriority, _colorStringFilter, _checkPlugin, _replaceRandom, _plugins, GSCache, PropTween, _config, _ticker, _round, _missingPlugin, _getSetter, _getCache, _colorExp, _parseRelative, _setDefaults, _removeLinkedListItem //for the commented-out className feature.
13} from "./gsap-core.js";
14
15var _win,
16 _doc,
17 _docElement,
18 _pluginInitted,
19 _tempDiv,
20 _tempDivStyler,
21 _recentSetterPlugin,
22 _windowExists = function _windowExists() {
23 return typeof window !== "undefined";
24},
25 _transformProps = {},
26 _RAD2DEG = 180 / Math.PI,
27 _DEG2RAD = Math.PI / 180,
28 _atan2 = Math.atan2,
29 _bigNum = 1e8,
30 _capsExp = /([A-Z])/g,
31 _horizontalExp = /(left|right|width|margin|padding|x)/i,
32 _complexExp = /[\s,\(]\S/,
33 _propertyAliases = {
34 autoAlpha: "opacity,visibility",
35 scale: "scaleX,scaleY",
36 alpha: "opacity"
37},
38 _renderCSSProp = function _renderCSSProp(ratio, data) {
39 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data);
40},
41 _renderPropWithEnd = function _renderPropWithEnd(ratio, data) {
42 return data.set(data.t, data.p, ratio === 1 ? data.e : Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data);
43},
44 _renderCSSPropWithBeginning = function _renderCSSPropWithBeginning(ratio, data) {
45 return data.set(data.t, data.p, ratio ? Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u : data.b, data);
46},
47 //if units change, we need a way to render the original unit/value when the tween goes all the way back to the beginning (ratio:0)
48_renderRoundedCSSProp = function _renderRoundedCSSProp(ratio, data) {
49 var value = data.s + data.c * ratio;
50 data.set(data.t, data.p, ~~(value + (value < 0 ? -.5 : .5)) + data.u, data);
51},
52 _renderNonTweeningValue = function _renderNonTweeningValue(ratio, data) {
53 return data.set(data.t, data.p, ratio ? data.e : data.b, data);
54},
55 _renderNonTweeningValueOnlyAtEnd = function _renderNonTweeningValueOnlyAtEnd(ratio, data) {
56 return data.set(data.t, data.p, ratio !== 1 ? data.b : data.e, data);
57},
58 _setterCSSStyle = function _setterCSSStyle(target, property, value) {
59 return target.style[property] = value;
60},
61 _setterCSSProp = function _setterCSSProp(target, property, value) {
62 return target.style.setProperty(property, value);
63},
64 _setterTransform = function _setterTransform(target, property, value) {
65 return target._gsap[property] = value;
66},
67 _setterScale = function _setterScale(target, property, value) {
68 return target._gsap.scaleX = target._gsap.scaleY = value;
69},
70 _setterScaleWithRender = function _setterScaleWithRender(target, property, value, data, ratio) {
71 var cache = target._gsap;
72 cache.scaleX = cache.scaleY = value;
73 cache.renderTransform(ratio, cache);
74},
75 _setterTransformWithRender = function _setterTransformWithRender(target, property, value, data, ratio) {
76 var cache = target._gsap;
77 cache[property] = value;
78 cache.renderTransform(ratio, cache);
79},
80 _transformProp = "transform",
81 _transformOriginProp = _transformProp + "Origin",
82 _supports3D,
83 _createElement = function _createElement(type, ns) {
84 var e = _doc.createElementNS ? _doc.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc.createElement(type); //some servers swap in https for http in the namespace which can break things, making "style" inaccessible.
85
86 return e.style ? e : _doc.createElement(type); //some environments won't allow access to the element's style when created with a namespace in which case we default to the standard createElement() to work around the issue. Also note that when GSAP is embedded directly inside an SVG file, createElement() won't allow access to the style object in Firefox (see https://greensock.com/forums/topic/20215-problem-using-tweenmax-in-standalone-self-containing-svg-file-err-cannot-set-property-csstext-of-undefined/).
87},
88 _getComputedProperty = function _getComputedProperty(target, property, skipPrefixFallback) {
89 var cs = getComputedStyle(target);
90 return cs[property] || cs.getPropertyValue(property.replace(_capsExp, "-$1").toLowerCase()) || cs.getPropertyValue(property) || !skipPrefixFallback && _getComputedProperty(target, _checkPropPrefix(property) || property, 1) || ""; //css variables may not need caps swapped out for dashes and lowercase.
91},
92 _prefixes = "O,Moz,ms,Ms,Webkit".split(","),
93 _checkPropPrefix = function _checkPropPrefix(property, element, preferPrefix) {
94 var e = element || _tempDiv,
95 s = e.style,
96 i = 5;
97
98 if (property in s && !preferPrefix) {
99 return property;
100 }
101
102 property = property.charAt(0).toUpperCase() + property.substr(1);
103
104 while (i-- && !(_prefixes[i] + property in s)) {}
105
106 return i < 0 ? null : (i === 3 ? "ms" : i >= 0 ? _prefixes[i] : "") + property;
107},
108 _initCore = function _initCore() {
109 if (_windowExists() && window.document) {
110 _win = window;
111 _doc = _win.document;
112 _docElement = _doc.documentElement;
113 _tempDiv = _createElement("div") || {
114 style: {}
115 };
116 _tempDivStyler = _createElement("div");
117 _transformProp = _checkPropPrefix(_transformProp);
118 _transformOriginProp = _transformProp + "Origin";
119 _tempDiv.style.cssText = "border-width:0;line-height:0;position:absolute;padding:0"; //make sure to override certain properties that may contaminate measurements, in case the user has overreaching style sheets.
120
121 _supports3D = !!_checkPropPrefix("perspective");
122 _pluginInitted = 1;
123 }
124},
125 _getBBoxHack = function _getBBoxHack(swapIfPossible) {
126 //works around issues in some browsers (like Firefox) that don't correctly report getBBox() on SVG elements inside a <defs> element and/or <mask>. We try creating an SVG, adding it to the documentElement and toss the element in there so that it's definitely part of the rendering tree, then grab the bbox and if it works, we actually swap out the original getBBox() method for our own that does these extra steps whenever getBBox is needed. This helps ensure that performance is optimal (only do all these extra steps when absolutely necessary...most elements don't need it).
127 var svg = _createElement("svg", this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"),
128 oldParent = this.parentNode,
129 oldSibling = this.nextSibling,
130 oldCSS = this.style.cssText,
131 bbox;
132
133 _docElement.appendChild(svg);
134
135 svg.appendChild(this);
136 this.style.display = "block";
137
138 if (swapIfPossible) {
139 try {
140 bbox = this.getBBox();
141 this._gsapBBox = this.getBBox; //store the original
142
143 this.getBBox = _getBBoxHack;
144 } catch (e) {}
145 } else if (this._gsapBBox) {
146 bbox = this._gsapBBox();
147 }
148
149 if (oldParent) {
150 if (oldSibling) {
151 oldParent.insertBefore(this, oldSibling);
152 } else {
153 oldParent.appendChild(this);
154 }
155 }
156
157 _docElement.removeChild(svg);
158
159 this.style.cssText = oldCSS;
160 return bbox;
161},
162 _getAttributeFallbacks = function _getAttributeFallbacks(target, attributesArray) {
163 var i = attributesArray.length;
164
165 while (i--) {
166 if (target.hasAttribute(attributesArray[i])) {
167 return target.getAttribute(attributesArray[i]);
168 }
169 }
170},
171 _getBBox = function _getBBox(target) {
172 var bounds;
173
174 try {
175 bounds = target.getBBox(); //Firefox throws errors if you try calling getBBox() on an SVG element that's not rendered (like in a <symbol> or <defs>). https://bugzilla.mozilla.org/show_bug.cgi?id=612118
176 } catch (error) {
177 bounds = _getBBoxHack.call(target, true);
178 }
179
180 bounds && (bounds.width || bounds.height) || target.getBBox === _getBBoxHack || (bounds = _getBBoxHack.call(target, true)); //some browsers (like Firefox) misreport the bounds if the element has zero width and height (it just assumes it's at x:0, y:0), thus we need to manually grab the position in that case.
181
182 return bounds && !bounds.width && !bounds.x && !bounds.y ? {
183 x: +_getAttributeFallbacks(target, ["x", "cx", "x1"]) || 0,
184 y: +_getAttributeFallbacks(target, ["y", "cy", "y1"]) || 0,
185 width: 0,
186 height: 0
187 } : bounds;
188},
189 _isSVG = function _isSVG(e) {
190 return !!(e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e));
191},
192 //reports if the element is an SVG on which getBBox() actually works
193_removeProperty = function _removeProperty(target, property) {
194 if (property) {
195 var style = target.style;
196
197 if (property in _transformProps && property !== _transformOriginProp) {
198 property = _transformProp;
199 }
200
201 if (style.removeProperty) {
202 if (property.substr(0, 2) === "ms" || property.substr(0, 6) === "webkit") {
203 //Microsoft and some Webkit browsers don't conform to the standard of capitalizing the first prefix character, so we adjust so that when we prefix the caps with a dash, it's correct (otherwise it'd be "ms-transform" instead of "-ms-transform" for IE9, for example)
204 property = "-" + property;
205 }
206
207 style.removeProperty(property.replace(_capsExp, "-$1").toLowerCase());
208 } else {
209 //note: old versions of IE use "removeAttribute()" instead of "removeProperty()"
210 style.removeAttribute(property);
211 }
212 }
213},
214 _addNonTweeningPT = function _addNonTweeningPT(plugin, target, property, beginning, end, onlySetAtEnd) {
215 var pt = new PropTween(plugin._pt, target, property, 0, 1, onlySetAtEnd ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue);
216 plugin._pt = pt;
217 pt.b = beginning;
218 pt.e = end;
219
220 plugin._props.push(property);
221
222 return pt;
223},
224 _nonConvertibleUnits = {
225 deg: 1,
226 rad: 1,
227 turn: 1
228},
229 //takes a single value like 20px and converts it to the unit specified, like "%", returning only the numeric amount.
230_convertToUnit = function _convertToUnit(target, property, value, unit) {
231 var curValue = parseFloat(value) || 0,
232 curUnit = (value + "").trim().substr((curValue + "").length) || "px",
233 // some browsers leave extra whitespace at the beginning of CSS variables, hence the need to trim()
234 style = _tempDiv.style,
235 horizontal = _horizontalExp.test(property),
236 isRootSVG = target.tagName.toLowerCase() === "svg",
237 measureProperty = (isRootSVG ? "client" : "offset") + (horizontal ? "Width" : "Height"),
238 amount = 100,
239 toPixels = unit === "px",
240 toPercent = unit === "%",
241 px,
242 parent,
243 cache,
244 isSVG;
245
246 if (unit === curUnit || !curValue || _nonConvertibleUnits[unit] || _nonConvertibleUnits[curUnit]) {
247 return curValue;
248 }
249
250 curUnit !== "px" && !toPixels && (curValue = _convertToUnit(target, property, value, "px"));
251 isSVG = target.getCTM && _isSVG(target);
252
253 if ((toPercent || curUnit === "%") && (_transformProps[property] || ~property.indexOf("adius"))) {
254 px = isSVG ? target.getBBox()[horizontal ? "width" : "height"] : target[measureProperty];
255 return _round(toPercent ? curValue / px * amount : curValue / 100 * px);
256 }
257
258 style[horizontal ? "width" : "height"] = amount + (toPixels ? curUnit : unit);
259 parent = ~property.indexOf("adius") || unit === "em" && target.appendChild && !isRootSVG ? target : target.parentNode;
260
261 if (isSVG) {
262 parent = (target.ownerSVGElement || {}).parentNode;
263 }
264
265 if (!parent || parent === _doc || !parent.appendChild) {
266 parent = _doc.body;
267 }
268
269 cache = parent._gsap;
270
271 if (cache && toPercent && cache.width && horizontal && cache.time === _ticker.time) {
272 return _round(curValue / cache.width * amount);
273 } else {
274 (toPercent || curUnit === "%") && (style.position = _getComputedProperty(target, "position"));
275 parent === target && (style.position = "static"); // like for borderRadius, if it's a % we must have it relative to the target itself but that may not have position: relative or position: absolute in which case it'd go up the chain until it finds its offsetParent (bad). position: static protects against that.
276
277 parent.appendChild(_tempDiv);
278 px = _tempDiv[measureProperty];
279 parent.removeChild(_tempDiv);
280 style.position = "absolute";
281
282 if (horizontal && toPercent) {
283 cache = _getCache(parent);
284 cache.time = _ticker.time;
285 cache.width = parent[measureProperty];
286 }
287 }
288
289 return _round(toPixels ? px * curValue / amount : px && curValue ? amount / px * curValue : 0);
290},
291 _get = function _get(target, property, unit, uncache) {
292 var value;
293 _pluginInitted || _initCore();
294
295 if (property in _propertyAliases && property !== "transform") {
296 property = _propertyAliases[property];
297
298 if (~property.indexOf(",")) {
299 property = property.split(",")[0];
300 }
301 }
302
303 if (_transformProps[property] && property !== "transform") {
304 value = _parseTransform(target, uncache);
305 value = property !== "transformOrigin" ? value[property] : value.svg ? value.origin : _firstTwoOnly(_getComputedProperty(target, _transformOriginProp)) + " " + value.zOrigin + "px";
306 } else {
307 value = target.style[property];
308
309 if (!value || value === "auto" || uncache || ~(value + "").indexOf("calc(")) {
310 value = _specialProps[property] && _specialProps[property](target, property, unit) || _getComputedProperty(target, property) || _getProperty(target, property) || (property === "opacity" ? 1 : 0); // note: some browsers, like Firefox, don't report borderRadius correctly! Instead, it only reports every corner like borderTopLeftRadius
311 }
312 }
313
314 return unit && !~(value + "").trim().indexOf(" ") ? _convertToUnit(target, property, value, unit) + unit : value;
315},
316 _tweenComplexCSSString = function _tweenComplexCSSString(target, prop, start, end) {
317 // note: we call _tweenComplexCSSString.call(pluginInstance...) to ensure that it's scoped properly. We may call it from within a plugin too, thus "this" would refer to the plugin.
318 if (!start || start === "none") {
319 // some browsers like Safari actually PREFER the prefixed property and mis-report the unprefixed value like clipPath (BUG). In other words, even though clipPath exists in the style ("clipPath" in target.style) and it's set in the CSS properly (along with -webkit-clip-path), Safari reports clipPath as "none" whereas WebkitClipPath reports accurately like "ellipse(100% 0% at 50% 0%)", so in this case we must SWITCH to using the prefixed property instead. See https://greensock.com/forums/topic/18310-clippath-doesnt-work-on-ios/
320 var p = _checkPropPrefix(prop, target, 1),
321 s = p && _getComputedProperty(target, p, 1);
322
323 if (s && s !== start) {
324 prop = p;
325 start = s;
326 } else if (prop === "borderColor") {
327 start = _getComputedProperty(target, "borderTopColor"); // Firefox bug: always reports "borderColor" as "", so we must fall back to borderTopColor. See https://greensock.com/forums/topic/24583-how-to-return-colors-that-i-had-after-reverse/
328 }
329 }
330
331 var pt = new PropTween(this._pt, target.style, prop, 0, 1, _renderComplexString),
332 index = 0,
333 matchIndex = 0,
334 a,
335 result,
336 startValues,
337 startNum,
338 color,
339 startValue,
340 endValue,
341 endNum,
342 chunk,
343 endUnit,
344 startUnit,
345 endValues;
346 pt.b = start;
347 pt.e = end;
348 start += ""; // ensure values are strings
349
350 end += "";
351
352 if (end === "auto") {
353 target.style[prop] = end;
354 end = _getComputedProperty(target, prop) || end;
355 target.style[prop] = start;
356 }
357
358 a = [start, end];
359
360 _colorStringFilter(a); // pass an array with the starting and ending values and let the filter do whatever it needs to the values. If colors are found, it returns true and then we must match where the color shows up order-wise because for things like boxShadow, sometimes the browser provides the computed values with the color FIRST, but the user provides it with the color LAST, so flip them if necessary. Same for drop-shadow().
361
362
363 start = a[0];
364 end = a[1];
365 startValues = start.match(_numWithUnitExp) || [];
366 endValues = end.match(_numWithUnitExp) || [];
367
368 if (endValues.length) {
369 while (result = _numWithUnitExp.exec(end)) {
370 endValue = result[0];
371 chunk = end.substring(index, result.index);
372
373 if (color) {
374 color = (color + 1) % 5;
375 } else if (chunk.substr(-5) === "rgba(" || chunk.substr(-5) === "hsla(") {
376 color = 1;
377 }
378
379 if (endValue !== (startValue = startValues[matchIndex++] || "")) {
380 startNum = parseFloat(startValue) || 0;
381 startUnit = startValue.substr((startNum + "").length);
382 endValue.charAt(1) === "=" && (endValue = _parseRelative(startNum, endValue) + startUnit);
383 endNum = parseFloat(endValue);
384 endUnit = endValue.substr((endNum + "").length);
385 index = _numWithUnitExp.lastIndex - endUnit.length;
386
387 if (!endUnit) {
388 //if something like "perspective:300" is passed in and we must add a unit to the end
389 endUnit = endUnit || _config.units[prop] || startUnit;
390
391 if (index === end.length) {
392 end += endUnit;
393 pt.e += endUnit;
394 }
395 }
396
397 if (startUnit !== endUnit) {
398 startNum = _convertToUnit(target, prop, startValue, endUnit) || 0;
399 } // these nested PropTweens are handled in a special way - we'll never actually call a render or setter method on them. We'll just loop through them in the parent complex string PropTween's render method.
400
401
402 pt._pt = {
403 _next: pt._pt,
404 p: chunk || matchIndex === 1 ? chunk : ",",
405 //note: SVG spec allows omission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case.
406 s: startNum,
407 c: endNum - startNum,
408 m: color && color < 4 || prop === "zIndex" ? Math.round : 0
409 };
410 }
411 }
412
413 pt.c = index < end.length ? end.substring(index, end.length) : ""; //we use the "c" of the PropTween to store the final part of the string (after the last number)
414 } else {
415 pt.r = prop === "display" && end === "none" ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue;
416 }
417
418 _relExp.test(end) && (pt.e = 0); //if the end string contains relative values or dynamic random(...) values, delete the end it so that on the final render we don't actually set it to the string with += or -= characters (forces it to use the calculated value).
419
420 this._pt = pt; //start the linked list with this new PropTween. Remember, we call _tweenComplexCSSString.call(pluginInstance...) to ensure that it's scoped properly. We may call it from within another plugin too, thus "this" would refer to the plugin.
421
422 return pt;
423},
424 _keywordToPercent = {
425 top: "0%",
426 bottom: "100%",
427 left: "0%",
428 right: "100%",
429 center: "50%"
430},
431 _convertKeywordsToPercentages = function _convertKeywordsToPercentages(value) {
432 var split = value.split(" "),
433 x = split[0],
434 y = split[1] || "50%";
435
436 if (x === "top" || x === "bottom" || y === "left" || y === "right") {
437 //the user provided them in the wrong order, so flip them
438 value = x;
439 x = y;
440 y = value;
441 }
442
443 split[0] = _keywordToPercent[x] || x;
444 split[1] = _keywordToPercent[y] || y;
445 return split.join(" ");
446},
447 _renderClearProps = function _renderClearProps(ratio, data) {
448 if (data.tween && data.tween._time === data.tween._dur) {
449 var target = data.t,
450 style = target.style,
451 props = data.u,
452 cache = target._gsap,
453 prop,
454 clearTransforms,
455 i;
456
457 if (props === "all" || props === true) {
458 style.cssText = "";
459 clearTransforms = 1;
460 } else {
461 props = props.split(",");
462 i = props.length;
463
464 while (--i > -1) {
465 prop = props[i];
466
467 if (_transformProps[prop]) {
468 clearTransforms = 1;
469 prop = prop === "transformOrigin" ? _transformOriginProp : _transformProp;
470 }
471
472 _removeProperty(target, prop);
473 }
474 }
475
476 if (clearTransforms) {
477 _removeProperty(target, _transformProp);
478
479 if (cache) {
480 cache.svg && target.removeAttribute("transform");
481
482 _parseTransform(target, 1); // force all the cached values back to "normal"/identity, otherwise if there's another tween that's already set to render transforms on this element, it could display the wrong values.
483
484
485 cache.uncache = 1;
486 }
487 }
488 }
489},
490 // note: specialProps should return 1 if (and only if) they have a non-zero priority. It indicates we need to sort the linked list.
491_specialProps = {
492 clearProps: function clearProps(plugin, target, property, endValue, tween) {
493 if (tween.data !== "isFromStart") {
494 var pt = plugin._pt = new PropTween(plugin._pt, target, property, 0, 0, _renderClearProps);
495 pt.u = endValue;
496 pt.pr = -10;
497 pt.tween = tween;
498
499 plugin._props.push(property);
500
501 return 1;
502 }
503 }
504 /* className feature (about 0.4kb gzipped).
505 , className(plugin, target, property, endValue, tween) {
506 let _renderClassName = (ratio, data) => {
507 data.css.render(ratio, data.css);
508 if (!ratio || ratio === 1) {
509 let inline = data.rmv,
510 target = data.t,
511 p;
512 target.setAttribute("class", ratio ? data.e : data.b);
513 for (p in inline) {
514 _removeProperty(target, p);
515 }
516 }
517 },
518 _getAllStyles = (target) => {
519 let styles = {},
520 computed = getComputedStyle(target),
521 p;
522 for (p in computed) {
523 if (isNaN(p) && p !== "cssText" && p !== "length") {
524 styles[p] = computed[p];
525 }
526 }
527 _setDefaults(styles, _parseTransform(target, 1));
528 return styles;
529 },
530 startClassList = target.getAttribute("class"),
531 style = target.style,
532 cssText = style.cssText,
533 cache = target._gsap,
534 classPT = cache.classPT,
535 inlineToRemoveAtEnd = {},
536 data = {t:target, plugin:plugin, rmv:inlineToRemoveAtEnd, b:startClassList, e:(endValue.charAt(1) !== "=") ? endValue : startClassList.replace(new RegExp("(?:\\s|^)" + endValue.substr(2) + "(?![\\w-])"), "") + ((endValue.charAt(0) === "+") ? " " + endValue.substr(2) : "")},
537 changingVars = {},
538 startVars = _getAllStyles(target),
539 transformRelated = /(transform|perspective)/i,
540 endVars, p;
541 if (classPT) {
542 classPT.r(1, classPT.d);
543 _removeLinkedListItem(classPT.d.plugin, classPT, "_pt");
544 }
545 target.setAttribute("class", data.e);
546 endVars = _getAllStyles(target, true);
547 target.setAttribute("class", startClassList);
548 for (p in endVars) {
549 if (endVars[p] !== startVars[p] && !transformRelated.test(p)) {
550 changingVars[p] = endVars[p];
551 if (!style[p] && style[p] !== "0") {
552 inlineToRemoveAtEnd[p] = 1;
553 }
554 }
555 }
556 cache.classPT = plugin._pt = new PropTween(plugin._pt, target, "className", 0, 0, _renderClassName, data, 0, -11);
557 if (style.cssText !== cssText) { //only apply if things change. Otherwise, in cases like a background-image that's pulled dynamically, it could cause a refresh. See https://greensock.com/forums/topic/20368-possible-gsap-bug-switching-classnames-in-chrome/.
558 style.cssText = cssText; //we recorded cssText before we swapped classes and ran _getAllStyles() because in cases when a className tween is overwritten, we remove all the related tweening properties from that class change (otherwise class-specific stuff can't override properties we've directly set on the target's style object due to specificity).
559 }
560 _parseTransform(target, true); //to clear the caching of transforms
561 data.css = new gsap.plugins.css();
562 data.css.init(target, changingVars, tween);
563 plugin._props.push(...data.css._props);
564 return 1;
565 }
566 */
567
568},
569
570/*
571 * --------------------------------------------------------------------------------------
572 * TRANSFORMS
573 * --------------------------------------------------------------------------------------
574 */
575_identity2DMatrix = [1, 0, 0, 1, 0, 0],
576 _rotationalProperties = {},
577 _isNullTransform = function _isNullTransform(value) {
578 return value === "matrix(1, 0, 0, 1, 0, 0)" || value === "none" || !value;
579},
580 _getComputedTransformMatrixAsArray = function _getComputedTransformMatrixAsArray(target) {
581 var matrixString = _getComputedProperty(target, _transformProp);
582
583 return _isNullTransform(matrixString) ? _identity2DMatrix : matrixString.substr(7).match(_numExp).map(_round);
584},
585 _getMatrix = function _getMatrix(target, force2D) {
586 var cache = target._gsap || _getCache(target),
587 style = target.style,
588 matrix = _getComputedTransformMatrixAsArray(target),
589 parent,
590 nextSibling,
591 temp,
592 addedToDOM;
593
594 if (cache.svg && target.getAttribute("transform")) {
595 temp = target.transform.baseVal.consolidate().matrix; //ensures that even complex values like "translate(50,60) rotate(135,0,0)" are parsed because it mashes it into a matrix.
596
597 matrix = [temp.a, temp.b, temp.c, temp.d, temp.e, temp.f];
598 return matrix.join(",") === "1,0,0,1,0,0" ? _identity2DMatrix : matrix;
599 } else if (matrix === _identity2DMatrix && !target.offsetParent && target !== _docElement && !cache.svg) {
600 //note: if offsetParent is null, that means the element isn't in the normal document flow, like if it has display:none or one of its ancestors has display:none). Firefox returns null for getComputedStyle() if the element is in an iframe that has display:none. https://bugzilla.mozilla.org/show_bug.cgi?id=548397
601 //browsers don't report transforms accurately unless the element is in the DOM and has a display value that's not "none". Firefox and Microsoft browsers have a partial bug where they'll report transforms even if display:none BUT not any percentage-based values like translate(-50%, 8px) will be reported as if it's translate(0, 8px).
602 temp = style.display;
603 style.display = "block";
604 parent = target.parentNode;
605
606 if (!parent || !target.offsetParent) {
607 // note: in 3.3.0 we switched target.offsetParent to _doc.body.contains(target) to avoid [sometimes unnecessary] MutationObserver calls but that wasn't adequate because there are edge cases where nested position: fixed elements need to get reparented to accurately sense transforms. See https://github.com/greensock/GSAP/issues/388 and https://github.com/greensock/GSAP/issues/375
608 addedToDOM = 1; //flag
609
610 nextSibling = target.nextSibling;
611
612 _docElement.appendChild(target); //we must add it to the DOM in order to get values properly
613
614 }
615
616 matrix = _getComputedTransformMatrixAsArray(target);
617 temp ? style.display = temp : _removeProperty(target, "display");
618
619 if (addedToDOM) {
620 nextSibling ? parent.insertBefore(target, nextSibling) : parent ? parent.appendChild(target) : _docElement.removeChild(target);
621 }
622 }
623
624 return force2D && matrix.length > 6 ? [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]] : matrix;
625},
626 _applySVGOrigin = function _applySVGOrigin(target, origin, originIsAbsolute, smooth, matrixArray, pluginToAddPropTweensTo) {
627 var cache = target._gsap,
628 matrix = matrixArray || _getMatrix(target, true),
629 xOriginOld = cache.xOrigin || 0,
630 yOriginOld = cache.yOrigin || 0,
631 xOffsetOld = cache.xOffset || 0,
632 yOffsetOld = cache.yOffset || 0,
633 a = matrix[0],
634 b = matrix[1],
635 c = matrix[2],
636 d = matrix[3],
637 tx = matrix[4],
638 ty = matrix[5],
639 originSplit = origin.split(" "),
640 xOrigin = parseFloat(originSplit[0]) || 0,
641 yOrigin = parseFloat(originSplit[1]) || 0,
642 bounds,
643 determinant,
644 x,
645 y;
646
647 if (!originIsAbsolute) {
648 bounds = _getBBox(target);
649 xOrigin = bounds.x + (~originSplit[0].indexOf("%") ? xOrigin / 100 * bounds.width : xOrigin);
650 yOrigin = bounds.y + (~(originSplit[1] || originSplit[0]).indexOf("%") ? yOrigin / 100 * bounds.height : yOrigin);
651 } else if (matrix !== _identity2DMatrix && (determinant = a * d - b * c)) {
652 //if it's zero (like if scaleX and scaleY are zero), skip it to avoid errors with dividing by zero.
653 x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant;
654 y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant;
655 xOrigin = x;
656 yOrigin = y;
657 }
658
659 if (smooth || smooth !== false && cache.smooth) {
660 tx = xOrigin - xOriginOld;
661 ty = yOrigin - yOriginOld;
662 cache.xOffset = xOffsetOld + (tx * a + ty * c) - tx;
663 cache.yOffset = yOffsetOld + (tx * b + ty * d) - ty;
664 } else {
665 cache.xOffset = cache.yOffset = 0;
666 }
667
668 cache.xOrigin = xOrigin;
669 cache.yOrigin = yOrigin;
670 cache.smooth = !!smooth;
671 cache.origin = origin;
672 cache.originIsAbsolute = !!originIsAbsolute;
673 target.style[_transformOriginProp] = "0px 0px"; //otherwise, if someone sets an origin via CSS, it will likely interfere with the SVG transform attribute ones (because remember, we're baking the origin into the matrix() value).
674
675 if (pluginToAddPropTweensTo) {
676 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOrigin", xOriginOld, xOrigin);
677
678 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOrigin", yOriginOld, yOrigin);
679
680 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOffset", xOffsetOld, cache.xOffset);
681
682 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOffset", yOffsetOld, cache.yOffset);
683 }
684
685 target.setAttribute("data-svg-origin", xOrigin + " " + yOrigin);
686},
687 _parseTransform = function _parseTransform(target, uncache) {
688 var cache = target._gsap || new GSCache(target);
689
690 if ("x" in cache && !uncache && !cache.uncache) {
691 return cache;
692 }
693
694 var style = target.style,
695 invertedScaleX = cache.scaleX < 0,
696 px = "px",
697 deg = "deg",
698 origin = _getComputedProperty(target, _transformOriginProp) || "0",
699 x,
700 y,
701 z,
702 scaleX,
703 scaleY,
704 rotation,
705 rotationX,
706 rotationY,
707 skewX,
708 skewY,
709 perspective,
710 xOrigin,
711 yOrigin,
712 matrix,
713 angle,
714 cos,
715 sin,
716 a,
717 b,
718 c,
719 d,
720 a12,
721 a22,
722 t1,
723 t2,
724 t3,
725 a13,
726 a23,
727 a33,
728 a42,
729 a43,
730 a32;
731 x = y = z = rotation = rotationX = rotationY = skewX = skewY = perspective = 0;
732 scaleX = scaleY = 1;
733 cache.svg = !!(target.getCTM && _isSVG(target));
734 matrix = _getMatrix(target, cache.svg);
735
736 if (cache.svg) {
737 t1 = (!cache.uncache || origin === "0px 0px") && !uncache && target.getAttribute("data-svg-origin"); // if origin is 0,0 and cache.uncache is true, let the recorded data-svg-origin stay. Otherwise, whenever we set cache.uncache to true, we'd need to set element.style.transformOrigin = (cache.xOrigin - bbox.x) + "px " + (cache.yOrigin - bbox.y) + "px". Remember, to work around browser inconsistencies we always force SVG elements' transformOrigin to 0,0 and offset the translation accordingly.
738
739 _applySVGOrigin(target, t1 || origin, !!t1 || cache.originIsAbsolute, cache.smooth !== false, matrix);
740 }
741
742 xOrigin = cache.xOrigin || 0;
743 yOrigin = cache.yOrigin || 0;
744
745 if (matrix !== _identity2DMatrix) {
746 a = matrix[0]; //a11
747
748 b = matrix[1]; //a21
749
750 c = matrix[2]; //a31
751
752 d = matrix[3]; //a41
753
754 x = a12 = matrix[4];
755 y = a22 = matrix[5]; //2D matrix
756
757 if (matrix.length === 6) {
758 scaleX = Math.sqrt(a * a + b * b);
759 scaleY = Math.sqrt(d * d + c * c);
760 rotation = a || b ? _atan2(b, a) * _RAD2DEG : 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).
761
762 skewX = c || d ? _atan2(c, d) * _RAD2DEG + rotation : 0;
763 skewX && (scaleY *= Math.abs(Math.cos(skewX * _DEG2RAD)));
764
765 if (cache.svg) {
766 x -= xOrigin - (xOrigin * a + yOrigin * c);
767 y -= yOrigin - (xOrigin * b + yOrigin * d);
768 } //3D matrix
769
770 } else {
771 a32 = matrix[6];
772 a42 = matrix[7];
773 a13 = matrix[8];
774 a23 = matrix[9];
775 a33 = matrix[10];
776 a43 = matrix[11];
777 x = matrix[12];
778 y = matrix[13];
779 z = matrix[14];
780 angle = _atan2(a32, a33);
781 rotationX = angle * _RAD2DEG; //rotationX
782
783 if (angle) {
784 cos = Math.cos(-angle);
785 sin = Math.sin(-angle);
786 t1 = a12 * cos + a13 * sin;
787 t2 = a22 * cos + a23 * sin;
788 t3 = a32 * cos + a33 * sin;
789 a13 = a12 * -sin + a13 * cos;
790 a23 = a22 * -sin + a23 * cos;
791 a33 = a32 * -sin + a33 * cos;
792 a43 = a42 * -sin + a43 * cos;
793 a12 = t1;
794 a22 = t2;
795 a32 = t3;
796 } //rotationY
797
798
799 angle = _atan2(-c, a33);
800 rotationY = angle * _RAD2DEG;
801
802 if (angle) {
803 cos = Math.cos(-angle);
804 sin = Math.sin(-angle);
805 t1 = a * cos - a13 * sin;
806 t2 = b * cos - a23 * sin;
807 t3 = c * cos - a33 * sin;
808 a43 = d * sin + a43 * cos;
809 a = t1;
810 b = t2;
811 c = t3;
812 } //rotationZ
813
814
815 angle = _atan2(b, a);
816 rotation = angle * _RAD2DEG;
817
818 if (angle) {
819 cos = Math.cos(angle);
820 sin = Math.sin(angle);
821 t1 = a * cos + b * sin;
822 t2 = a12 * cos + a22 * sin;
823 b = b * cos - a * sin;
824 a22 = a22 * cos - a12 * sin;
825 a = t1;
826 a12 = t2;
827 }
828
829 if (rotationX && Math.abs(rotationX) + Math.abs(rotation) > 359.9) {
830 //when rotationY is set, it will often be parsed as 180 degrees different than it should be, and rotationX and rotation both being 180 (it looks the same), so we adjust for that here.
831 rotationX = rotation = 0;
832 rotationY = 180 - rotationY;
833 }
834
835 scaleX = _round(Math.sqrt(a * a + b * b + c * c));
836 scaleY = _round(Math.sqrt(a22 * a22 + a32 * a32));
837 angle = _atan2(a12, a22);
838 skewX = Math.abs(angle) > 0.0002 ? angle * _RAD2DEG : 0;
839 perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0;
840 }
841
842 if (cache.svg) {
843 //sense if there are CSS transforms applied on an SVG element in which case we must overwrite them when rendering. The transform attribute is more reliable cross-browser, but we can't just remove the CSS ones because they may be applied in a CSS rule somewhere (not just inline).
844 t1 = target.getAttribute("transform");
845 cache.forceCSS = target.setAttribute("transform", "") || !_isNullTransform(_getComputedProperty(target, _transformProp));
846 t1 && target.setAttribute("transform", t1);
847 }
848 }
849
850 if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) {
851 if (invertedScaleX) {
852 scaleX *= -1;
853 skewX += rotation <= 0 ? 180 : -180;
854 rotation += rotation <= 0 ? 180 : -180;
855 } else {
856 scaleY *= -1;
857 skewX += skewX <= 0 ? 180 : -180;
858 }
859 }
860
861 uncache = uncache || cache.uncache;
862 cache.x = x - ((cache.xPercent = x && (!uncache && cache.xPercent || (Math.round(target.offsetWidth / 2) === Math.round(-x) ? -50 : 0))) ? target.offsetWidth * cache.xPercent / 100 : 0) + px;
863 cache.y = y - ((cache.yPercent = y && (!uncache && cache.yPercent || (Math.round(target.offsetHeight / 2) === Math.round(-y) ? -50 : 0))) ? target.offsetHeight * cache.yPercent / 100 : 0) + px;
864 cache.z = z + px;
865 cache.scaleX = _round(scaleX);
866 cache.scaleY = _round(scaleY);
867 cache.rotation = _round(rotation) + deg;
868 cache.rotationX = _round(rotationX) + deg;
869 cache.rotationY = _round(rotationY) + deg;
870 cache.skewX = skewX + deg;
871 cache.skewY = skewY + deg;
872 cache.transformPerspective = perspective + px;
873
874 if (cache.zOrigin = parseFloat(origin.split(" ")[2]) || 0) {
875 style[_transformOriginProp] = _firstTwoOnly(origin);
876 }
877
878 cache.xOffset = cache.yOffset = 0;
879 cache.force3D = _config.force3D;
880 cache.renderTransform = cache.svg ? _renderSVGTransforms : _supports3D ? _renderCSSTransforms : _renderNon3DTransforms;
881 cache.uncache = 0;
882 return cache;
883},
884 _firstTwoOnly = function _firstTwoOnly(value) {
885 return (value = value.split(" "))[0] + " " + value[1];
886},
887 //for handling transformOrigin values, stripping out the 3rd dimension
888_addPxTranslate = function _addPxTranslate(target, start, value) {
889 var unit = getUnit(start);
890 return _round(parseFloat(start) + parseFloat(_convertToUnit(target, "x", value + "px", unit))) + unit;
891},
892 _renderNon3DTransforms = function _renderNon3DTransforms(ratio, cache) {
893 cache.z = "0px";
894 cache.rotationY = cache.rotationX = "0deg";
895 cache.force3D = 0;
896
897 _renderCSSTransforms(ratio, cache);
898},
899 _zeroDeg = "0deg",
900 _zeroPx = "0px",
901 _endParenthesis = ") ",
902 _renderCSSTransforms = function _renderCSSTransforms(ratio, cache) {
903 var _ref = cache || this,
904 xPercent = _ref.xPercent,
905 yPercent = _ref.yPercent,
906 x = _ref.x,
907 y = _ref.y,
908 z = _ref.z,
909 rotation = _ref.rotation,
910 rotationY = _ref.rotationY,
911 rotationX = _ref.rotationX,
912 skewX = _ref.skewX,
913 skewY = _ref.skewY,
914 scaleX = _ref.scaleX,
915 scaleY = _ref.scaleY,
916 transformPerspective = _ref.transformPerspective,
917 force3D = _ref.force3D,
918 target = _ref.target,
919 zOrigin = _ref.zOrigin,
920 transforms = "",
921 use3D = force3D === "auto" && ratio && ratio !== 1 || force3D === true; // Safari has a bug that causes it not to render 3D transform-origin values properly, so we force the z origin to 0, record it in the cache, and then do the math here to offset the translate values accordingly (basically do the 3D transform-origin part manually)
922
923
924 if (zOrigin && (rotationX !== _zeroDeg || rotationY !== _zeroDeg)) {
925 var angle = parseFloat(rotationY) * _DEG2RAD,
926 a13 = Math.sin(angle),
927 a33 = Math.cos(angle),
928 cos;
929
930 angle = parseFloat(rotationX) * _DEG2RAD;
931 cos = Math.cos(angle);
932 x = _addPxTranslate(target, x, a13 * cos * -zOrigin);
933 y = _addPxTranslate(target, y, -Math.sin(angle) * -zOrigin);
934 z = _addPxTranslate(target, z, a33 * cos * -zOrigin + zOrigin);
935 }
936
937 if (transformPerspective !== _zeroPx) {
938 transforms += "perspective(" + transformPerspective + _endParenthesis;
939 }
940
941 if (xPercent || yPercent) {
942 transforms += "translate(" + xPercent + "%, " + yPercent + "%) ";
943 }
944
945 if (use3D || x !== _zeroPx || y !== _zeroPx || z !== _zeroPx) {
946 transforms += z !== _zeroPx || use3D ? "translate3d(" + x + ", " + y + ", " + z + ") " : "translate(" + x + ", " + y + _endParenthesis;
947 }
948
949 if (rotation !== _zeroDeg) {
950 transforms += "rotate(" + rotation + _endParenthesis;
951 }
952
953 if (rotationY !== _zeroDeg) {
954 transforms += "rotateY(" + rotationY + _endParenthesis;
955 }
956
957 if (rotationX !== _zeroDeg) {
958 transforms += "rotateX(" + rotationX + _endParenthesis;
959 }
960
961 if (skewX !== _zeroDeg || skewY !== _zeroDeg) {
962 transforms += "skew(" + skewX + ", " + skewY + _endParenthesis;
963 }
964
965 if (scaleX !== 1 || scaleY !== 1) {
966 transforms += "scale(" + scaleX + ", " + scaleY + _endParenthesis;
967 }
968
969 target.style[_transformProp] = transforms || "translate(0, 0)";
970},
971 _renderSVGTransforms = function _renderSVGTransforms(ratio, cache) {
972 var _ref2 = cache || this,
973 xPercent = _ref2.xPercent,
974 yPercent = _ref2.yPercent,
975 x = _ref2.x,
976 y = _ref2.y,
977 rotation = _ref2.rotation,
978 skewX = _ref2.skewX,
979 skewY = _ref2.skewY,
980 scaleX = _ref2.scaleX,
981 scaleY = _ref2.scaleY,
982 target = _ref2.target,
983 xOrigin = _ref2.xOrigin,
984 yOrigin = _ref2.yOrigin,
985 xOffset = _ref2.xOffset,
986 yOffset = _ref2.yOffset,
987 forceCSS = _ref2.forceCSS,
988 tx = parseFloat(x),
989 ty = parseFloat(y),
990 a11,
991 a21,
992 a12,
993 a22,
994 temp;
995
996 rotation = parseFloat(rotation);
997 skewX = parseFloat(skewX);
998 skewY = parseFloat(skewY);
999
1000 if (skewY) {
1001 //for performance reasons, we combine all skewing into the skewX and rotation values. Remember, a skewY of 10 degrees looks the same as a rotation of 10 degrees plus a skewX of 10 degrees.
1002 skewY = parseFloat(skewY);
1003 skewX += skewY;
1004 rotation += skewY;
1005 }
1006
1007 if (rotation || skewX) {
1008 rotation *= _DEG2RAD;
1009 skewX *= _DEG2RAD;
1010 a11 = Math.cos(rotation) * scaleX;
1011 a21 = Math.sin(rotation) * scaleX;
1012 a12 = Math.sin(rotation - skewX) * -scaleY;
1013 a22 = Math.cos(rotation - skewX) * scaleY;
1014
1015 if (skewX) {
1016 skewY *= _DEG2RAD;
1017 temp = Math.tan(skewX - skewY);
1018 temp = Math.sqrt(1 + temp * temp);
1019 a12 *= temp;
1020 a22 *= temp;
1021
1022 if (skewY) {
1023 temp = Math.tan(skewY);
1024 temp = Math.sqrt(1 + temp * temp);
1025 a11 *= temp;
1026 a21 *= temp;
1027 }
1028 }
1029
1030 a11 = _round(a11);
1031 a21 = _round(a21);
1032 a12 = _round(a12);
1033 a22 = _round(a22);
1034 } else {
1035 a11 = scaleX;
1036 a22 = scaleY;
1037 a21 = a12 = 0;
1038 }
1039
1040 if (tx && !~(x + "").indexOf("px") || ty && !~(y + "").indexOf("px")) {
1041 tx = _convertToUnit(target, "x", x, "px");
1042 ty = _convertToUnit(target, "y", y, "px");
1043 }
1044
1045 if (xOrigin || yOrigin || xOffset || yOffset) {
1046 tx = _round(tx + xOrigin - (xOrigin * a11 + yOrigin * a12) + xOffset);
1047 ty = _round(ty + yOrigin - (xOrigin * a21 + yOrigin * a22) + yOffset);
1048 }
1049
1050 if (xPercent || yPercent) {
1051 //The SVG spec doesn't support percentage-based translation in the "transform" attribute, so we merge it into the translation to simulate it.
1052 temp = target.getBBox();
1053 tx = _round(tx + xPercent / 100 * temp.width);
1054 ty = _round(ty + yPercent / 100 * temp.height);
1055 }
1056
1057 temp = "matrix(" + a11 + "," + a21 + "," + a12 + "," + a22 + "," + tx + "," + ty + ")";
1058 target.setAttribute("transform", temp);
1059 forceCSS && (target.style[_transformProp] = temp); //some browsers prioritize CSS transforms over the transform attribute. When we sense that the user has CSS transforms applied, we must overwrite them this way (otherwise some browser simply won't render the transform attribute changes!)
1060},
1061 _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue) {
1062 var cap = 360,
1063 isString = _isString(endValue),
1064 endNum = parseFloat(endValue) * (isString && ~endValue.indexOf("rad") ? _RAD2DEG : 1),
1065 change = endNum - startNum,
1066 finalValue = startNum + change + "deg",
1067 direction,
1068 pt;
1069
1070 if (isString) {
1071 direction = endValue.split("_")[1];
1072
1073 if (direction === "short") {
1074 change %= cap;
1075
1076 if (change !== change % (cap / 2)) {
1077 change += change < 0 ? cap : -cap;
1078 }
1079 }
1080
1081 if (direction === "cw" && change < 0) {
1082 change = (change + cap * _bigNum) % cap - ~~(change / cap) * cap;
1083 } else if (direction === "ccw" && change > 0) {
1084 change = (change - cap * _bigNum) % cap - ~~(change / cap) * cap;
1085 }
1086 }
1087
1088 plugin._pt = pt = new PropTween(plugin._pt, target, property, startNum, change, _renderPropWithEnd);
1089 pt.e = finalValue;
1090 pt.u = "deg";
1091
1092 plugin._props.push(property);
1093
1094 return pt;
1095},
1096 _assign = function _assign(target, source) {
1097 // Internet Explorer doesn't have Object.assign(), so we recreate it here.
1098 for (var p in source) {
1099 target[p] = source[p];
1100 }
1101
1102 return target;
1103},
1104 _addRawTransformPTs = function _addRawTransformPTs(plugin, transforms, target) {
1105 //for handling cases where someone passes in a whole transform string, like transform: "scale(2, 3) rotate(20deg) translateY(30em)"
1106 var startCache = _assign({}, target._gsap),
1107 exclude = "perspective,force3D,transformOrigin,svgOrigin",
1108 style = target.style,
1109 endCache,
1110 p,
1111 startValue,
1112 endValue,
1113 startNum,
1114 endNum,
1115 startUnit,
1116 endUnit;
1117
1118 if (startCache.svg) {
1119 startValue = target.getAttribute("transform");
1120 target.setAttribute("transform", "");
1121 style[_transformProp] = transforms;
1122 endCache = _parseTransform(target, 1);
1123
1124 _removeProperty(target, _transformProp);
1125
1126 target.setAttribute("transform", startValue);
1127 } else {
1128 startValue = getComputedStyle(target)[_transformProp];
1129 style[_transformProp] = transforms;
1130 endCache = _parseTransform(target, 1);
1131 style[_transformProp] = startValue;
1132 }
1133
1134 for (p in _transformProps) {
1135 startValue = startCache[p];
1136 endValue = endCache[p];
1137
1138 if (startValue !== endValue && exclude.indexOf(p) < 0) {
1139 //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case.
1140 startUnit = getUnit(startValue);
1141 endUnit = getUnit(endValue);
1142 startNum = startUnit !== endUnit ? _convertToUnit(target, p, startValue, endUnit) : parseFloat(startValue);
1143 endNum = parseFloat(endValue);
1144 plugin._pt = new PropTween(plugin._pt, endCache, p, startNum, endNum - startNum, _renderCSSProp);
1145 plugin._pt.u = endUnit || 0;
1146
1147 plugin._props.push(p);
1148 }
1149 }
1150
1151 _assign(endCache, startCache);
1152}; // handle splitting apart padding, margin, borderWidth, and borderRadius into their 4 components. Firefox, for example, won't report borderRadius correctly - it will only do borderTopLeftRadius and the other corners. We also want to handle paddingTop, marginLeft, borderRightWidth, etc.
1153
1154
1155_forEachName("padding,margin,Width,Radius", function (name, index) {
1156 var t = "Top",
1157 r = "Right",
1158 b = "Bottom",
1159 l = "Left",
1160 props = (index < 3 ? [t, r, b, l] : [t + l, t + r, b + r, b + l]).map(function (side) {
1161 return index < 2 ? name + side : "border" + side + name;
1162 });
1163
1164 _specialProps[index > 1 ? "border" + name : name] = function (plugin, target, property, endValue, tween) {
1165 var a, vars;
1166
1167 if (arguments.length < 4) {
1168 // getter, passed target, property, and unit (from _get())
1169 a = props.map(function (prop) {
1170 return _get(plugin, prop, property);
1171 });
1172 vars = a.join(" ");
1173 return vars.split(a[0]).length === 5 ? a[0] : vars;
1174 }
1175
1176 a = (endValue + "").split(" ");
1177 vars = {};
1178 props.forEach(function (prop, i) {
1179 return vars[prop] = a[i] = a[i] || a[(i - 1) / 2 | 0];
1180 });
1181 plugin.init(target, vars, tween);
1182 };
1183});
1184
1185export var CSSPlugin = {
1186 name: "css",
1187 register: _initCore,
1188 targetTest: function targetTest(target) {
1189 return target.style && target.nodeType;
1190 },
1191 init: function init(target, vars, tween, index, targets) {
1192 var props = this._props,
1193 style = target.style,
1194 startAt = tween.vars.startAt,
1195 startValue,
1196 endValue,
1197 endNum,
1198 startNum,
1199 type,
1200 specialProp,
1201 p,
1202 startUnit,
1203 endUnit,
1204 relative,
1205 isTransformRelated,
1206 transformPropTween,
1207 cache,
1208 smooth,
1209 hasPriority;
1210 _pluginInitted || _initCore();
1211
1212 for (p in vars) {
1213 if (p === "autoRound") {
1214 continue;
1215 }
1216
1217 endValue = vars[p];
1218
1219 if (_plugins[p] && _checkPlugin(p, vars, tween, index, target, targets)) {
1220 // plugins
1221 continue;
1222 }
1223
1224 type = typeof endValue;
1225 specialProp = _specialProps[p];
1226
1227 if (type === "function") {
1228 endValue = endValue.call(tween, index, target, targets);
1229 type = typeof endValue;
1230 }
1231
1232 if (type === "string" && ~endValue.indexOf("random(")) {
1233 endValue = _replaceRandom(endValue);
1234 }
1235
1236 if (specialProp) {
1237 specialProp(this, target, p, endValue, tween) && (hasPriority = 1);
1238 } else if (p.substr(0, 2) === "--") {
1239 //CSS variable
1240 startValue = (getComputedStyle(target).getPropertyValue(p) + "").trim();
1241 endValue += "";
1242 _colorExp.lastIndex = 0;
1243
1244 if (!_colorExp.test(startValue)) {
1245 // colors don't have units
1246 startUnit = getUnit(startValue);
1247 endUnit = getUnit(endValue);
1248 }
1249
1250 endUnit ? startUnit !== endUnit && (startValue = _convertToUnit(target, p, startValue, endUnit) + endUnit) : startUnit && (endValue += startUnit);
1251 this.add(style, "setProperty", startValue, endValue, index, targets, 0, 0, p);
1252 props.push(p);
1253 } else if (type !== "undefined") {
1254 if (startAt && p in startAt) {
1255 // in case someone hard-codes a complex value as the start, like top: "calc(2vh / 2)". Without this, it'd use the computed value (always in px)
1256 startValue = typeof startAt[p] === "function" ? startAt[p].call(tween, index, target, targets) : startAt[p];
1257 _isString(startValue) && ~startValue.indexOf("random(") && (startValue = _replaceRandom(startValue));
1258 getUnit(startValue + "") || (startValue += _config.units[p] || getUnit(_get(target, p)) || ""); // for cases when someone passes in a unitless value like {x: 100}; if we try setting translate(100, 0px) it won't work.
1259
1260 (startValue + "").charAt(1) === "=" && (startValue = _get(target, p)); // can't work with relative values
1261 } else {
1262 startValue = _get(target, p);
1263 }
1264
1265 startNum = parseFloat(startValue);
1266 relative = type === "string" && endValue.charAt(1) === "=" && endValue.substr(0, 2);
1267 relative && (endValue = endValue.substr(2));
1268 endNum = parseFloat(endValue);
1269
1270 if (p in _propertyAliases) {
1271 if (p === "autoAlpha") {
1272 //special case where we control the visibility along with opacity. We still allow the opacity value to pass through and get tweened.
1273 if (startNum === 1 && _get(target, "visibility") === "hidden" && endNum) {
1274 //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience)
1275 startNum = 0;
1276 }
1277
1278 _addNonTweeningPT(this, style, "visibility", startNum ? "inherit" : "hidden", endNum ? "inherit" : "hidden", !endNum);
1279 }
1280
1281 if (p !== "scale" && p !== "transform") {
1282 p = _propertyAliases[p];
1283 ~p.indexOf(",") && (p = p.split(",")[0]);
1284 }
1285 }
1286
1287 isTransformRelated = p in _transformProps; //--- TRANSFORM-RELATED ---
1288
1289 if (isTransformRelated) {
1290 if (!transformPropTween) {
1291 cache = target._gsap;
1292 cache.renderTransform && !vars.parseTransform || _parseTransform(target, vars.parseTransform); // if, for example, gsap.set(... {transform:"translateX(50vw)"}), the _get() call doesn't parse the transform, thus cache.renderTransform won't be set yet so force the parsing of the transform here.
1293
1294 smooth = vars.smoothOrigin !== false && cache.smooth;
1295 transformPropTween = this._pt = new PropTween(this._pt, style, _transformProp, 0, 1, cache.renderTransform, cache, 0, -1); //the first time through, create the rendering PropTween so that it runs LAST (in the linked list, we keep adding to the beginning)
1296
1297 transformPropTween.dep = 1; //flag it as dependent so that if things get killed/overwritten and this is the only PropTween left, we can safely kill the whole tween.
1298 }
1299
1300 if (p === "scale") {
1301 this._pt = new PropTween(this._pt, cache, "scaleY", cache.scaleY, (relative ? _parseRelative(cache.scaleY, relative + endNum) : endNum) - cache.scaleY || 0);
1302 props.push("scaleY", p);
1303 p += "X";
1304 } else if (p === "transformOrigin") {
1305 endValue = _convertKeywordsToPercentages(endValue); //in case something like "left top" or "bottom right" is passed in. Convert to percentages.
1306
1307 if (cache.svg) {
1308 _applySVGOrigin(target, endValue, 0, smooth, 0, this);
1309 } else {
1310 endUnit = parseFloat(endValue.split(" ")[2]) || 0; //handle the zOrigin separately!
1311
1312 endUnit !== cache.zOrigin && _addNonTweeningPT(this, cache, "zOrigin", cache.zOrigin, endUnit);
1313
1314 _addNonTweeningPT(this, style, p, _firstTwoOnly(startValue), _firstTwoOnly(endValue));
1315 }
1316
1317 continue;
1318 } else if (p === "svgOrigin") {
1319 _applySVGOrigin(target, endValue, 1, smooth, 0, this);
1320
1321 continue;
1322 } else if (p in _rotationalProperties) {
1323 _addRotationalPropTween(this, cache, p, startNum, relative ? _parseRelative(startNum, relative + endValue) : endValue);
1324
1325 continue;
1326 } else if (p === "smoothOrigin") {
1327 _addNonTweeningPT(this, cache, "smooth", cache.smooth, endValue);
1328
1329 continue;
1330 } else if (p === "force3D") {
1331 cache[p] = endValue;
1332 continue;
1333 } else if (p === "transform") {
1334 _addRawTransformPTs(this, endValue, target);
1335
1336 continue;
1337 }
1338 } else if (!(p in style)) {
1339 p = _checkPropPrefix(p) || p;
1340 }
1341
1342 if (isTransformRelated || (endNum || endNum === 0) && (startNum || startNum === 0) && !_complexExp.test(endValue) && p in style) {
1343 startUnit = (startValue + "").substr((startNum + "").length);
1344 endNum || (endNum = 0); // protect against NaN
1345
1346 endUnit = getUnit(endValue) || (p in _config.units ? _config.units[p] : startUnit);
1347 startUnit !== endUnit && (startNum = _convertToUnit(target, p, startValue, endUnit));
1348 this._pt = new PropTween(this._pt, isTransformRelated ? cache : style, p, startNum, (relative ? _parseRelative(startNum, relative + endNum) : endNum) - startNum, !isTransformRelated && (endUnit === "px" || p === "zIndex") && vars.autoRound !== false ? _renderRoundedCSSProp : _renderCSSProp);
1349 this._pt.u = endUnit || 0;
1350
1351 if (startUnit !== endUnit && endUnit !== "%") {
1352 //when the tween goes all the way back to the beginning, we need to revert it to the OLD/ORIGINAL value (with those units). We record that as a "b" (beginning) property and point to a render method that handles that. (performance optimization)
1353 this._pt.b = startValue;
1354 this._pt.r = _renderCSSPropWithBeginning;
1355 }
1356 } else if (!(p in style)) {
1357 if (p in target) {
1358 //maybe it's not a style - it could be a property added directly to an element in which case we'll try to animate that.
1359 this.add(target, p, startValue || target[p], relative ? relative + endValue : endValue, index, targets);
1360 } else {
1361 _missingPlugin(p, endValue);
1362
1363 continue;
1364 }
1365 } else {
1366 _tweenComplexCSSString.call(this, target, p, startValue, relative ? relative + endValue : endValue);
1367 }
1368
1369 props.push(p);
1370 }
1371 }
1372
1373 hasPriority && _sortPropTweensByPriority(this);
1374 },
1375 get: _get,
1376 aliases: _propertyAliases,
1377 getSetter: function getSetter(target, property, plugin) {
1378 //returns a setter function that accepts target, property, value and applies it accordingly. Remember, properties like "x" aren't as simple as target.style.property = value because they've got to be applied to a proxy object and then merged into a transform string in a renderer.
1379 var p = _propertyAliases[property];
1380 p && p.indexOf(",") < 0 && (property = p);
1381 return property in _transformProps && property !== _transformOriginProp && (target._gsap.x || _get(target, "x")) ? plugin && _recentSetterPlugin === plugin ? property === "scale" ? _setterScale : _setterTransform : (_recentSetterPlugin = plugin || {}) && (property === "scale" ? _setterScaleWithRender : _setterTransformWithRender) : target.style && !_isUndefined(target.style[property]) ? _setterCSSStyle : ~property.indexOf("-") ? _setterCSSProp : _getSetter(target, property);
1382 },
1383 core: {
1384 _removeProperty: _removeProperty,
1385 _getMatrix: _getMatrix
1386 }
1387};
1388gsap.utils.checkPrefix = _checkPropPrefix;
1389
1390(function (positionAndScale, rotation, others, aliases) {
1391 var all = _forEachName(positionAndScale + "," + rotation + "," + others, function (name) {
1392 _transformProps[name] = 1;
1393 });
1394
1395 _forEachName(rotation, function (name) {
1396 _config.units[name] = "deg";
1397 _rotationalProperties[name] = 1;
1398 });
1399
1400 _propertyAliases[all[13]] = positionAndScale + "," + rotation;
1401
1402 _forEachName(aliases, function (name) {
1403 var split = name.split(":");
1404 _propertyAliases[split[1]] = all[split[0]];
1405 });
1406})("x,y,z,scale,scaleX,scaleY,xPercent,yPercent", "rotation,rotationX,rotationY,skewX,skewY", "transform,transformOrigin,svgOrigin,force3D,smoothOrigin,transformPerspective", "0:translateX,1:translateY,2:translateZ,8:rotate,8:rotationZ,8:rotateZ,9:rotateX,10:rotateY");
1407
1408_forEachName("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective", function (name) {
1409 _config.units[name] = "px";
1410});
1411
1412gsap.registerPlugin(CSSPlugin);
1413export { CSSPlugin as default, _getBBox, _createElement, _checkPropPrefix as checkPrefix };
\No newline at end of file