UNPKG

49 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (global = global || self, factory(global.window = global.window || {}));
5}(this, (function (exports) { 'use strict';
6
7 var _svgPathExp = /[achlmqstvz]|(-?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig,
8 _numbersExp = /(?:(-)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig,
9 _scientific = /[\+\-]?\d*\.?\d+e[\+\-]?\d+/ig,
10 _selectorExp = /(^[#\.][a-z]|[a-y][a-z])/i,
11 _DEG2RAD = Math.PI / 180,
12 _RAD2DEG = 180 / Math.PI,
13 _sin = Math.sin,
14 _cos = Math.cos,
15 _abs = Math.abs,
16 _sqrt = Math.sqrt,
17 _atan2 = Math.atan2,
18 _largeNum = 1e8,
19 _isString = function _isString(value) {
20 return typeof value === "string";
21 },
22 _isNumber = function _isNumber(value) {
23 return typeof value === "number";
24 },
25 _isUndefined = function _isUndefined(value) {
26 return typeof value === "undefined";
27 },
28 _temp = {},
29 _temp2 = {},
30 _roundingNum = 1e5,
31 _wrapProgress = function _wrapProgress(progress) {
32 return Math.round((progress + _largeNum) % 1 * _roundingNum) / _roundingNum || (progress < 0 ? 0 : 1);
33 },
34 _round = function _round(value) {
35 return Math.round(value * _roundingNum) / _roundingNum || 0;
36 },
37 _splitSegment = function _splitSegment(rawPath, segIndex, i, t) {
38 var segment = rawPath[segIndex],
39 shift = t === 1 ? 6 : subdivideSegment(segment, i, t);
40
41 if (shift && shift + i + 2 < segment.length) {
42 rawPath.splice(segIndex, 0, segment.slice(0, i + shift + 2));
43 segment.splice(0, i + shift);
44 return 1;
45 }
46 },
47 _reverseRawPath = function _reverseRawPath(rawPath, skipOuter) {
48 var i = rawPath.length;
49
50 if (!skipOuter) {
51 rawPath.reverse();
52 }
53
54 while (i--) {
55 if (!rawPath[i].reversed) {
56 reverseSegment(rawPath[i]);
57 }
58 }
59 },
60 _copyMetaData = function _copyMetaData(source, copy) {
61 copy.totalLength = source.totalLength;
62
63 if (source.samples) {
64 copy.samples = source.samples.slice(0);
65 copy.lookup = source.lookup.slice(0);
66 copy.minLength = source.minLength;
67 copy.resolution = source.resolution;
68 } else {
69 copy.totalPoints = source.totalPoints;
70 }
71
72 return copy;
73 },
74 _appendOrMerge = function _appendOrMerge(rawPath, segment) {
75 var index = rawPath.length,
76 prevSeg = rawPath[index - 1] || [],
77 l = prevSeg.length;
78
79 if (segment[0] === prevSeg[l - 2] && segment[1] === prevSeg[l - 1]) {
80 segment = prevSeg.concat(segment.slice(2));
81 index--;
82 }
83
84 rawPath[index] = segment;
85 };
86
87 function getRawPath(value) {
88 value = _isString(value) && _selectorExp.test(value) ? document.querySelector(value) || value : value;
89 var e = value.getAttribute ? value : 0,
90 rawPath;
91
92 if (e && (value = value.getAttribute("d"))) {
93 if (!e._gsPath) {
94 e._gsPath = {};
95 }
96
97 rawPath = e._gsPath[value];
98 return rawPath && !rawPath._dirty ? rawPath : e._gsPath[value] = stringToRawPath(value);
99 }
100
101 return !value ? console.warn("Expecting a <path> element or an SVG path data string") : _isString(value) ? stringToRawPath(value) : _isNumber(value[0]) ? [value] : value;
102 }
103 function copyRawPath(rawPath) {
104 var a = [],
105 i = 0;
106
107 for (; i < rawPath.length; i++) {
108 a[i] = _copyMetaData(rawPath[i], rawPath[i].slice(0));
109 }
110
111 return _copyMetaData(rawPath, a);
112 }
113 function reverseSegment(segment) {
114 var i = 0,
115 y;
116 segment.reverse();
117
118 for (; i < segment.length; i += 2) {
119 y = segment[i];
120 segment[i] = segment[i + 1];
121 segment[i + 1] = y;
122 }
123
124 segment.reversed = !segment.reversed;
125 }
126
127 var _createPath = function _createPath(e, ignore) {
128 var path = document.createElementNS("http://www.w3.org/2000/svg", "path"),
129 attr = [].slice.call(e.attributes),
130 i = attr.length,
131 name;
132 ignore = "," + ignore + ",";
133
134 while (--i > -1) {
135 name = attr[i].nodeName.toLowerCase();
136
137 if (ignore.indexOf("," + name + ",") < 0) {
138 path.setAttributeNS(null, name, attr[i].nodeValue);
139 }
140 }
141
142 return path;
143 },
144 _typeAttrs = {
145 rect: "rx,ry,x,y,width,height",
146 circle: "r,cx,cy",
147 ellipse: "rx,ry,cx,cy",
148 line: "x1,x2,y1,y2"
149 },
150 _attrToObj = function _attrToObj(e, attrs) {
151 var props = attrs ? attrs.split(",") : [],
152 obj = {},
153 i = props.length;
154
155 while (--i > -1) {
156 obj[props[i]] = +e.getAttribute(props[i]) || 0;
157 }
158
159 return obj;
160 };
161
162 function convertToPath(element, swap) {
163 var type = element.tagName.toLowerCase(),
164 circ = 0.552284749831,
165 data,
166 x,
167 y,
168 r,
169 ry,
170 path,
171 rcirc,
172 rycirc,
173 points,
174 w,
175 h,
176 x2,
177 x3,
178 x4,
179 x5,
180 x6,
181 y2,
182 y3,
183 y4,
184 y5,
185 y6,
186 attr;
187
188 if (type === "path" || !element.getBBox) {
189 return element;
190 }
191
192 path = _createPath(element, "x,y,width,height,cx,cy,rx,ry,r,x1,x2,y1,y2,points");
193 attr = _attrToObj(element, _typeAttrs[type]);
194
195 if (type === "rect") {
196 r = attr.rx;
197 ry = attr.ry || r;
198 x = attr.x;
199 y = attr.y;
200 w = attr.width - r * 2;
201 h = attr.height - ry * 2;
202
203 if (r || ry) {
204 x2 = x + r * (1 - circ);
205 x3 = x + r;
206 x4 = x3 + w;
207 x5 = x4 + r * circ;
208 x6 = x4 + r;
209 y2 = y + ry * (1 - circ);
210 y3 = y + ry;
211 y4 = y3 + h;
212 y5 = y4 + ry * circ;
213 y6 = y4 + ry;
214 data = "M" + x6 + "," + y3 + " V" + y4 + " C" + [x6, y5, x5, y6, x4, y6, x4 - (x4 - x3) / 3, y6, x3 + (x4 - x3) / 3, y6, x3, y6, x2, y6, x, y5, x, y4, x, y4 - (y4 - y3) / 3, x, y3 + (y4 - y3) / 3, x, y3, x, y2, x2, y, x3, y, x3 + (x4 - x3) / 3, y, x4 - (x4 - x3) / 3, y, x4, y, x5, y, x6, y2, x6, y3].join(",") + "z";
215 } else {
216 data = "M" + (x + w) + "," + y + " v" + h + " h" + -w + " v" + -h + " h" + w + "z";
217 }
218 } else if (type === "circle" || type === "ellipse") {
219 if (type === "circle") {
220 r = ry = attr.r;
221 rycirc = r * circ;
222 } else {
223 r = attr.rx;
224 ry = attr.ry;
225 rycirc = ry * circ;
226 }
227
228 x = attr.cx;
229 y = attr.cy;
230 rcirc = r * circ;
231 data = "M" + (x + r) + "," + y + " C" + [x + r, y + rycirc, x + rcirc, y + ry, x, y + ry, x - rcirc, y + ry, x - r, y + rycirc, x - r, y, x - r, y - rycirc, x - rcirc, y - ry, x, y - ry, x + rcirc, y - ry, x + r, y - rycirc, x + r, y].join(",") + "z";
232 } else if (type === "line") {
233 data = "M" + attr.x1 + "," + attr.y1 + " L" + attr.x2 + "," + attr.y2;
234 } else if (type === "polyline" || type === "polygon") {
235 points = (element.getAttribute("points") + "").match(_numbersExp) || [];
236 x = points.shift();
237 y = points.shift();
238 data = "M" + x + "," + y + " L" + points.join(",");
239
240 if (type === "polygon") {
241 data += "," + x + "," + y + "z";
242 }
243 }
244
245 path.setAttribute("d", rawPathToString(path._gsRawPath = stringToRawPath(data)));
246
247 if (swap && element.parentNode) {
248 element.parentNode.insertBefore(path, element);
249 element.parentNode.removeChild(element);
250 }
251
252 return path;
253 }
254
255 function getRotationAtBezierT(segment, i, t) {
256 var a = segment[i],
257 b = segment[i + 2],
258 c = segment[i + 4],
259 x;
260 a += (b - a) * t;
261 b += (c - b) * t;
262 a += (b - a) * t;
263 x = b + (c + (segment[i + 6] - c) * t - b) * t - a;
264 a = segment[i + 1];
265 b = segment[i + 3];
266 c = segment[i + 5];
267 a += (b - a) * t;
268 b += (c - b) * t;
269 a += (b - a) * t;
270 return _round(_atan2(b + (c + (segment[i + 7] - c) * t - b) * t - a, x) * _RAD2DEG);
271 }
272
273 function sliceRawPath(rawPath, start, end) {
274 if (_isUndefined(end)) {
275 end = 1;
276 }
277
278 start = start || 0;
279 var reverse = start > end,
280 loops = Math.max(0, ~~(_abs(end - start) - 1e-8));
281
282 if (reverse) {
283 reverse = end;
284 end = start;
285 start = reverse;
286 reverse = 1;
287 loops -= loops ? 1 : 0;
288 }
289
290 if (start < 0 || end < 0) {
291 var offset = ~~Math.min(start, end) + 1;
292 start += offset;
293 end += offset;
294 }
295
296 var path = copyRawPath(rawPath.totalLength ? rawPath : cacheRawPathMeasurements(rawPath)),
297 wrap = end > 1,
298 s = getProgressData(path, start, _temp, true),
299 e = getProgressData(path, end, _temp2),
300 eSeg = e.segment,
301 sSeg = s.segment,
302 eSegIndex = e.segIndex,
303 sSegIndex = s.segIndex,
304 ei = e.i,
305 si = s.i,
306 sameSegment = sSegIndex === eSegIndex,
307 sameBezier = ei === si && sameSegment,
308 invertedOrder = sameSegment && si > ei || sameBezier && s.t > e.t,
309 sShift,
310 eShift,
311 i,
312 copy,
313 totalSegments,
314 l,
315 j;
316
317 if (wrap || loops) {
318 if (_splitSegment(path, sSegIndex, si, s.t)) {
319 sShift = 1;
320 sSegIndex++;
321
322 if (sameBezier) {
323 if (invertedOrder) {
324 e.t /= s.t;
325 } else {
326 e.t = (e.t - s.t) / (1 - s.t);
327 eSegIndex++;
328 ei = 0;
329 }
330 } else if (sSegIndex <= eSegIndex + 1 && !invertedOrder) {
331 eSegIndex++;
332
333 if (sameSegment) {
334 ei -= si;
335 }
336 }
337 }
338
339 if (!e.t) {
340 eSegIndex--;
341 reverse && sSegIndex--;
342 } else if (_splitSegment(path, eSegIndex, ei, e.t)) {
343 invertedOrder && sShift && sSegIndex++;
344 reverse && eSegIndex++;
345 }
346
347 copy = [];
348 totalSegments = path.length;
349 l = 1 + totalSegments * loops;
350 j = sSegIndex;
351
352 if (reverse) {
353 eSegIndex = (eSegIndex || totalSegments) - 1;
354 l += (totalSegments - eSegIndex + sSegIndex) % totalSegments;
355
356 for (i = 0; i < l; i++) {
357 _appendOrMerge(copy, path[j]);
358
359 j = (j || totalSegments) - 1;
360 }
361 } else {
362 l += (totalSegments - sSegIndex + eSegIndex) % totalSegments;
363
364 for (i = 0; i < l; i++) {
365 _appendOrMerge(copy, path[j++ % totalSegments]);
366 }
367 }
368
369 path = copy;
370 } else {
371 eShift = e.t === 1 ? 6 : subdivideSegment(eSeg, ei, e.t);
372
373 if (start !== end) {
374 sShift = subdivideSegment(sSeg, si, sameBezier ? s.t / e.t : s.t);
375
376 if (sameSegment) {
377 eShift += sShift;
378 }
379
380 eSeg.splice(ei + eShift + 2);
381
382 if (sShift || si) {
383 sSeg.splice(0, si + sShift);
384 }
385
386 i = path.length;
387
388 while (i--) {
389 if (i < sSegIndex || i > eSegIndex) {
390 path.splice(i, 1);
391 }
392 }
393 } else {
394 eSeg.angle = getRotationAtBezierT(eSeg, ei + eShift, 0);
395 ei += eShift;
396 s = eSeg[ei];
397 e = eSeg[ei + 1];
398 eSeg.length = eSeg.totalLength = 0;
399 eSeg.totalPoints = path.totalPoints = 8;
400 eSeg.push(s, e, s, e, s, e, s, e);
401 }
402 }
403
404 reverse && _reverseRawPath(path, wrap || loops);
405 path.totalLength = 0;
406 return path;
407 }
408
409 function measureSegment(segment, startIndex, bezierQty) {
410 startIndex = startIndex || 0;
411
412 if (!segment.samples) {
413 segment.samples = [];
414 segment.lookup = [];
415 }
416
417 var resolution = ~~segment.resolution || 12,
418 inc = 1 / resolution,
419 endIndex = bezierQty ? startIndex + bezierQty * 6 + 1 : segment.length,
420 x1 = segment[startIndex],
421 y1 = segment[startIndex + 1],
422 samplesIndex = startIndex ? startIndex / 6 * resolution : 0,
423 samples = segment.samples,
424 lookup = segment.lookup,
425 min = (startIndex ? segment.minLength : _largeNum) || _largeNum,
426 prevLength = samples[samplesIndex + bezierQty * resolution - 1],
427 length = startIndex ? samples[samplesIndex - 1] : 0,
428 i,
429 j,
430 x4,
431 x3,
432 x2,
433 xd,
434 xd1,
435 y4,
436 y3,
437 y2,
438 yd,
439 yd1,
440 inv,
441 t,
442 lengthIndex,
443 l,
444 segLength;
445 samples.length = lookup.length = 0;
446
447 for (j = startIndex + 2; j < endIndex; j += 6) {
448 x4 = segment[j + 4] - x1;
449 x3 = segment[j + 2] - x1;
450 x2 = segment[j] - x1;
451 y4 = segment[j + 5] - y1;
452 y3 = segment[j + 3] - y1;
453 y2 = segment[j + 1] - y1;
454 xd = xd1 = yd = yd1 = 0;
455
456 if (_abs(x4) < 1e-5 && _abs(y4) < 1e-5 && _abs(x2) + _abs(y2) < 1e-5) {
457 if (segment.length > 8) {
458 segment.splice(j, 6);
459 j -= 6;
460 endIndex -= 6;
461 }
462 } else {
463 for (i = 1; i <= resolution; i++) {
464 t = inc * i;
465 inv = 1 - t;
466 xd = xd1 - (xd1 = (t * t * x4 + 3 * inv * (t * x3 + inv * x2)) * t);
467 yd = yd1 - (yd1 = (t * t * y4 + 3 * inv * (t * y3 + inv * y2)) * t);
468 l = _sqrt(yd * yd + xd * xd);
469
470 if (l < min) {
471 min = l;
472 }
473
474 length += l;
475 samples[samplesIndex++] = length;
476 }
477 }
478
479 x1 += x4;
480 y1 += y4;
481 }
482
483 if (prevLength) {
484 prevLength -= length;
485
486 for (; samplesIndex < samples.length; samplesIndex++) {
487 samples[samplesIndex] += prevLength;
488 }
489 }
490
491 if (samples.length && min) {
492 segment.totalLength = segLength = samples[samples.length - 1] || 0;
493 segment.minLength = min;
494 l = lengthIndex = 0;
495
496 for (i = 0; i < segLength; i += min) {
497 lookup[l++] = samples[lengthIndex] < i ? ++lengthIndex : lengthIndex;
498 }
499 } else {
500 segment.totalLength = samples[0] = 0;
501 }
502
503 return startIndex ? length - samples[startIndex / 2 - 1] : length;
504 }
505
506 function cacheRawPathMeasurements(rawPath, resolution) {
507 var pathLength, points, i;
508
509 for (i = pathLength = points = 0; i < rawPath.length; i++) {
510 rawPath[i].resolution = ~~resolution || 12;
511 points += rawPath[i].length;
512 pathLength += measureSegment(rawPath[i]);
513 }
514
515 rawPath.totalPoints = points;
516 rawPath.totalLength = pathLength;
517 return rawPath;
518 }
519 function subdivideSegment(segment, i, t) {
520 if (t <= 0 || t >= 1) {
521 return 0;
522 }
523
524 var ax = segment[i],
525 ay = segment[i + 1],
526 cp1x = segment[i + 2],
527 cp1y = segment[i + 3],
528 cp2x = segment[i + 4],
529 cp2y = segment[i + 5],
530 bx = segment[i + 6],
531 by = segment[i + 7],
532 x1a = ax + (cp1x - ax) * t,
533 x2 = cp1x + (cp2x - cp1x) * t,
534 y1a = ay + (cp1y - ay) * t,
535 y2 = cp1y + (cp2y - cp1y) * t,
536 x1 = x1a + (x2 - x1a) * t,
537 y1 = y1a + (y2 - y1a) * t,
538 x2a = cp2x + (bx - cp2x) * t,
539 y2a = cp2y + (by - cp2y) * t;
540 x2 += (x2a - x2) * t;
541 y2 += (y2a - y2) * t;
542 segment.splice(i + 2, 4, _round(x1a), _round(y1a), _round(x1), _round(y1), _round(x1 + (x2 - x1) * t), _round(y1 + (y2 - y1) * t), _round(x2), _round(y2), _round(x2a), _round(y2a));
543 segment.samples && segment.samples.splice(i / 6 * segment.resolution | 0, 0, 0, 0, 0, 0, 0, 0);
544 return 6;
545 }
546
547 function getProgressData(rawPath, progress, decoratee, pushToNextIfAtEnd) {
548 decoratee = decoratee || {};
549 rawPath.totalLength || cacheRawPathMeasurements(rawPath);
550
551 if (progress < 0 || progress > 1) {
552 progress = _wrapProgress(progress);
553 }
554
555 var segIndex = 0,
556 segment = rawPath[0],
557 samples,
558 resolution,
559 length,
560 min,
561 max,
562 i,
563 t;
564
565 if (rawPath.length > 1) {
566 length = rawPath.totalLength * progress;
567 max = i = 0;
568
569 while ((max += rawPath[i++].totalLength) < length) {
570 segIndex = i;
571 }
572
573 segment = rawPath[segIndex];
574 min = max - segment.totalLength;
575 progress = (length - min) / (max - min) || 0;
576 }
577
578 samples = segment.samples;
579 resolution = segment.resolution;
580 length = segment.totalLength * progress;
581 i = segment.lookup[~~(length / segment.minLength)] || 0;
582 min = i ? samples[i - 1] : 0;
583 max = samples[i];
584
585 if (max < length) {
586 min = max;
587 max = samples[++i];
588 }
589
590 t = 1 / resolution * ((length - min) / (max - min) + i % resolution);
591 i = ~~(i / resolution) * 6;
592
593 if (pushToNextIfAtEnd && t === 1) {
594 if (i + 6 < segment.length) {
595 i += 6;
596 t = 0;
597 } else if (segIndex + 1 < rawPath.length) {
598 i = t = 0;
599 segment = rawPath[++segIndex];
600 }
601 }
602
603 decoratee.t = t;
604 decoratee.i = i;
605 decoratee.path = rawPath;
606 decoratee.segment = segment;
607 decoratee.segIndex = segIndex;
608 return decoratee;
609 }
610
611 function getPositionOnPath(rawPath, progress, includeAngle, point) {
612 var segment = rawPath[0],
613 result = point || {},
614 samples,
615 resolution,
616 length,
617 min,
618 max,
619 i,
620 t,
621 a,
622 inv;
623
624 if (progress < 0 || progress > 1) {
625 progress = _wrapProgress(progress);
626 }
627
628 if (rawPath.length > 1) {
629 length = rawPath.totalLength * progress;
630 max = i = 0;
631
632 while ((max += rawPath[i++].totalLength) < length) {
633 segment = rawPath[i];
634 }
635
636 min = max - segment.totalLength;
637 progress = (length - min) / (max - min) || 0;
638 }
639
640 samples = segment.samples;
641 resolution = segment.resolution;
642 length = segment.totalLength * progress;
643 i = segment.lookup[~~(length / segment.minLength)] || 0;
644 min = i ? samples[i - 1] : 0;
645 max = samples[i];
646
647 if (max < length) {
648 min = max;
649 max = samples[++i];
650 }
651
652 t = 1 / resolution * ((length - min) / (max - min) + i % resolution) || 0;
653 inv = 1 - t;
654 i = ~~(i / resolution) * 6;
655 a = segment[i];
656 result.x = _round((t * t * (segment[i + 6] - a) + 3 * inv * (t * (segment[i + 4] - a) + inv * (segment[i + 2] - a))) * t + a);
657 result.y = _round((t * t * (segment[i + 7] - (a = segment[i + 1])) + 3 * inv * (t * (segment[i + 5] - a) + inv * (segment[i + 3] - a))) * t + a);
658
659 if (includeAngle) {
660 result.angle = segment.totalLength ? getRotationAtBezierT(segment, i, t >= 1 ? 1 - 1e-9 : t ? t : 1e-9) : segment.angle || 0;
661 }
662
663 return result;
664 }
665 function transformRawPath(rawPath, a, b, c, d, tx, ty) {
666 var j = rawPath.length,
667 segment,
668 l,
669 i,
670 x,
671 y;
672
673 while (--j > -1) {
674 segment = rawPath[j];
675 l = segment.length;
676
677 for (i = 0; i < l; i += 2) {
678 x = segment[i];
679 y = segment[i + 1];
680 segment[i] = x * a + y * c + tx;
681 segment[i + 1] = x * b + y * d + ty;
682 }
683 }
684
685 rawPath._dirty = 1;
686 return rawPath;
687 }
688
689 function arcToSegment(lastX, lastY, rx, ry, angle, largeArcFlag, sweepFlag, x, y) {
690 if (lastX === x && lastY === y) {
691 return;
692 }
693
694 rx = _abs(rx);
695 ry = _abs(ry);
696
697 var angleRad = angle % 360 * _DEG2RAD,
698 cosAngle = _cos(angleRad),
699 sinAngle = _sin(angleRad),
700 PI = Math.PI,
701 TWOPI = PI * 2,
702 dx2 = (lastX - x) / 2,
703 dy2 = (lastY - y) / 2,
704 x1 = cosAngle * dx2 + sinAngle * dy2,
705 y1 = -sinAngle * dx2 + cosAngle * dy2,
706 x1_sq = x1 * x1,
707 y1_sq = y1 * y1,
708 radiiCheck = x1_sq / (rx * rx) + y1_sq / (ry * ry);
709
710 if (radiiCheck > 1) {
711 rx = _sqrt(radiiCheck) * rx;
712 ry = _sqrt(radiiCheck) * ry;
713 }
714
715 var rx_sq = rx * rx,
716 ry_sq = ry * ry,
717 sq = (rx_sq * ry_sq - rx_sq * y1_sq - ry_sq * x1_sq) / (rx_sq * y1_sq + ry_sq * x1_sq);
718
719 if (sq < 0) {
720 sq = 0;
721 }
722
723 var coef = (largeArcFlag === sweepFlag ? -1 : 1) * _sqrt(sq),
724 cx1 = coef * (rx * y1 / ry),
725 cy1 = coef * -(ry * x1 / rx),
726 sx2 = (lastX + x) / 2,
727 sy2 = (lastY + y) / 2,
728 cx = sx2 + (cosAngle * cx1 - sinAngle * cy1),
729 cy = sy2 + (sinAngle * cx1 + cosAngle * cy1),
730 ux = (x1 - cx1) / rx,
731 uy = (y1 - cy1) / ry,
732 vx = (-x1 - cx1) / rx,
733 vy = (-y1 - cy1) / ry,
734 temp = ux * ux + uy * uy,
735 angleStart = (uy < 0 ? -1 : 1) * Math.acos(ux / _sqrt(temp)),
736 angleExtent = (ux * vy - uy * vx < 0 ? -1 : 1) * Math.acos((ux * vx + uy * vy) / _sqrt(temp * (vx * vx + vy * vy)));
737
738 isNaN(angleExtent) && (angleExtent = PI);
739
740 if (!sweepFlag && angleExtent > 0) {
741 angleExtent -= TWOPI;
742 } else if (sweepFlag && angleExtent < 0) {
743 angleExtent += TWOPI;
744 }
745
746 angleStart %= TWOPI;
747 angleExtent %= TWOPI;
748
749 var segments = Math.ceil(_abs(angleExtent) / (TWOPI / 4)),
750 rawPath = [],
751 angleIncrement = angleExtent / segments,
752 controlLength = 4 / 3 * _sin(angleIncrement / 2) / (1 + _cos(angleIncrement / 2)),
753 ma = cosAngle * rx,
754 mb = sinAngle * rx,
755 mc = sinAngle * -ry,
756 md = cosAngle * ry,
757 i;
758
759 for (i = 0; i < segments; i++) {
760 angle = angleStart + i * angleIncrement;
761 x1 = _cos(angle);
762 y1 = _sin(angle);
763 ux = _cos(angle += angleIncrement);
764 uy = _sin(angle);
765 rawPath.push(x1 - controlLength * y1, y1 + controlLength * x1, ux + controlLength * uy, uy - controlLength * ux, ux, uy);
766 }
767
768 for (i = 0; i < rawPath.length; i += 2) {
769 x1 = rawPath[i];
770 y1 = rawPath[i + 1];
771 rawPath[i] = x1 * ma + y1 * mc + cx;
772 rawPath[i + 1] = x1 * mb + y1 * md + cy;
773 }
774
775 rawPath[i - 2] = x;
776 rawPath[i - 1] = y;
777 return rawPath;
778 }
779
780 function stringToRawPath(d) {
781 var a = (d + "").replace(_scientific, function (m) {
782 var n = +m;
783 return n < 0.0001 && n > -0.0001 ? 0 : n;
784 }).match(_svgPathExp) || [],
785 path = [],
786 relativeX = 0,
787 relativeY = 0,
788 twoThirds = 2 / 3,
789 elements = a.length,
790 points = 0,
791 errorMessage = "ERROR: malformed path: " + d,
792 i,
793 j,
794 x,
795 y,
796 command,
797 isRelative,
798 segment,
799 startX,
800 startY,
801 difX,
802 difY,
803 beziers,
804 prevCommand,
805 flag1,
806 flag2,
807 line = function line(sx, sy, ex, ey) {
808 difX = (ex - sx) / 3;
809 difY = (ey - sy) / 3;
810 segment.push(sx + difX, sy + difY, ex - difX, ey - difY, ex, ey);
811 };
812
813 if (!d || !isNaN(a[0]) || isNaN(a[1])) {
814 console.log(errorMessage);
815 return path;
816 }
817
818 for (i = 0; i < elements; i++) {
819 prevCommand = command;
820
821 if (isNaN(a[i])) {
822 command = a[i].toUpperCase();
823 isRelative = command !== a[i];
824 } else {
825 i--;
826 }
827
828 x = +a[i + 1];
829 y = +a[i + 2];
830
831 if (isRelative) {
832 x += relativeX;
833 y += relativeY;
834 }
835
836 if (!i) {
837 startX = x;
838 startY = y;
839 }
840
841 if (command === "M") {
842 if (segment) {
843 if (segment.length < 8) {
844 path.length -= 1;
845 } else {
846 points += segment.length;
847 }
848 }
849
850 relativeX = startX = x;
851 relativeY = startY = y;
852 segment = [x, y];
853 path.push(segment);
854 i += 2;
855 command = "L";
856 } else if (command === "C") {
857 if (!segment) {
858 segment = [0, 0];
859 }
860
861 if (!isRelative) {
862 relativeX = relativeY = 0;
863 }
864
865 segment.push(x, y, relativeX + a[i + 3] * 1, relativeY + a[i + 4] * 1, relativeX += a[i + 5] * 1, relativeY += a[i + 6] * 1);
866 i += 6;
867 } else if (command === "S") {
868 difX = relativeX;
869 difY = relativeY;
870
871 if (prevCommand === "C" || prevCommand === "S") {
872 difX += relativeX - segment[segment.length - 4];
873 difY += relativeY - segment[segment.length - 3];
874 }
875
876 if (!isRelative) {
877 relativeX = relativeY = 0;
878 }
879
880 segment.push(difX, difY, x, y, relativeX += a[i + 3] * 1, relativeY += a[i + 4] * 1);
881 i += 4;
882 } else if (command === "Q") {
883 difX = relativeX + (x - relativeX) * twoThirds;
884 difY = relativeY + (y - relativeY) * twoThirds;
885
886 if (!isRelative) {
887 relativeX = relativeY = 0;
888 }
889
890 relativeX += a[i + 3] * 1;
891 relativeY += a[i + 4] * 1;
892 segment.push(difX, difY, relativeX + (x - relativeX) * twoThirds, relativeY + (y - relativeY) * twoThirds, relativeX, relativeY);
893 i += 4;
894 } else if (command === "T") {
895 difX = relativeX - segment[segment.length - 4];
896 difY = relativeY - segment[segment.length - 3];
897 segment.push(relativeX + difX, relativeY + difY, x + (relativeX + difX * 1.5 - x) * twoThirds, y + (relativeY + difY * 1.5 - y) * twoThirds, relativeX = x, relativeY = y);
898 i += 2;
899 } else if (command === "H") {
900 line(relativeX, relativeY, relativeX = x, relativeY);
901 i += 1;
902 } else if (command === "V") {
903 line(relativeX, relativeY, relativeX, relativeY = x + (isRelative ? relativeY - relativeX : 0));
904 i += 1;
905 } else if (command === "L" || command === "Z") {
906 if (command === "Z") {
907 x = startX;
908 y = startY;
909 segment.closed = true;
910 }
911
912 if (command === "L" || _abs(relativeX - x) > 0.5 || _abs(relativeY - y) > 0.5) {
913 line(relativeX, relativeY, x, y);
914
915 if (command === "L") {
916 i += 2;
917 }
918 }
919
920 relativeX = x;
921 relativeY = y;
922 } else if (command === "A") {
923 flag1 = a[i + 4];
924 flag2 = a[i + 5];
925 difX = a[i + 6];
926 difY = a[i + 7];
927 j = 7;
928
929 if (flag1.length > 1) {
930 if (flag1.length < 3) {
931 difY = difX;
932 difX = flag2;
933 j--;
934 } else {
935 difY = flag2;
936 difX = flag1.substr(2);
937 j -= 2;
938 }
939
940 flag2 = flag1.charAt(1);
941 flag1 = flag1.charAt(0);
942 }
943
944 beziers = arcToSegment(relativeX, relativeY, +a[i + 1], +a[i + 2], +a[i + 3], +flag1, +flag2, (isRelative ? relativeX : 0) + difX * 1, (isRelative ? relativeY : 0) + difY * 1);
945 i += j;
946
947 if (beziers) {
948 for (j = 0; j < beziers.length; j++) {
949 segment.push(beziers[j]);
950 }
951 }
952
953 relativeX = segment[segment.length - 2];
954 relativeY = segment[segment.length - 1];
955 } else {
956 console.log(errorMessage);
957 }
958 }
959
960 i = segment.length;
961
962 if (i < 6) {
963 path.pop();
964 i = 0;
965 } else if (segment[0] === segment[i - 2] && segment[1] === segment[i - 1]) {
966 segment.closed = true;
967 }
968
969 path.totalPoints = points + i;
970 return path;
971 }
972 function flatPointsToSegment(points, curviness) {
973 if (curviness === void 0) {
974 curviness = 1;
975 }
976
977 var x = points[0],
978 y = 0,
979 segment = [x, y],
980 i = 2;
981
982 for (; i < points.length; i += 2) {
983 segment.push(x, y, points[i], y = (points[i] - x) * curviness / 2, x = points[i], -y);
984 }
985
986 return segment;
987 }
988 function pointsToSegment(points, curviness, cornerThreshold) {
989 var l = points.length - 2,
990 x = +points[0],
991 y = +points[1],
992 nextX = +points[2],
993 nextY = +points[3],
994 segment = [x, y, x, y],
995 dx2 = nextX - x,
996 dy2 = nextY - y,
997 closed = Math.abs(points[l] - x) < 0.001 && Math.abs(points[l + 1] - y) < 0.001,
998 prevX,
999 prevY,
1000 angle,
1001 slope,
1002 i,
1003 dx1,
1004 dx3,
1005 dy1,
1006 dy3,
1007 d1,
1008 d2,
1009 a,
1010 b,
1011 c;
1012
1013 if (isNaN(cornerThreshold)) {
1014 cornerThreshold = Math.PI / 10;
1015 }
1016
1017 if (closed) {
1018 points.push(nextX, nextY);
1019 nextX = x;
1020 nextY = y;
1021 x = points[l - 2];
1022 y = points[l - 1];
1023 points.unshift(x, y);
1024 l += 4;
1025 }
1026
1027 curviness = curviness || curviness === 0 ? +curviness : 1;
1028
1029 for (i = 2; i < l; i += 2) {
1030 prevX = x;
1031 prevY = y;
1032 x = nextX;
1033 y = nextY;
1034 nextX = +points[i + 2];
1035 nextY = +points[i + 3];
1036 dx1 = dx2;
1037 dy1 = dy2;
1038 dx2 = nextX - x;
1039 dy2 = nextY - y;
1040 dx3 = nextX - prevX;
1041 dy3 = nextY - prevY;
1042 a = dx1 * dx1 + dy1 * dy1;
1043 b = dx2 * dx2 + dy2 * dy2;
1044 c = dx3 * dx3 + dy3 * dy3;
1045 angle = Math.acos((a + b - c) / _sqrt(4 * a * b));
1046 d2 = angle / Math.PI * curviness;
1047 d1 = _sqrt(a) * d2;
1048 d2 *= _sqrt(b);
1049
1050 if (x !== prevX || y !== prevY) {
1051 if (angle > cornerThreshold) {
1052 slope = _atan2(dy3, dx3);
1053 segment.push(_round(x - _cos(slope) * d1), _round(y - _sin(slope) * d1), _round(x), _round(y), _round(x + _cos(slope) * d2), _round(y + _sin(slope) * d2));
1054 } else {
1055 slope = _atan2(dy1, dx1);
1056 segment.push(_round(x - _cos(slope) * d1), _round(y - _sin(slope) * d1));
1057 slope = _atan2(dy2, dx2);
1058 segment.push(_round(x), _round(y), _round(x + _cos(slope) * d2), _round(y + _sin(slope) * d2));
1059 }
1060 }
1061 }
1062
1063 segment.push(_round(nextX), _round(nextY), _round(nextX), _round(nextY));
1064
1065 if (closed) {
1066 segment.splice(0, 6);
1067 segment.length = segment.length - 6;
1068 }
1069
1070 return segment;
1071 }
1072 function rawPathToString(rawPath) {
1073 if (_isNumber(rawPath[0])) {
1074 rawPath = [rawPath];
1075 }
1076
1077 var result = "",
1078 l = rawPath.length,
1079 sl,
1080 s,
1081 i,
1082 segment;
1083
1084 for (s = 0; s < l; s++) {
1085 segment = rawPath[s];
1086 result += "M" + _round(segment[0]) + "," + _round(segment[1]) + " C";
1087 sl = segment.length;
1088
1089 for (i = 2; i < sl; i++) {
1090 result += _round(segment[i++]) + "," + _round(segment[i++]) + " " + _round(segment[i++]) + "," + _round(segment[i++]) + " " + _round(segment[i++]) + "," + _round(segment[i]) + " ";
1091 }
1092
1093 if (segment.closed) {
1094 result += "z";
1095 }
1096 }
1097
1098 return result;
1099 }
1100
1101 var _doc,
1102 _win,
1103 _docElement,
1104 _body,
1105 _divContainer,
1106 _svgContainer,
1107 _identityMatrix,
1108 _transformProp = "transform",
1109 _transformOriginProp = _transformProp + "Origin",
1110 _hasOffsetBug,
1111 _setDoc = function _setDoc(element) {
1112 var doc = element.ownerDocument || element;
1113
1114 if (!(_transformProp in element.style) && "msTransform" in element.style) {
1115 _transformProp = "msTransform";
1116 _transformOriginProp = _transformProp + "Origin";
1117 }
1118
1119 while (doc.parentNode && (doc = doc.parentNode)) {}
1120
1121 _win = window;
1122 _identityMatrix = new Matrix2D();
1123
1124 if (doc) {
1125 _doc = doc;
1126 _docElement = doc.documentElement;
1127 _body = doc.body;
1128 var d1 = doc.createElement("div"),
1129 d2 = doc.createElement("div");
1130
1131 _body.appendChild(d1);
1132
1133 d1.appendChild(d2);
1134 d1.style.position = "static";
1135 d1.style[_transformProp] = "translate3d(0,0,1px)";
1136 _hasOffsetBug = d2.offsetParent !== d1;
1137
1138 _body.removeChild(d1);
1139 }
1140
1141 return doc;
1142 },
1143 _forceNonZeroScale = function _forceNonZeroScale(e) {
1144 var a, cache;
1145
1146 while (e && e !== _body) {
1147 cache = e._gsap;
1148
1149 if (cache && !cache.scaleX && !cache.scaleY && cache.renderTransform) {
1150 cache.scaleX = cache.scaleY = 1e-4;
1151 cache.renderTransform(1, cache);
1152 a ? a.push(cache) : a = [cache];
1153 }
1154
1155 e = e.parentNode;
1156 }
1157
1158 return a;
1159 },
1160 _svgTemps = [],
1161 _divTemps = [],
1162 _getDocScrollTop = function _getDocScrollTop() {
1163 return _win.pageYOffset || _doc.scrollTop || _docElement.scrollTop || _body.scrollTop || 0;
1164 },
1165 _getDocScrollLeft = function _getDocScrollLeft() {
1166 return _win.pageXOffset || _doc.scrollLeft || _docElement.scrollLeft || _body.scrollLeft || 0;
1167 },
1168 _svgOwner = function _svgOwner(element) {
1169 return element.ownerSVGElement || ((element.tagName + "").toLowerCase() === "svg" ? element : null);
1170 },
1171 _isFixed = function _isFixed(element) {
1172 if (_win.getComputedStyle(element).position === "fixed") {
1173 return true;
1174 }
1175
1176 element = element.parentNode;
1177
1178 if (element && element.nodeType === 1) {
1179 return _isFixed(element);
1180 }
1181 },
1182 _createSibling = function _createSibling(element, i) {
1183 if (element.parentNode && (_doc || _setDoc(element))) {
1184 var svg = _svgOwner(element),
1185 ns = svg ? svg.getAttribute("xmlns") || "http://www.w3.org/2000/svg" : "http://www.w3.org/1999/xhtml",
1186 type = svg ? i ? "rect" : "g" : "div",
1187 x = i !== 2 ? 0 : 100,
1188 y = i === 3 ? 100 : 0,
1189 css = "position:absolute;display:block;pointer-events:none;",
1190 e = _doc.createElementNS ? _doc.createElementNS(ns.replace(/^https/, "http"), type) : _doc.createElement(type);
1191
1192 if (i) {
1193 if (!svg) {
1194 if (!_divContainer) {
1195 _divContainer = _createSibling(element);
1196 _divContainer.style.cssText = css;
1197 }
1198
1199 e.style.cssText = css + "width:0.1px;height:0.1px;top:" + y + "px;left:" + x + "px";
1200
1201 _divContainer.appendChild(e);
1202 } else {
1203 if (!_svgContainer) {
1204 _svgContainer = _createSibling(element);
1205 }
1206
1207 e.setAttribute("width", 0.01);
1208 e.setAttribute("height", 0.01);
1209 e.setAttribute("transform", "translate(" + x + "," + y + ")");
1210
1211 _svgContainer.appendChild(e);
1212 }
1213 }
1214
1215 return e;
1216 }
1217
1218 throw "Need document and parent.";
1219 },
1220 _consolidate = function _consolidate(m) {
1221 var c = new Matrix2D(),
1222 i = 0;
1223
1224 for (; i < m.numberOfItems; i++) {
1225 c.multiply(m.getItem(i).matrix);
1226 }
1227
1228 return c;
1229 },
1230 _placeSiblings = function _placeSiblings(element, adjustGOffset) {
1231 var svg = _svgOwner(element),
1232 isRootSVG = element === svg,
1233 siblings = svg ? _svgTemps : _divTemps,
1234 container,
1235 m,
1236 b,
1237 x,
1238 y;
1239
1240 if (element === _win) {
1241 return element;
1242 }
1243
1244 if (!siblings.length) {
1245 siblings.push(_createSibling(element, 1), _createSibling(element, 2), _createSibling(element, 3));
1246 }
1247
1248 container = svg ? _svgContainer : _divContainer;
1249
1250 if (svg) {
1251 b = isRootSVG ? {
1252 x: 0,
1253 y: 0
1254 } : element.getBBox();
1255 m = element.transform ? element.transform.baseVal : {};
1256
1257 if (m.numberOfItems) {
1258 m = m.numberOfItems > 1 ? _consolidate(m) : m.getItem(0).matrix;
1259 x = m.a * b.x + m.c * b.y;
1260 y = m.b * b.x + m.d * b.y;
1261 } else {
1262 m = _identityMatrix;
1263 x = b.x;
1264 y = b.y;
1265 }
1266
1267 if (adjustGOffset && element.tagName.toLowerCase() === "g") {
1268 x = y = 0;
1269 }
1270
1271 container.setAttribute("transform", "matrix(" + m.a + "," + m.b + "," + m.c + "," + m.d + "," + (m.e + x) + "," + (m.f + y) + ")");
1272 (isRootSVG ? svg : element.parentNode).appendChild(container);
1273 } else {
1274 x = y = 0;
1275
1276 if (_hasOffsetBug) {
1277 m = element.offsetParent;
1278 b = element;
1279
1280 while (b && (b = b.parentNode) && b !== m && b.parentNode) {
1281 if ((_win.getComputedStyle(b)[_transformProp] + "").length > 4) {
1282 x = b.offsetLeft;
1283 y = b.offsetTop;
1284 b = 0;
1285 }
1286 }
1287 }
1288
1289 b = container.style;
1290 b.top = element.offsetTop - y + "px";
1291 b.left = element.offsetLeft - x + "px";
1292 m = _win.getComputedStyle(element);
1293 b[_transformProp] = m[_transformProp];
1294 b[_transformOriginProp] = m[_transformOriginProp];
1295 b.border = m.border;
1296 b.borderLeftStyle = m.borderLeftStyle;
1297 b.borderTopStyle = m.borderTopStyle;
1298 b.borderLeftWidth = m.borderLeftWidth;
1299 b.borderTopWidth = m.borderTopWidth;
1300 b.position = m.position === "fixed" ? "fixed" : "absolute";
1301 element.parentNode.appendChild(container);
1302 }
1303
1304 return container;
1305 },
1306 _setMatrix = function _setMatrix(m, a, b, c, d, e, f) {
1307 m.a = a;
1308 m.b = b;
1309 m.c = c;
1310 m.d = d;
1311 m.e = e;
1312 m.f = f;
1313 return m;
1314 };
1315
1316 var Matrix2D = function () {
1317 function Matrix2D(a, b, c, d, e, f) {
1318 if (a === void 0) {
1319 a = 1;
1320 }
1321
1322 if (b === void 0) {
1323 b = 0;
1324 }
1325
1326 if (c === void 0) {
1327 c = 0;
1328 }
1329
1330 if (d === void 0) {
1331 d = 1;
1332 }
1333
1334 if (e === void 0) {
1335 e = 0;
1336 }
1337
1338 if (f === void 0) {
1339 f = 0;
1340 }
1341
1342 _setMatrix(this, a, b, c, d, e, f);
1343 }
1344
1345 var _proto = Matrix2D.prototype;
1346
1347 _proto.inverse = function inverse() {
1348 var a = this.a,
1349 b = this.b,
1350 c = this.c,
1351 d = this.d,
1352 e = this.e,
1353 f = this.f,
1354 determinant = a * d - b * c || 1e-10;
1355 return _setMatrix(this, d / determinant, -b / determinant, -c / determinant, a / determinant, (c * f - d * e) / determinant, -(a * f - b * e) / determinant);
1356 };
1357
1358 _proto.multiply = function multiply(matrix) {
1359 var a = this.a,
1360 b = this.b,
1361 c = this.c,
1362 d = this.d,
1363 e = this.e,
1364 f = this.f,
1365 a2 = matrix.a,
1366 b2 = matrix.c,
1367 c2 = matrix.b,
1368 d2 = matrix.d,
1369 e2 = matrix.e,
1370 f2 = matrix.f;
1371 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);
1372 };
1373
1374 _proto.clone = function clone() {
1375 return new Matrix2D(this.a, this.b, this.c, this.d, this.e, this.f);
1376 };
1377
1378 _proto.equals = function equals(matrix) {
1379 var a = this.a,
1380 b = this.b,
1381 c = this.c,
1382 d = this.d,
1383 e = this.e,
1384 f = this.f;
1385 return a === matrix.a && b === matrix.b && c === matrix.c && d === matrix.d && e === matrix.e && f === matrix.f;
1386 };
1387
1388 _proto.apply = function apply(point, decoratee) {
1389 if (decoratee === void 0) {
1390 decoratee = {};
1391 }
1392
1393 var x = point.x,
1394 y = point.y,
1395 a = this.a,
1396 b = this.b,
1397 c = this.c,
1398 d = this.d,
1399 e = this.e,
1400 f = this.f;
1401 decoratee.x = x * a + y * c + e || 0;
1402 decoratee.y = x * b + y * d + f || 0;
1403 return decoratee;
1404 };
1405
1406 return Matrix2D;
1407 }();
1408 function getGlobalMatrix(element, inverse, adjustGOffset) {
1409 if (!element || !element.parentNode || (_doc || _setDoc(element)).documentElement === element) {
1410 return new Matrix2D();
1411 }
1412
1413 var zeroScales = _forceNonZeroScale(element.parentNode),
1414 svg = _svgOwner(element),
1415 temps = svg ? _svgTemps : _divTemps,
1416 container = _placeSiblings(element, adjustGOffset),
1417 b1 = temps[0].getBoundingClientRect(),
1418 b2 = temps[1].getBoundingClientRect(),
1419 b3 = temps[2].getBoundingClientRect(),
1420 parent = container.parentNode,
1421 isFixed = _isFixed(element),
1422 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()));
1423
1424 parent.removeChild(container);
1425
1426 if (zeroScales) {
1427 b1 = zeroScales.length;
1428
1429 while (b1--) {
1430 b2 = zeroScales[b1];
1431 b2.scaleX = b2.scaleY = 0;
1432 b2.renderTransform(1, b2);
1433 }
1434 }
1435
1436 return inverse ? m.inverse() : m;
1437 }
1438
1439 /*!
1440 * MotionPathPlugin 3.5.1
1441 * https://greensock.com
1442 *
1443 * @license Copyright 2008-2020, GreenSock. All rights reserved.
1444 * Subject to the terms at https://greensock.com/standard-license or for
1445 * Club GreenSock members, the agreement issued with that membership.
1446 * @author: Jack Doyle, jack@greensock.com
1447 */
1448
1449 var _xProps = ["x", "translateX", "left", "marginLeft"],
1450 _yProps = ["y", "translateY", "top", "marginTop"],
1451 _DEG2RAD$1 = Math.PI / 180,
1452 gsap,
1453 PropTween,
1454 _getUnit,
1455 _toArray,
1456 _getGSAP = function _getGSAP() {
1457 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap;
1458 },
1459 _populateSegmentFromArray = function _populateSegmentFromArray(segment, values, property, mode) {
1460 var l = values.length,
1461 si = mode === 2 ? 0 : mode,
1462 i = 0;
1463
1464 for (; i < l; i++) {
1465 segment[si] = parseFloat(values[i][property]);
1466 mode === 2 && (segment[si + 1] = 0);
1467 si += 2;
1468 }
1469
1470 return segment;
1471 },
1472 _getPropNum = function _getPropNum(target, prop, unit) {
1473 return parseFloat(target._gsap.get(target, prop, unit || "px")) || 0;
1474 },
1475 _relativize = function _relativize(segment) {
1476 var x = segment[0],
1477 y = segment[1],
1478 i;
1479
1480 for (i = 2; i < segment.length; i += 2) {
1481 x = segment[i] += x;
1482 y = segment[i + 1] += y;
1483 }
1484 },
1485 _segmentToRawPath = function _segmentToRawPath(plugin, segment, target, x, y, slicer, vars) {
1486 if (vars.type === "cubic") {
1487 segment = [segment];
1488 } else {
1489 segment.unshift(_getPropNum(target, x, vars.unitX), y ? _getPropNum(target, y, vars.unitY) : 0);
1490 vars.relative && _relativize(segment);
1491 var pointFunc = y ? pointsToSegment : flatPointsToSegment;
1492 segment = [pointFunc(segment, vars.curviness)];
1493 }
1494
1495 segment = slicer(_align(segment, target, vars));
1496
1497 _addDimensionalPropTween(plugin, target, x, segment, "x", vars.unitX);
1498
1499 y && _addDimensionalPropTween(plugin, target, y, segment, "y", vars.unitY);
1500 return cacheRawPathMeasurements(segment, vars.resolution || (vars.curviness === 0 ? 20 : 12));
1501 },
1502 _emptyFunc = function _emptyFunc(v) {
1503 return v;
1504 },
1505 _numExp = /[-+\.]*\d+[\.e\-\+]*\d*[e\-\+]*\d*/g,
1506 _originToPoint = function _originToPoint(element, origin, parentMatrix) {
1507 var m = getGlobalMatrix(element),
1508 svg,
1509 x,
1510 y;
1511
1512 if ((element.tagName + "").toLowerCase() === "svg") {
1513 svg = element.viewBox.baseVal;
1514 x = svg.x;
1515 y = svg.y;
1516 svg.width || (svg = {
1517 width: +element.getAttribute("width"),
1518 height: +element.getAttribute("height")
1519 });
1520 } else {
1521 svg = origin && element.getBBox && element.getBBox();
1522 x = y = 0;
1523 }
1524
1525 if (origin && origin !== "auto") {
1526 x += origin.push ? origin[0] * (svg ? svg.width : element.offsetWidth || 0) : origin.x;
1527 y += origin.push ? origin[1] * (svg ? svg.height : element.offsetHeight || 0) : origin.y;
1528 }
1529
1530 return parentMatrix.apply(x || y ? m.apply({
1531 x: x,
1532 y: y
1533 }) : {
1534 x: m.e,
1535 y: m.f
1536 });
1537 },
1538 _getAlignMatrix = function _getAlignMatrix(fromElement, toElement, fromOrigin, toOrigin) {
1539 var parentMatrix = getGlobalMatrix(fromElement.parentNode, true, true),
1540 m = parentMatrix.clone().multiply(getGlobalMatrix(toElement)),
1541 fromPoint = _originToPoint(fromElement, fromOrigin, parentMatrix),
1542 _originToPoint2 = _originToPoint(toElement, toOrigin, parentMatrix),
1543 x = _originToPoint2.x,
1544 y = _originToPoint2.y,
1545 p;
1546
1547 m.e = m.f = 0;
1548
1549 if (toOrigin === "auto" && toElement.getTotalLength && toElement.tagName.toLowerCase() === "path") {
1550 p = toElement.getAttribute("d").match(_numExp) || [];
1551 p = m.apply({
1552 x: +p[0],
1553 y: +p[1]
1554 });
1555 x += p.x;
1556 y += p.y;
1557 }
1558
1559 if (p || toElement.getBBox && fromElement.getBBox && toElement.ownerSVGElement === fromElement.ownerSVGElement) {
1560 p = m.apply(toElement.getBBox());
1561 x -= p.x;
1562 y -= p.y;
1563 }
1564
1565 m.e = x - fromPoint.x;
1566 m.f = y - fromPoint.y;
1567 return m;
1568 },
1569 _align = function _align(rawPath, target, _ref) {
1570 var align = _ref.align,
1571 matrix = _ref.matrix,
1572 offsetX = _ref.offsetX,
1573 offsetY = _ref.offsetY,
1574 alignOrigin = _ref.alignOrigin;
1575
1576 var x = rawPath[0][0],
1577 y = rawPath[0][1],
1578 curX = _getPropNum(target, "x"),
1579 curY = _getPropNum(target, "y"),
1580 alignTarget,
1581 m,
1582 p;
1583
1584 if (!rawPath || !rawPath.length) {
1585 return getRawPath("M0,0L0,0");
1586 }
1587
1588 if (align) {
1589 if (align === "self" || (alignTarget = _toArray(align)[0] || target) === target) {
1590 transformRawPath(rawPath, 1, 0, 0, 1, curX - x, curY - y);
1591 } else {
1592 if (alignOrigin && alignOrigin[2] !== false) {
1593 gsap.set(target, {
1594 transformOrigin: alignOrigin[0] * 100 + "% " + alignOrigin[1] * 100 + "%"
1595 });
1596 } else {
1597 alignOrigin = [_getPropNum(target, "xPercent") / -100, _getPropNum(target, "yPercent") / -100];
1598 }
1599
1600 m = _getAlignMatrix(target, alignTarget, alignOrigin, "auto");
1601 p = m.apply({
1602 x: x,
1603 y: y
1604 });
1605 transformRawPath(rawPath, m.a, m.b, m.c, m.d, curX + m.e - (p.x - m.e), curY + m.f - (p.y - m.f));
1606 }
1607 }
1608
1609 if (matrix) {
1610 transformRawPath(rawPath, matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f);
1611 } else if (offsetX || offsetY) {
1612 transformRawPath(rawPath, 1, 0, 0, 1, offsetX || 0, offsetY || 0);
1613 }
1614
1615 return rawPath;
1616 },
1617 _addDimensionalPropTween = function _addDimensionalPropTween(plugin, target, property, rawPath, pathProperty, forceUnit) {
1618 var cache = target._gsap,
1619 harness = cache.harness,
1620 alias = harness && harness.aliases && harness.aliases[property],
1621 prop = alias && alias.indexOf(",") < 0 ? alias : property,
1622 pt = plugin._pt = new PropTween(plugin._pt, target, prop, 0, 0, _emptyFunc, 0, cache.set(target, prop, plugin));
1623 pt.u = _getUnit(cache.get(target, prop, forceUnit)) || 0;
1624 pt.path = rawPath;
1625 pt.pp = pathProperty;
1626
1627 plugin._props.push(prop);
1628 },
1629 _sliceModifier = function _sliceModifier(start, end) {
1630 return function (rawPath) {
1631 return start || end !== 1 ? sliceRawPath(rawPath, start, end) : rawPath;
1632 };
1633 };
1634
1635 var MotionPathPlugin = {
1636 version: "3.5.1",
1637 name: "motionPath",
1638 register: function register(core, Plugin, propTween) {
1639 gsap = core;
1640 _getUnit = gsap.utils.getUnit;
1641 _toArray = gsap.utils.toArray;
1642 PropTween = propTween;
1643 },
1644 init: function init(target, vars) {
1645 if (!gsap) {
1646 console.warn("Please gsap.registerPlugin(MotionPathPlugin)");
1647 return false;
1648 }
1649
1650 if (!(typeof vars === "object" && !vars.style) || !vars.path) {
1651 vars = {
1652 path: vars
1653 };
1654 }
1655
1656 var rawPaths = [],
1657 path = vars.path,
1658 firstObj = path[0],
1659 autoRotate = vars.autoRotate,
1660 slicer = _sliceModifier(vars.start, "end" in vars ? vars.end : 1),
1661 rawPath,
1662 p,
1663 x,
1664 y;
1665
1666 this.rawPaths = rawPaths;
1667 this.target = target;
1668
1669 if (this.rotate = autoRotate || autoRotate === 0) {
1670 this.rOffset = parseFloat(autoRotate) || 0;
1671 this.radians = !!vars.useRadians;
1672 this.rProp = vars.rotation || "rotation";
1673 this.rSet = target._gsap.set(target, this.rProp, this);
1674 this.ru = _getUnit(target._gsap.get(target, this.rProp)) || 0;
1675 }
1676
1677 if (Array.isArray(path) && !("closed" in path) && typeof firstObj !== "number") {
1678 for (p in firstObj) {
1679 if (~_xProps.indexOf(p)) {
1680 x = p;
1681 } else if (~_yProps.indexOf(p)) {
1682 y = p;
1683 }
1684 }
1685
1686 if (x && y) {
1687 rawPaths.push(_segmentToRawPath(this, _populateSegmentFromArray(_populateSegmentFromArray([], path, x, 0), path, y, 1), target, vars.x || x, vars.y || y, slicer, vars));
1688 } else {
1689 x = y = 0;
1690 }
1691
1692 for (p in firstObj) {
1693 p !== x && p !== y && rawPaths.push(_segmentToRawPath(this, _populateSegmentFromArray([], path, p, 2), target, p, 0, slicer, vars));
1694 }
1695 } else {
1696 rawPath = slicer(_align(getRawPath(vars.path), target, vars));
1697 cacheRawPathMeasurements(rawPath, vars.resolution);
1698 rawPaths.push(rawPath);
1699
1700 _addDimensionalPropTween(this, target, vars.x || "x", rawPath, "x", vars.unitX || "px");
1701
1702 _addDimensionalPropTween(this, target, vars.y || "y", rawPath, "y", vars.unitY || "px");
1703 }
1704 },
1705 render: function render(ratio, data) {
1706 var rawPaths = data.rawPaths,
1707 i = rawPaths.length,
1708 pt = data._pt;
1709
1710 if (ratio > 1) {
1711 ratio = 1;
1712 } else if (ratio < 0) {
1713 ratio = 0;
1714 }
1715
1716 while (i--) {
1717 getPositionOnPath(rawPaths[i], ratio, !i && data.rotate, rawPaths[i]);
1718 }
1719
1720 while (pt) {
1721 pt.set(pt.t, pt.p, pt.path[pt.pp] + pt.u, pt.d, ratio);
1722 pt = pt._next;
1723 }
1724
1725 data.rotate && data.rSet(data.target, data.rProp, rawPaths[0].angle * (data.radians ? _DEG2RAD$1 : 1) + data.rOffset + data.ru, data, ratio);
1726 },
1727 getLength: function getLength(path) {
1728 return cacheRawPathMeasurements(getRawPath(path)).totalLength;
1729 },
1730 sliceRawPath: sliceRawPath,
1731 getRawPath: getRawPath,
1732 pointsToSegment: pointsToSegment,
1733 stringToRawPath: stringToRawPath,
1734 rawPathToString: rawPathToString,
1735 transformRawPath: transformRawPath,
1736 getGlobalMatrix: getGlobalMatrix,
1737 getPositionOnPath: getPositionOnPath,
1738 cacheRawPathMeasurements: cacheRawPathMeasurements,
1739 convertToPath: function convertToPath$1(targets, swap) {
1740 return _toArray(targets).map(function (target) {
1741 return convertToPath(target, swap !== false);
1742 });
1743 },
1744 convertCoordinates: function convertCoordinates(fromElement, toElement, point) {
1745 var m = getGlobalMatrix(toElement, true, true).multiply(getGlobalMatrix(fromElement));
1746 return point ? m.apply(point) : m;
1747 },
1748 getAlignMatrix: _getAlignMatrix,
1749 getRelativePosition: function getRelativePosition(fromElement, toElement, fromOrigin, toOrigin) {
1750 var m = _getAlignMatrix(fromElement, toElement, fromOrigin, toOrigin);
1751
1752 return {
1753 x: m.e,
1754 y: m.f
1755 };
1756 },
1757 arrayToRawPath: function arrayToRawPath(value, vars) {
1758 vars = vars || {};
1759
1760 var segment = _populateSegmentFromArray(_populateSegmentFromArray([], value, vars.x || "x", 0), value, vars.y || "y", 1);
1761
1762 vars.relative && _relativize(segment);
1763 return [vars.type === "cubic" ? segment : pointsToSegment(segment, vars.curviness)];
1764 }
1765 };
1766 _getGSAP() && gsap.registerPlugin(MotionPathPlugin);
1767
1768 exports.MotionPathPlugin = MotionPathPlugin;
1769 exports.default = MotionPathPlugin;
1770
1771 Object.defineProperty(exports, '__esModule', { value: true });
1772
1773})));