UNPKG

54.6 kBJavaScriptView Raw
1/*!
2 * CSSPlugin 3.4.2
3 * https://greensock.com
4 *
5 * Copyright 2008-2020, 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, _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 && (_transformProps[property] || ~property.indexOf("adius"))) {
254 //transforms and borderRadius are relative to the size of the element itself!
255 return _round(curValue / (isSVG ? target.getBBox()[horizontal ? "width" : "height"] : target[measureProperty]) * amount);
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] : _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 + "").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 relative,
346 endValues;
347 pt.b = start;
348 pt.e = end;
349 start += ""; //ensure values are strings
350
351 end += "";
352
353 if (end === "auto") {
354 target.style[prop] = end;
355 end = _getComputedProperty(target, prop) || end;
356 target.style[prop] = start;
357 }
358
359 a = [start, end];
360
361 _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().
362
363
364 start = a[0];
365 end = a[1];
366 startValues = start.match(_numWithUnitExp) || [];
367 endValues = end.match(_numWithUnitExp) || [];
368
369 if (endValues.length) {
370 while (result = _numWithUnitExp.exec(end)) {
371 endValue = result[0];
372 chunk = end.substring(index, result.index);
373
374 if (color) {
375 color = (color + 1) % 5;
376 } else if (chunk.substr(-5) === "rgba(" || chunk.substr(-5) === "hsla(") {
377 color = 1;
378 }
379
380 if (endValue !== (startValue = startValues[matchIndex++] || "")) {
381 startNum = parseFloat(startValue) || 0;
382 startUnit = startValue.substr((startNum + "").length);
383 relative = endValue.charAt(1) === "=" ? +(endValue.charAt(0) + "1") : 0;
384
385 if (relative) {
386 endValue = endValue.substr(2);
387 }
388
389 endNum = parseFloat(endValue);
390 endUnit = endValue.substr((endNum + "").length);
391 index = _numWithUnitExp.lastIndex - endUnit.length;
392
393 if (!endUnit) {
394 //if something like "perspective:300" is passed in and we must add a unit to the end
395 endUnit = endUnit || _config.units[prop] || startUnit;
396
397 if (index === end.length) {
398 end += endUnit;
399 pt.e += endUnit;
400 }
401 }
402
403 if (startUnit !== endUnit) {
404 startNum = _convertToUnit(target, prop, startValue, endUnit) || 0;
405 } //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.
406
407
408 pt._pt = {
409 _next: pt._pt,
410 p: chunk || matchIndex === 1 ? chunk : ",",
411 //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.
412 s: startNum,
413 c: relative ? relative * endNum : endNum - startNum,
414 m: color && color < 4 ? Math.round : 0
415 };
416 }
417 }
418
419 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)
420 } else {
421 pt.r = prop === "display" && end === "none" ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue;
422 }
423
424 if (_relExp.test(end)) {
425 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).
426 }
427
428 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.
429
430 return pt;
431},
432 _keywordToPercent = {
433 top: "0%",
434 bottom: "100%",
435 left: "0%",
436 right: "100%",
437 center: "50%"
438},
439 _convertKeywordsToPercentages = function _convertKeywordsToPercentages(value) {
440 var split = value.split(" "),
441 x = split[0],
442 y = split[1] || "50%";
443
444 if (x === "top" || x === "bottom" || y === "left" || y === "right") {
445 //the user provided them in the wrong order, so flip them
446 value = x;
447 x = y;
448 y = value;
449 }
450
451 split[0] = _keywordToPercent[x] || x;
452 split[1] = _keywordToPercent[y] || y;
453 return split.join(" ");
454},
455 _renderClearProps = function _renderClearProps(ratio, data) {
456 if (data.tween && data.tween._time === data.tween._dur) {
457 var target = data.t,
458 style = target.style,
459 props = data.u,
460 cache = target._gsap,
461 prop,
462 clearTransforms,
463 i;
464
465 if (props === "all" || props === true) {
466 style.cssText = "";
467 clearTransforms = 1;
468 } else {
469 props = props.split(",");
470 i = props.length;
471
472 while (--i > -1) {
473 prop = props[i];
474
475 if (_transformProps[prop]) {
476 clearTransforms = 1;
477 prop = prop === "transformOrigin" ? _transformOriginProp : _transformProp;
478 }
479
480 _removeProperty(target, prop);
481 }
482 }
483
484 if (clearTransforms) {
485 _removeProperty(target, _transformProp);
486
487 if (cache) {
488 cache.svg && target.removeAttribute("transform");
489
490 _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.
491
492
493 cache.uncache = 1;
494 }
495 }
496 }
497},
498 // note: specialProps should return 1 if (and only if) they have a non-zero priority. It indicates we need to sort the linked list.
499_specialProps = {
500 clearProps: function clearProps(plugin, target, property, endValue, tween) {
501 if (tween.data !== "isFromStart") {
502 var pt = plugin._pt = new PropTween(plugin._pt, target, property, 0, 0, _renderClearProps);
503 pt.u = endValue;
504 pt.pr = -10;
505 pt.tween = tween;
506
507 plugin._props.push(property);
508
509 return 1;
510 }
511 }
512 /* className feature (about 0.4kb gzipped).
513 , className(plugin, target, property, endValue, tween) {
514 let _renderClassName = (ratio, data) => {
515 data.css.render(ratio, data.css);
516 if (!ratio || ratio === 1) {
517 let inline = data.rmv,
518 target = data.t,
519 p;
520 target.setAttribute("class", ratio ? data.e : data.b);
521 for (p in inline) {
522 _removeProperty(target, p);
523 }
524 }
525 },
526 _getAllStyles = (target) => {
527 let styles = {},
528 computed = getComputedStyle(target),
529 p;
530 for (p in computed) {
531 if (isNaN(p) && p !== "cssText" && p !== "length") {
532 styles[p] = computed[p];
533 }
534 }
535 _setDefaults(styles, _parseTransform(target, 1));
536 return styles;
537 },
538 startClassList = target.getAttribute("class"),
539 style = target.style,
540 cssText = style.cssText,
541 cache = target._gsap,
542 classPT = cache.classPT,
543 inlineToRemoveAtEnd = {},
544 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) : "")},
545 changingVars = {},
546 startVars = _getAllStyles(target),
547 transformRelated = /(transform|perspective)/i,
548 endVars, p;
549 if (classPT) {
550 classPT.r(1, classPT.d);
551 _removeLinkedListItem(classPT.d.plugin, classPT, "_pt");
552 }
553 target.setAttribute("class", data.e);
554 endVars = _getAllStyles(target, true);
555 target.setAttribute("class", startClassList);
556 for (p in endVars) {
557 if (endVars[p] !== startVars[p] && !transformRelated.test(p)) {
558 changingVars[p] = endVars[p];
559 if (!style[p] && style[p] !== "0") {
560 inlineToRemoveAtEnd[p] = 1;
561 }
562 }
563 }
564 cache.classPT = plugin._pt = new PropTween(plugin._pt, target, "className", 0, 0, _renderClassName, data, 0, -11);
565 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/.
566 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).
567 }
568 _parseTransform(target, true); //to clear the caching of transforms
569 data.css = new gsap.plugins.css();
570 data.css.init(target, changingVars, tween);
571 plugin._props.push(...data.css._props);
572 return 1;
573 }
574 */
575
576},
577
578/*
579 * --------------------------------------------------------------------------------------
580 * TRANSFORMS
581 * --------------------------------------------------------------------------------------
582 */
583_identity2DMatrix = [1, 0, 0, 1, 0, 0],
584 _rotationalProperties = {},
585 _isNullTransform = function _isNullTransform(value) {
586 return value === "matrix(1, 0, 0, 1, 0, 0)" || value === "none" || !value;
587},
588 _getComputedTransformMatrixAsArray = function _getComputedTransformMatrixAsArray(target) {
589 var matrixString = _getComputedProperty(target, _transformProp);
590
591 return _isNullTransform(matrixString) ? _identity2DMatrix : matrixString.substr(7).match(_numExp).map(_round);
592},
593 _getMatrix = function _getMatrix(target, force2D) {
594 var cache = target._gsap || _getCache(target),
595 style = target.style,
596 matrix = _getComputedTransformMatrixAsArray(target),
597 parent,
598 nextSibling,
599 temp,
600 addedToDOM;
601
602 if (cache.svg && target.getAttribute("transform")) {
603 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.
604
605 matrix = [temp.a, temp.b, temp.c, temp.d, temp.e, temp.f];
606 return matrix.join(",") === "1,0,0,1,0,0" ? _identity2DMatrix : matrix;
607 } else if (matrix === _identity2DMatrix && !target.offsetParent && target !== _docElement && !cache.svg) {
608 //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
609 //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).
610 temp = style.display;
611 style.display = "block";
612 parent = target.parentNode;
613
614 if (!parent || !target.offsetParent) {
615 // 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
616 addedToDOM = 1; //flag
617
618 nextSibling = target.nextSibling;
619
620 _docElement.appendChild(target); //we must add it to the DOM in order to get values properly
621
622 }
623
624 matrix = _getComputedTransformMatrixAsArray(target);
625 temp ? style.display = temp : _removeProperty(target, "display");
626
627 if (addedToDOM) {
628 nextSibling ? parent.insertBefore(target, nextSibling) : parent ? parent.appendChild(target) : _docElement.removeChild(target);
629 }
630 }
631
632 return force2D && matrix.length > 6 ? [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]] : matrix;
633},
634 _applySVGOrigin = function _applySVGOrigin(target, origin, originIsAbsolute, smooth, matrixArray, pluginToAddPropTweensTo) {
635 var cache = target._gsap,
636 matrix = matrixArray || _getMatrix(target, true),
637 xOriginOld = cache.xOrigin || 0,
638 yOriginOld = cache.yOrigin || 0,
639 xOffsetOld = cache.xOffset || 0,
640 yOffsetOld = cache.yOffset || 0,
641 a = matrix[0],
642 b = matrix[1],
643 c = matrix[2],
644 d = matrix[3],
645 tx = matrix[4],
646 ty = matrix[5],
647 originSplit = origin.split(" "),
648 xOrigin = parseFloat(originSplit[0]) || 0,
649 yOrigin = parseFloat(originSplit[1]) || 0,
650 bounds,
651 determinant,
652 x,
653 y;
654
655 if (!originIsAbsolute) {
656 bounds = _getBBox(target);
657 xOrigin = bounds.x + (~originSplit[0].indexOf("%") ? xOrigin / 100 * bounds.width : xOrigin);
658 yOrigin = bounds.y + (~(originSplit[1] || originSplit[0]).indexOf("%") ? yOrigin / 100 * bounds.height : yOrigin);
659 } else if (matrix !== _identity2DMatrix && (determinant = a * d - b * c)) {
660 //if it's zero (like if scaleX and scaleY are zero), skip it to avoid errors with dividing by zero.
661 x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant;
662 y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant;
663 xOrigin = x;
664 yOrigin = y;
665 }
666
667 if (smooth || smooth !== false && cache.smooth) {
668 tx = xOrigin - xOriginOld;
669 ty = yOrigin - yOriginOld;
670 cache.xOffset = xOffsetOld + (tx * a + ty * c) - tx;
671 cache.yOffset = yOffsetOld + (tx * b + ty * d) - ty;
672 } else {
673 cache.xOffset = cache.yOffset = 0;
674 }
675
676 cache.xOrigin = xOrigin;
677 cache.yOrigin = yOrigin;
678 cache.smooth = !!smooth;
679 cache.origin = origin;
680 cache.originIsAbsolute = !!originIsAbsolute;
681 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).
682
683 if (pluginToAddPropTweensTo) {
684 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOrigin", xOriginOld, xOrigin);
685
686 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOrigin", yOriginOld, yOrigin);
687
688 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOffset", xOffsetOld, cache.xOffset);
689
690 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOffset", yOffsetOld, cache.yOffset);
691 }
692
693 target.setAttribute("data-svg-origin", xOrigin + " " + yOrigin);
694},
695 _parseTransform = function _parseTransform(target, uncache) {
696 var cache = target._gsap || new GSCache(target);
697
698 if ("x" in cache && !uncache && !cache.uncache) {
699 return cache;
700 }
701
702 var style = target.style,
703 invertedScaleX = cache.scaleX < 0,
704 px = "px",
705 deg = "deg",
706 origin = _getComputedProperty(target, _transformOriginProp) || "0",
707 x,
708 y,
709 z,
710 scaleX,
711 scaleY,
712 rotation,
713 rotationX,
714 rotationY,
715 skewX,
716 skewY,
717 perspective,
718 xOrigin,
719 yOrigin,
720 matrix,
721 angle,
722 cos,
723 sin,
724 a,
725 b,
726 c,
727 d,
728 a12,
729 a22,
730 t1,
731 t2,
732 t3,
733 a13,
734 a23,
735 a33,
736 a42,
737 a43,
738 a32;
739 x = y = z = rotation = rotationX = rotationY = skewX = skewY = perspective = 0;
740 scaleX = scaleY = 1;
741 cache.svg = !!(target.getCTM && _isSVG(target));
742 matrix = _getMatrix(target, cache.svg);
743
744 if (cache.svg) {
745 t1 = !cache.uncache && target.getAttribute("data-svg-origin");
746
747 _applySVGOrigin(target, t1 || origin, !!t1 || cache.originIsAbsolute, cache.smooth !== false, matrix);
748 }
749
750 xOrigin = cache.xOrigin || 0;
751 yOrigin = cache.yOrigin || 0;
752
753 if (matrix !== _identity2DMatrix) {
754 a = matrix[0]; //a11
755
756 b = matrix[1]; //a21
757
758 c = matrix[2]; //a31
759
760 d = matrix[3]; //a41
761
762 x = a12 = matrix[4];
763 y = a22 = matrix[5]; //2D matrix
764
765 if (matrix.length === 6) {
766 scaleX = Math.sqrt(a * a + b * b);
767 scaleY = Math.sqrt(d * d + c * c);
768 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).
769
770 skewX = c || d ? _atan2(c, d) * _RAD2DEG + rotation : 0;
771 skewX && (scaleY *= Math.cos(skewX * _DEG2RAD));
772
773 if (cache.svg) {
774 x -= xOrigin - (xOrigin * a + yOrigin * c);
775 y -= yOrigin - (xOrigin * b + yOrigin * d);
776 } //3D matrix
777
778 } else {
779 a32 = matrix[6];
780 a42 = matrix[7];
781 a13 = matrix[8];
782 a23 = matrix[9];
783 a33 = matrix[10];
784 a43 = matrix[11];
785 x = matrix[12];
786 y = matrix[13];
787 z = matrix[14];
788 angle = _atan2(a32, a33);
789 rotationX = angle * _RAD2DEG; //rotationX
790
791 if (angle) {
792 cos = Math.cos(-angle);
793 sin = Math.sin(-angle);
794 t1 = a12 * cos + a13 * sin;
795 t2 = a22 * cos + a23 * sin;
796 t3 = a32 * cos + a33 * sin;
797 a13 = a12 * -sin + a13 * cos;
798 a23 = a22 * -sin + a23 * cos;
799 a33 = a32 * -sin + a33 * cos;
800 a43 = a42 * -sin + a43 * cos;
801 a12 = t1;
802 a22 = t2;
803 a32 = t3;
804 } //rotationY
805
806
807 angle = _atan2(-c, a33);
808 rotationY = angle * _RAD2DEG;
809
810 if (angle) {
811 cos = Math.cos(-angle);
812 sin = Math.sin(-angle);
813 t1 = a * cos - a13 * sin;
814 t2 = b * cos - a23 * sin;
815 t3 = c * cos - a33 * sin;
816 a43 = d * sin + a43 * cos;
817 a = t1;
818 b = t2;
819 c = t3;
820 } //rotationZ
821
822
823 angle = _atan2(b, a);
824 rotation = angle * _RAD2DEG;
825
826 if (angle) {
827 cos = Math.cos(angle);
828 sin = Math.sin(angle);
829 t1 = a * cos + b * sin;
830 t2 = a12 * cos + a22 * sin;
831 b = b * cos - a * sin;
832 a22 = a22 * cos - a12 * sin;
833 a = t1;
834 a12 = t2;
835 }
836
837 if (rotationX && Math.abs(rotationX) + Math.abs(rotation) > 359.9) {
838 //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.
839 rotationX = rotation = 0;
840 rotationY = 180 - rotationY;
841 }
842
843 scaleX = _round(Math.sqrt(a * a + b * b + c * c));
844 scaleY = _round(Math.sqrt(a22 * a22 + a32 * a32));
845 angle = _atan2(a12, a22);
846 skewX = Math.abs(angle) > 0.0002 ? angle * _RAD2DEG : 0;
847 perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0;
848 }
849
850 if (cache.svg) {
851 //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).
852 t1 = target.getAttribute("transform");
853 cache.forceCSS = target.setAttribute("transform", "") || !_isNullTransform(_getComputedProperty(target, _transformProp));
854 t1 && target.setAttribute("transform", t1);
855 }
856 }
857
858 if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) {
859 if (invertedScaleX) {
860 scaleX *= -1;
861 skewX += rotation <= 0 ? 180 : -180;
862 rotation += rotation <= 0 ? 180 : -180;
863 } else {
864 scaleY *= -1;
865 skewX += skewX <= 0 ? 180 : -180;
866 }
867 }
868
869 cache.x = ((cache.xPercent = x && Math.round(target.offsetWidth / 2) === Math.round(-x) ? -50 : 0) ? 0 : x) + px;
870 cache.y = ((cache.yPercent = y && Math.round(target.offsetHeight / 2) === Math.round(-y) ? -50 : 0) ? 0 : y) + px;
871 cache.z = z + px;
872 cache.scaleX = _round(scaleX);
873 cache.scaleY = _round(scaleY);
874 cache.rotation = _round(rotation) + deg;
875 cache.rotationX = _round(rotationX) + deg;
876 cache.rotationY = _round(rotationY) + deg;
877 cache.skewX = skewX + deg;
878 cache.skewY = skewY + deg;
879 cache.transformPerspective = perspective + px;
880
881 if (cache.zOrigin = parseFloat(origin.split(" ")[2]) || 0) {
882 style[_transformOriginProp] = _firstTwoOnly(origin);
883 }
884
885 cache.xOffset = cache.yOffset = 0;
886 cache.force3D = _config.force3D;
887 cache.renderTransform = cache.svg ? _renderSVGTransforms : _supports3D ? _renderCSSTransforms : _renderNon3DTransforms;
888 cache.uncache = 0;
889 return cache;
890},
891 _firstTwoOnly = function _firstTwoOnly(value) {
892 return (value = value.split(" "))[0] + " " + value[1];
893},
894 //for handling transformOrigin values, stripping out the 3rd dimension
895_addPxTranslate = function _addPxTranslate(target, start, value) {
896 var unit = getUnit(start);
897 return _round(parseFloat(start) + parseFloat(_convertToUnit(target, "x", value + "px", unit))) + unit;
898},
899 _renderNon3DTransforms = function _renderNon3DTransforms(ratio, cache) {
900 cache.z = "0px";
901 cache.rotationY = cache.rotationX = "0deg";
902 cache.force3D = 0;
903
904 _renderCSSTransforms(ratio, cache);
905},
906 _zeroDeg = "0deg",
907 _zeroPx = "0px",
908 _endParenthesis = ") ",
909 _renderCSSTransforms = function _renderCSSTransforms(ratio, cache) {
910 var _ref = cache || this,
911 xPercent = _ref.xPercent,
912 yPercent = _ref.yPercent,
913 x = _ref.x,
914 y = _ref.y,
915 z = _ref.z,
916 rotation = _ref.rotation,
917 rotationY = _ref.rotationY,
918 rotationX = _ref.rotationX,
919 skewX = _ref.skewX,
920 skewY = _ref.skewY,
921 scaleX = _ref.scaleX,
922 scaleY = _ref.scaleY,
923 transformPerspective = _ref.transformPerspective,
924 force3D = _ref.force3D,
925 target = _ref.target,
926 zOrigin = _ref.zOrigin,
927 transforms = "",
928 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)
929
930
931 if (zOrigin && (rotationX !== _zeroDeg || rotationY !== _zeroDeg)) {
932 var angle = parseFloat(rotationY) * _DEG2RAD,
933 a13 = Math.sin(angle),
934 a33 = Math.cos(angle),
935 cos;
936
937 angle = parseFloat(rotationX) * _DEG2RAD;
938 cos = Math.cos(angle);
939 x = _addPxTranslate(target, x, a13 * cos * -zOrigin);
940 y = _addPxTranslate(target, y, -Math.sin(angle) * -zOrigin);
941 z = _addPxTranslate(target, z, a33 * cos * -zOrigin + zOrigin);
942 }
943
944 if (transformPerspective !== _zeroPx) {
945 transforms += "perspective(" + transformPerspective + _endParenthesis;
946 }
947
948 if (xPercent || yPercent) {
949 transforms += "translate(" + xPercent + "%, " + yPercent + "%) ";
950 }
951
952 if (use3D || x !== _zeroPx || y !== _zeroPx || z !== _zeroPx) {
953 transforms += z !== _zeroPx || use3D ? "translate3d(" + x + ", " + y + ", " + z + ") " : "translate(" + x + ", " + y + _endParenthesis;
954 }
955
956 if (rotation !== _zeroDeg) {
957 transforms += "rotate(" + rotation + _endParenthesis;
958 }
959
960 if (rotationY !== _zeroDeg) {
961 transforms += "rotateY(" + rotationY + _endParenthesis;
962 }
963
964 if (rotationX !== _zeroDeg) {
965 transforms += "rotateX(" + rotationX + _endParenthesis;
966 }
967
968 if (skewX !== _zeroDeg || skewY !== _zeroDeg) {
969 transforms += "skew(" + skewX + ", " + skewY + _endParenthesis;
970 }
971
972 if (scaleX !== 1 || scaleY !== 1) {
973 transforms += "scale(" + scaleX + ", " + scaleY + _endParenthesis;
974 }
975
976 target.style[_transformProp] = transforms || "translate(0, 0)";
977},
978 _renderSVGTransforms = function _renderSVGTransforms(ratio, cache) {
979 var _ref2 = cache || this,
980 xPercent = _ref2.xPercent,
981 yPercent = _ref2.yPercent,
982 x = _ref2.x,
983 y = _ref2.y,
984 rotation = _ref2.rotation,
985 skewX = _ref2.skewX,
986 skewY = _ref2.skewY,
987 scaleX = _ref2.scaleX,
988 scaleY = _ref2.scaleY,
989 target = _ref2.target,
990 xOrigin = _ref2.xOrigin,
991 yOrigin = _ref2.yOrigin,
992 xOffset = _ref2.xOffset,
993 yOffset = _ref2.yOffset,
994 forceCSS = _ref2.forceCSS,
995 tx = parseFloat(x),
996 ty = parseFloat(y),
997 a11,
998 a21,
999 a12,
1000 a22,
1001 temp;
1002
1003 rotation = parseFloat(rotation);
1004 skewX = parseFloat(skewX);
1005 skewY = parseFloat(skewY);
1006
1007 if (skewY) {
1008 //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.
1009 skewY = parseFloat(skewY);
1010 skewX += skewY;
1011 rotation += skewY;
1012 }
1013
1014 if (rotation || skewX) {
1015 rotation *= _DEG2RAD;
1016 skewX *= _DEG2RAD;
1017 a11 = Math.cos(rotation) * scaleX;
1018 a21 = Math.sin(rotation) * scaleX;
1019 a12 = Math.sin(rotation - skewX) * -scaleY;
1020 a22 = Math.cos(rotation - skewX) * scaleY;
1021
1022 if (skewX) {
1023 skewY *= _DEG2RAD;
1024 temp = Math.tan(skewX - skewY);
1025 temp = Math.sqrt(1 + temp * temp);
1026 a12 *= temp;
1027 a22 *= temp;
1028
1029 if (skewY) {
1030 temp = Math.tan(skewY);
1031 temp = Math.sqrt(1 + temp * temp);
1032 a11 *= temp;
1033 a21 *= temp;
1034 }
1035 }
1036
1037 a11 = _round(a11);
1038 a21 = _round(a21);
1039 a12 = _round(a12);
1040 a22 = _round(a22);
1041 } else {
1042 a11 = scaleX;
1043 a22 = scaleY;
1044 a21 = a12 = 0;
1045 }
1046
1047 if (tx && !~(x + "").indexOf("px") || ty && !~(y + "").indexOf("px")) {
1048 tx = _convertToUnit(target, "x", x, "px");
1049 ty = _convertToUnit(target, "y", y, "px");
1050 }
1051
1052 if (xOrigin || yOrigin || xOffset || yOffset) {
1053 tx = _round(tx + xOrigin - (xOrigin * a11 + yOrigin * a12) + xOffset);
1054 ty = _round(ty + yOrigin - (xOrigin * a21 + yOrigin * a22) + yOffset);
1055 }
1056
1057 if (xPercent || yPercent) {
1058 //The SVG spec doesn't support percentage-based translation in the "transform" attribute, so we merge it into the translation to simulate it.
1059 temp = target.getBBox();
1060 tx = _round(tx + xPercent / 100 * temp.width);
1061 ty = _round(ty + yPercent / 100 * temp.height);
1062 }
1063
1064 temp = "matrix(" + a11 + "," + a21 + "," + a12 + "," + a22 + "," + tx + "," + ty + ")";
1065 target.setAttribute("transform", temp);
1066
1067 if (forceCSS) {
1068 //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!)
1069 target.style[_transformProp] = temp;
1070 }
1071},
1072 _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue, relative) {
1073 var cap = 360,
1074 isString = _isString(endValue),
1075 endNum = parseFloat(endValue) * (isString && ~endValue.indexOf("rad") ? _RAD2DEG : 1),
1076 change = relative ? endNum * relative : endNum - startNum,
1077 finalValue = startNum + change + "deg",
1078 direction,
1079 pt;
1080
1081 if (isString) {
1082 direction = endValue.split("_")[1];
1083
1084 if (direction === "short") {
1085 change %= cap;
1086
1087 if (change !== change % (cap / 2)) {
1088 change += change < 0 ? cap : -cap;
1089 }
1090 }
1091
1092 if (direction === "cw" && change < 0) {
1093 change = (change + cap * _bigNum) % cap - ~~(change / cap) * cap;
1094 } else if (direction === "ccw" && change > 0) {
1095 change = (change - cap * _bigNum) % cap - ~~(change / cap) * cap;
1096 }
1097 }
1098
1099 plugin._pt = pt = new PropTween(plugin._pt, target, property, startNum, change, _renderPropWithEnd);
1100 pt.e = finalValue;
1101 pt.u = "deg";
1102
1103 plugin._props.push(property);
1104
1105 return pt;
1106},
1107 _addRawTransformPTs = function _addRawTransformPTs(plugin, transforms, target) {
1108 //for handling cases where someone passes in a whole transform string, like transform: "scale(2, 3) rotate(20deg) translateY(30em)"
1109 var style = _tempDivStyler.style,
1110 startCache = target._gsap,
1111 exclude = "perspective,force3D,transformOrigin,svgOrigin",
1112 endCache,
1113 p,
1114 startValue,
1115 endValue,
1116 startNum,
1117 endNum,
1118 startUnit,
1119 endUnit;
1120 style.cssText = getComputedStyle(target).cssText + ";position:absolute;display:block;"; //%-based translations will fail unless we set the width/height to match the original target (and padding/borders can affect it)
1121
1122 style[_transformProp] = transforms;
1123
1124 _doc.body.appendChild(_tempDivStyler);
1125
1126 endCache = _parseTransform(_tempDivStyler, 1);
1127
1128 for (p in _transformProps) {
1129 startValue = startCache[p];
1130 endValue = endCache[p];
1131
1132 if (startValue !== endValue && exclude.indexOf(p) < 0) {
1133 //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case.
1134 startUnit = getUnit(startValue);
1135 endUnit = getUnit(endValue);
1136 startNum = startUnit !== endUnit ? _convertToUnit(target, p, startValue, endUnit) : parseFloat(startValue);
1137 endNum = parseFloat(endValue);
1138 plugin._pt = new PropTween(plugin._pt, startCache, p, startNum, endNum - startNum, _renderCSSProp);
1139 plugin._pt.u = endUnit || 0;
1140
1141 plugin._props.push(p);
1142 }
1143 }
1144
1145 _doc.body.removeChild(_tempDivStyler);
1146}; // 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.
1147
1148
1149_forEachName("padding,margin,Width,Radius", function (name, index) {
1150 var t = "Top",
1151 r = "Right",
1152 b = "Bottom",
1153 l = "Left",
1154 props = (index < 3 ? [t, r, b, l] : [t + l, t + r, b + r, b + l]).map(function (side) {
1155 return index < 2 ? name + side : "border" + side + name;
1156 });
1157
1158 _specialProps[index > 1 ? "border" + name : name] = function (plugin, target, property, endValue, tween) {
1159 var a, vars;
1160
1161 if (arguments.length < 4) {
1162 // getter, passed target, property, and unit (from _get())
1163 a = props.map(function (prop) {
1164 return _get(plugin, prop, property);
1165 });
1166 vars = a.join(" ");
1167 return vars.split(a[0]).length === 5 ? a[0] : vars;
1168 }
1169
1170 a = (endValue + "").split(" ");
1171 vars = {};
1172 props.forEach(function (prop, i) {
1173 return vars[prop] = a[i] = a[i] || a[(i - 1) / 2 | 0];
1174 });
1175 plugin.init(target, vars, tween);
1176 };
1177});
1178
1179export var CSSPlugin = {
1180 name: "css",
1181 register: _initCore,
1182 targetTest: function targetTest(target) {
1183 return target.style && target.nodeType;
1184 },
1185 init: function init(target, vars, tween, index, targets) {
1186 var props = this._props,
1187 style = target.style,
1188 startValue,
1189 endValue,
1190 endNum,
1191 startNum,
1192 type,
1193 specialProp,
1194 p,
1195 startUnit,
1196 endUnit,
1197 relative,
1198 isTransformRelated,
1199 transformPropTween,
1200 cache,
1201 smooth,
1202 hasPriority;
1203
1204 if (!_pluginInitted) {
1205 _initCore();
1206 }
1207
1208 for (p in vars) {
1209 if (p === "autoRound") {
1210 continue;
1211 }
1212
1213 endValue = vars[p];
1214
1215 if (_plugins[p] && _checkPlugin(p, vars, tween, index, target, targets)) {
1216 //plugins
1217 continue;
1218 }
1219
1220 type = typeof endValue;
1221 specialProp = _specialProps[p];
1222
1223 if (type === "function") {
1224 endValue = endValue.call(tween, index, target, targets);
1225 type = typeof endValue;
1226 }
1227
1228 if (type === "string" && ~endValue.indexOf("random(")) {
1229 endValue = _replaceRandom(endValue);
1230 }
1231
1232 if (specialProp) {
1233 if (specialProp(this, target, p, endValue, tween)) {
1234 hasPriority = 1;
1235 }
1236 } else if (p.substr(0, 2) === "--") {
1237 //CSS variable
1238 this.add(style, "setProperty", getComputedStyle(target).getPropertyValue(p) + "", endValue + "", index, targets, 0, 0, p);
1239 } else {
1240 startValue = _get(target, p);
1241 startNum = parseFloat(startValue);
1242 relative = type === "string" && endValue.charAt(1) === "=" ? +(endValue.charAt(0) + "1") : 0;
1243
1244 if (relative) {
1245 endValue = endValue.substr(2);
1246 }
1247
1248 endNum = parseFloat(endValue);
1249
1250 if (p in _propertyAliases) {
1251 if (p === "autoAlpha") {
1252 //special case where we control the visibility along with opacity. We still allow the opacity value to pass through and get tweened.
1253 if (startNum === 1 && _get(target, "visibility") === "hidden" && endNum) {
1254 //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience)
1255 startNum = 0;
1256 }
1257
1258 _addNonTweeningPT(this, style, "visibility", startNum ? "inherit" : "hidden", endNum ? "inherit" : "hidden", !endNum);
1259 }
1260
1261 if (p !== "scale" && p !== "transform") {
1262 p = _propertyAliases[p];
1263
1264 if (~p.indexOf(",")) {
1265 p = p.split(",")[0];
1266 }
1267 }
1268 }
1269
1270 isTransformRelated = p in _transformProps; //--- TRANSFORM-RELATED ---
1271
1272 if (isTransformRelated) {
1273 if (!transformPropTween) {
1274 cache = target._gsap;
1275 cache.renderTransform || _parseTransform(target); // 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.
1276
1277 smooth = vars.smoothOrigin !== false && cache.smooth;
1278 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)
1279
1280 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.
1281 }
1282
1283 if (p === "scale") {
1284 this._pt = new PropTween(this._pt, cache, "scaleY", cache.scaleY, relative ? relative * endNum : endNum - cache.scaleY);
1285 props.push("scaleY", p);
1286 p += "X";
1287 } else if (p === "transformOrigin") {
1288 endValue = _convertKeywordsToPercentages(endValue); //in case something like "left top" or "bottom right" is passed in. Convert to percentages.
1289
1290 if (cache.svg) {
1291 _applySVGOrigin(target, endValue, 0, smooth, 0, this);
1292 } else {
1293 endUnit = parseFloat(endValue.split(" ")[2]) || 0; //handle the zOrigin separately!
1294
1295 if (endUnit !== cache.zOrigin) {
1296 _addNonTweeningPT(this, cache, "zOrigin", cache.zOrigin, endUnit);
1297 }
1298
1299 _addNonTweeningPT(this, style, p, _firstTwoOnly(startValue), _firstTwoOnly(endValue));
1300 }
1301
1302 continue;
1303 } else if (p === "svgOrigin") {
1304 _applySVGOrigin(target, endValue, 1, smooth, 0, this);
1305
1306 continue;
1307 } else if (p in _rotationalProperties) {
1308 _addRotationalPropTween(this, cache, p, startNum, endValue, relative);
1309
1310 continue;
1311 } else if (p === "smoothOrigin") {
1312 _addNonTweeningPT(this, cache, "smooth", cache.smooth, endValue);
1313
1314 continue;
1315 } else if (p === "force3D") {
1316 cache[p] = endValue;
1317 continue;
1318 } else if (p === "transform") {
1319 _addRawTransformPTs(this, endValue, target);
1320
1321 continue;
1322 }
1323 } else if (!(p in style)) {
1324 p = _checkPropPrefix(p) || p;
1325 }
1326
1327 if (isTransformRelated || (endNum || endNum === 0) && (startNum || startNum === 0) && !_complexExp.test(endValue) && p in style) {
1328 startUnit = (startValue + "").substr((startNum + "").length);
1329 endNum || (endNum = 0); // protect against NaN
1330
1331 endUnit = (endValue + "").substr((endNum + "").length) || (p in _config.units ? _config.units[p] : startUnit);
1332
1333 if (startUnit !== endUnit) {
1334 startNum = _convertToUnit(target, p, startValue, endUnit);
1335 }
1336
1337 this._pt = new PropTween(this._pt, isTransformRelated ? cache : style, p, startNum, relative ? relative * endNum : endNum - startNum, endUnit === "px" && vars.autoRound !== false && !isTransformRelated ? _renderRoundedCSSProp : _renderCSSProp);
1338 this._pt.u = endUnit || 0;
1339
1340 if (startUnit !== endUnit) {
1341 //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)
1342 this._pt.b = startValue;
1343 this._pt.r = _renderCSSPropWithBeginning;
1344 }
1345 } else if (!(p in style)) {
1346 if (p in target) {
1347 //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.
1348 this.add(target, p, target[p], endValue, index, targets);
1349 } else {
1350 _missingPlugin(p, endValue);
1351
1352 continue;
1353 }
1354 } else {
1355 _tweenComplexCSSString.call(this, target, p, startValue, endValue);
1356 }
1357
1358 props.push(p);
1359 }
1360 }
1361
1362 if (hasPriority) {
1363 _sortPropTweensByPriority(this);
1364 }
1365 },
1366 get: _get,
1367 aliases: _propertyAliases,
1368 getSetter: function getSetter(target, property, plugin) {
1369 //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.
1370 var p = _propertyAliases[property];
1371 p && p.indexOf(",") < 0 && (property = p);
1372 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);
1373 },
1374 core: {
1375 _removeProperty: _removeProperty,
1376 _getMatrix: _getMatrix
1377 }
1378};
1379gsap.utils.checkPrefix = _checkPropPrefix;
1380
1381(function (positionAndScale, rotation, others, aliases) {
1382 var all = _forEachName(positionAndScale + "," + rotation + "," + others, function (name) {
1383 _transformProps[name] = 1;
1384 });
1385
1386 _forEachName(rotation, function (name) {
1387 _config.units[name] = "deg";
1388 _rotationalProperties[name] = 1;
1389 });
1390
1391 _propertyAliases[all[13]] = positionAndScale + "," + rotation;
1392
1393 _forEachName(aliases, function (name) {
1394 var split = name.split(":");
1395 _propertyAliases[split[1]] = all[split[0]];
1396 });
1397})("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");
1398
1399_forEachName("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective", function (name) {
1400 _config.units[name] = "px";
1401});
1402
1403gsap.registerPlugin(CSSPlugin);
1404export { CSSPlugin as default, _getBBox, _createElement, _checkPropPrefix as checkPrefix };
\No newline at end of file