UNPKG

13 kBJavaScriptView Raw
1/*!
2 * matrix 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 */
12var _doc,
13 _win,
14 _docElement,
15 _body,
16 _divContainer,
17 _svgContainer,
18 _identityMatrix,
19 _transformProp = "transform",
20 _transformOriginProp = _transformProp + "Origin",
21 _hasOffsetBug,
22 _setDoc = function _setDoc(element) {
23 var doc = element.ownerDocument || element;
24
25 if (!(_transformProp in element.style) && "msTransform" in element.style) {
26 //to improve compatibility with old Microsoft browsers
27 _transformProp = "msTransform";
28 _transformOriginProp = _transformProp + "Origin";
29 }
30
31 while (doc.parentNode && (doc = doc.parentNode)) {}
32
33 _win = window;
34 _identityMatrix = new Matrix2D();
35
36 if (doc) {
37 _doc = doc;
38 _docElement = doc.documentElement;
39 _body = doc.body; // now test for the offset reporting bug. Use feature detection instead of browser sniffing to make things more bulletproof and future-proof. Hopefully Safari will fix their bug soon but it's 2020 and it's still not fixed.
40
41 var d1 = doc.createElement("div"),
42 d2 = doc.createElement("div");
43
44 _body.appendChild(d1);
45
46 d1.appendChild(d2);
47 d1.style.position = "static";
48 d1.style[_transformProp] = "translate3d(0,0,1px)";
49 _hasOffsetBug = d2.offsetParent !== d1;
50
51 _body.removeChild(d1);
52 }
53
54 return doc;
55},
56 _forceNonZeroScale = function _forceNonZeroScale(e) {
57 // walks up the element's ancestors and finds any that had their scale set to 0 via GSAP, and changes them to 0.0001 to ensure that measurements work
58 var a, cache;
59
60 while (e && e !== _body) {
61 cache = e._gsap;
62
63 if (cache && !cache.scaleX && !cache.scaleY && cache.renderTransform) {
64 cache.scaleX = cache.scaleY = 1e-4;
65 cache.renderTransform(1, cache);
66 a ? a.push(cache) : a = [cache];
67 }
68
69 e = e.parentNode;
70 }
71
72 return a;
73},
74 // possible future addition: pass an element to _forceDisplay() and it'll walk up all its ancestors and make sure anything with display: none is set to display: block, and if there's no parentNode, it'll add it to the body. It returns an Array that you can then feed to _revertDisplay() to have it revert all the changes it made.
75// _forceDisplay = e => {
76// let a = [],
77// parent;
78// while (e && e !== _body) {
79// parent = e.parentNode;
80// (_win.getComputedStyle(e).display === "none" || !parent) && a.push(e, e.style.display, parent) && (e.style.display = "block");
81// parent || _body.appendChild(e);
82// e = parent;
83// }
84// return a;
85// },
86// _revertDisplay = a => {
87// for (let i = 0; i < a.length; i+=3) {
88// a[i+1] ? (a[i].style.display = a[i+1]) : a[i].style.removeProperty("display");
89// a[i+2] || a[i].parentNode.removeChild(a[i]);
90// }
91// },
92_svgTemps = [],
93 //we create 3 elements for SVG, and 3 for other DOM elements and cache them for performance reasons. They get nested in _divContainer and _svgContainer so that just one element is added to the DOM on each successive attempt. Again, performance is key.
94_divTemps = [],
95 _getDocScrollTop = function _getDocScrollTop() {
96 return _win.pageYOffset || _doc.scrollTop || _docElement.scrollTop || _body.scrollTop || 0;
97},
98 _getDocScrollLeft = function _getDocScrollLeft() {
99 return _win.pageXOffset || _doc.scrollLeft || _docElement.scrollLeft || _body.scrollLeft || 0;
100},
101 _svgOwner = function _svgOwner(element) {
102 return element.ownerSVGElement || ((element.tagName + "").toLowerCase() === "svg" ? element : null);
103},
104 _isFixed = function _isFixed(element) {
105 if (_win.getComputedStyle(element).position === "fixed") {
106 return true;
107 }
108
109 element = element.parentNode;
110
111 if (element && element.nodeType === 1) {
112 // avoid document fragments which will throw an error.
113 return _isFixed(element);
114 }
115},
116 _createSibling = function _createSibling(element, i) {
117 if (element.parentNode && (_doc || _setDoc(element))) {
118 var svg = _svgOwner(element),
119 ns = svg ? svg.getAttribute("xmlns") || "http://www.w3.org/2000/svg" : "http://www.w3.org/1999/xhtml",
120 type = svg ? i ? "rect" : "g" : "div",
121 x = i !== 2 ? 0 : 100,
122 y = i === 3 ? 100 : 0,
123 css = "position:absolute;display:block;pointer-events:none;",
124 e = _doc.createElementNS ? _doc.createElementNS(ns.replace(/^https/, "http"), type) : _doc.createElement(type);
125
126 if (i) {
127 if (!svg) {
128 if (!_divContainer) {
129 _divContainer = _createSibling(element);
130 _divContainer.style.cssText = css;
131 }
132
133 e.style.cssText = css + "width:0.1px;height:0.1px;top:" + y + "px;left:" + x + "px";
134
135 _divContainer.appendChild(e);
136 } else {
137 if (!_svgContainer) {
138 _svgContainer = _createSibling(element);
139 }
140
141 e.setAttribute("width", 0.01);
142 e.setAttribute("height", 0.01);
143 e.setAttribute("transform", "translate(" + x + "," + y + ")");
144
145 _svgContainer.appendChild(e);
146 }
147 }
148
149 return e;
150 }
151
152 throw "Need document and parent.";
153},
154 _consolidate = function _consolidate(m) {
155 // replaces SVGTransformList.consolidate() because a bug in Firefox causes it to break pointer events. See https://greensock.com/forums/topic/23248-touch-is-not-working-on-draggable-in-firefox-windows-v324/?tab=comments#comment-109800
156 var c = new Matrix2D(),
157 i = 0;
158
159 for (; i < m.numberOfItems; i++) {
160 c.multiply(m.getItem(i).matrix);
161 }
162
163 return c;
164},
165 _placeSiblings = function _placeSiblings(element, adjustGOffset) {
166 var svg = _svgOwner(element),
167 isRootSVG = element === svg,
168 siblings = svg ? _svgTemps : _divTemps,
169 container,
170 m,
171 b,
172 x,
173 y;
174
175 if (element === _win) {
176 return element;
177 }
178
179 if (!siblings.length) {
180 siblings.push(_createSibling(element, 1), _createSibling(element, 2), _createSibling(element, 3));
181 }
182
183 container = svg ? _svgContainer : _divContainer;
184
185 if (svg) {
186 b = isRootSVG ? {
187 x: 0,
188 y: 0
189 } : element.getBBox();
190 m = element.transform ? element.transform.baseVal : {}; // IE11 doesn't follow the spec.
191
192 if (m.numberOfItems) {
193 m = m.numberOfItems > 1 ? _consolidate(m) : m.getItem(0).matrix; // don't call m.consolidate().matrix because a bug in Firefox makes pointer events not work when consolidate() is called on the same tick as getBoundingClientRect()! See https://greensock.com/forums/topic/23248-touch-is-not-working-on-draggable-in-firefox-windows-v324/?tab=comments#comment-109800
194
195 x = m.a * b.x + m.c * b.y;
196 y = m.b * b.x + m.d * b.y;
197 } else {
198 m = _identityMatrix;
199 x = b.x;
200 y = b.y;
201 }
202
203 if (adjustGOffset && element.tagName.toLowerCase() === "g") {
204 x = y = 0;
205 }
206
207 container.setAttribute("transform", "matrix(" + m.a + "," + m.b + "," + m.c + "," + m.d + "," + (m.e + x) + "," + (m.f + y) + ")");
208 (isRootSVG ? svg : element.parentNode).appendChild(container);
209 } else {
210 x = y = 0;
211
212 if (_hasOffsetBug) {
213 // some browsers (like Safari) have a bug that causes them to misreport offset values. When an ancestor element has a transform applied, it's supposed to treat it as if it's position: relative (new context). Safari botches this, so we need to find the closest ancestor (between the element and its offsetParent) that has a transform applied and if one is found, grab its offsetTop/Left and subtract them to compensate.
214 m = element.offsetParent;
215 b = element;
216
217 while (b && (b = b.parentNode) && b !== m && b.parentNode) {
218 if ((_win.getComputedStyle(b)[_transformProp] + "").length > 4) {
219 x = b.offsetLeft;
220 y = b.offsetTop;
221 b = 0;
222 }
223 }
224 }
225
226 b = container.style;
227 b.top = element.offsetTop - y + "px";
228 b.left = element.offsetLeft - x + "px";
229 m = _win.getComputedStyle(element);
230 b[_transformProp] = m[_transformProp];
231 b[_transformOriginProp] = m[_transformOriginProp];
232 b.border = m.border;
233 b.borderLeftStyle = m.borderLeftStyle;
234 b.borderTopStyle = m.borderTopStyle;
235 b.borderLeftWidth = m.borderLeftWidth;
236 b.borderTopWidth = m.borderTopWidth;
237 b.position = m.position === "fixed" ? "fixed" : "absolute";
238 element.parentNode.appendChild(container);
239 }
240
241 return container;
242},
243 _setMatrix = function _setMatrix(m, a, b, c, d, e, f) {
244 m.a = a;
245 m.b = b;
246 m.c = c;
247 m.d = d;
248 m.e = e;
249 m.f = f;
250 return m;
251};
252
253export var Matrix2D = /*#__PURE__*/function () {
254 function Matrix2D(a, b, c, d, e, f) {
255 if (a === void 0) {
256 a = 1;
257 }
258
259 if (b === void 0) {
260 b = 0;
261 }
262
263 if (c === void 0) {
264 c = 0;
265 }
266
267 if (d === void 0) {
268 d = 1;
269 }
270
271 if (e === void 0) {
272 e = 0;
273 }
274
275 if (f === void 0) {
276 f = 0;
277 }
278
279 _setMatrix(this, a, b, c, d, e, f);
280 }
281
282 var _proto = Matrix2D.prototype;
283
284 _proto.inverse = function inverse() {
285 var a = this.a,
286 b = this.b,
287 c = this.c,
288 d = this.d,
289 e = this.e,
290 f = this.f,
291 determinant = a * d - b * c || 1e-10;
292 return _setMatrix(this, d / determinant, -b / determinant, -c / determinant, a / determinant, (c * f - d * e) / determinant, -(a * f - b * e) / determinant);
293 };
294
295 _proto.multiply = function multiply(matrix) {
296 var a = this.a,
297 b = this.b,
298 c = this.c,
299 d = this.d,
300 e = this.e,
301 f = this.f,
302 a2 = matrix.a,
303 b2 = matrix.c,
304 c2 = matrix.b,
305 d2 = matrix.d,
306 e2 = matrix.e,
307 f2 = matrix.f;
308 return _setMatrix(this, a2 * a + c2 * c, a2 * b + c2 * d, b2 * a + d2 * c, b2 * b + d2 * d, e + e2 * a + f2 * c, f + e2 * b + f2 * d);
309 };
310
311 _proto.clone = function clone() {
312 return new Matrix2D(this.a, this.b, this.c, this.d, this.e, this.f);
313 };
314
315 _proto.equals = function equals(matrix) {
316 var a = this.a,
317 b = this.b,
318 c = this.c,
319 d = this.d,
320 e = this.e,
321 f = this.f;
322 return a === matrix.a && b === matrix.b && c === matrix.c && d === matrix.d && e === matrix.e && f === matrix.f;
323 };
324
325 _proto.apply = function apply(point, decoratee) {
326 if (decoratee === void 0) {
327 decoratee = {};
328 }
329
330 var x = point.x,
331 y = point.y,
332 a = this.a,
333 b = this.b,
334 c = this.c,
335 d = this.d,
336 e = this.e,
337 f = this.f;
338 decoratee.x = x * a + y * c + e || 0;
339 decoratee.y = x * b + y * d + f || 0;
340 return decoratee;
341 };
342
343 return Matrix2D;
344}(); //feed in an element and it'll return a 2D matrix (optionally inverted) so that you can translate between coordinate spaces.
345// Inverting lets you translate a global point into a local coordinate space. No inverting lets you go the other way.
346// We needed this to work around various browser bugs, like Firefox doesn't accurately report getScreenCTM() when there
347// are transforms applied to ancestor elements.
348// The matrix math to convert any x/y coordinate is as follows, which is wrapped in a convenient apply() method of Matrix2D above:
349// tx = m.a * x + m.c * y + m.e
350// ty = m.b * x + m.d * y + m.f
351
352export function getGlobalMatrix(element, inverse, adjustGOffset) {
353 // adjustGOffset is typically used only when grabbing an element's PARENT's global matrix, and it ignores the x/y offset of any SVG <g> elements because they behave in a special way.
354 if (!element || !element.parentNode || (_doc || _setDoc(element)).documentElement === element) {
355 return new Matrix2D();
356 }
357
358 var zeroScales = _forceNonZeroScale(element.parentNode),
359 svg = _svgOwner(element),
360 temps = svg ? _svgTemps : _divTemps,
361 container = _placeSiblings(element, adjustGOffset),
362 b1 = temps[0].getBoundingClientRect(),
363 b2 = temps[1].getBoundingClientRect(),
364 b3 = temps[2].getBoundingClientRect(),
365 parent = container.parentNode,
366 isFixed = _isFixed(element),
367 m = new Matrix2D((b2.left - b1.left) / 100, (b2.top - b1.top) / 100, (b3.left - b1.left) / 100, (b3.top - b1.top) / 100, b1.left + (isFixed ? 0 : _getDocScrollLeft()), b1.top + (isFixed ? 0 : _getDocScrollTop()));
368
369 parent.removeChild(container);
370
371 if (zeroScales) {
372 b1 = zeroScales.length;
373
374 while (b1--) {
375 b2 = zeroScales[b1];
376 b2.scaleX = b2.scaleY = 0;
377 b2.renderTransform(1, b2);
378 }
379 }
380
381 return inverse ? m.inverse() : m;
382} // export function getMatrix(element) {
383// _doc || _setDoc(element);
384// let m = (_win.getComputedStyle(element)[_transformProp] + "").substr(7).match(/[-.]*\d+[.e\-+]*\d*[e\-\+]*\d*/g),
385// is2D = m && m.length === 6;
386// return !m || m.length < 6 ? new Matrix2D() : new Matrix2D(+m[0], +m[1], +m[is2D ? 2 : 4], +m[is2D ? 3 : 5], +m[is2D ? 4 : 12], +m[is2D ? 5 : 13]);
387// }
\No newline at end of file