UNPKG

12.1 kBJavaScriptView Raw
1/*!
2 * MotionPathPlugin 3.10.3
3 * https://greensock.com
4 *
5 * @license Copyright 2008-2022, GreenSock. All rights reserved.
6 * Subject to the terms at https://greensock.com/standard-license or for
7 * Club GreenSock members, the agreement issued with that membership.
8 * @author: Jack Doyle, jack@greensock.com
9*/
10
11/* eslint-disable */
12import { getRawPath, cacheRawPathMeasurements, getPositionOnPath, pointsToSegment, flatPointsToSegment, sliceRawPath, stringToRawPath, rawPathToString, transformRawPath, convertToPath as _convertToPath } from "./utils/paths.js";
13import { getGlobalMatrix } from "./utils/matrix.js";
14
15var _xProps = "x,translateX,left,marginLeft,xPercent".split(","),
16 _yProps = "y,translateY,top,marginTop,yPercent".split(","),
17 _DEG2RAD = Math.PI / 180,
18 gsap,
19 PropTween,
20 _getUnit,
21 _toArray,
22 _getGSAP = function _getGSAP() {
23 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap;
24},
25 _populateSegmentFromArray = function _populateSegmentFromArray(segment, values, property, mode) {
26 //mode: 0 = x but don't fill y yet, 1 = y, 2 = x and fill y with 0.
27 var l = values.length,
28 si = mode === 2 ? 0 : mode,
29 i = 0,
30 v;
31
32 for (; i < l; i++) {
33 segment[si] = v = parseFloat(values[i][property]);
34 mode === 2 && (segment[si + 1] = 0);
35 si += 2;
36 }
37
38 return segment;
39},
40 _getPropNum = function _getPropNum(target, prop, unit) {
41 return parseFloat(target._gsap.get(target, prop, unit || "px")) || 0;
42},
43 _relativize = function _relativize(segment) {
44 var x = segment[0],
45 y = segment[1],
46 i;
47
48 for (i = 2; i < segment.length; i += 2) {
49 x = segment[i] += x;
50 y = segment[i + 1] += y;
51 }
52},
53 // feed in an array of quadratic bezier points like [{x: 0, y: 0}, ...] and it'll convert it to cubic bezier
54// _quadToCubic = points => {
55// let cubic = [],
56// l = points.length - 1,
57// i = 1,
58// a, b, c;
59// for (; i < l; i+=2) {
60// a = points[i-1];
61// b = points[i];
62// c = points[i+1];
63// cubic.push(a, {x: (2 * b.x + a.x) / 3, y: (2 * b.y + a.y) / 3}, {x: (2 * b.x + c.x) / 3, y: (2 * b.y + c.y) / 3});
64// }
65// cubic.push(points[l]);
66// return cubic;
67// },
68_segmentToRawPath = function _segmentToRawPath(plugin, segment, target, x, y, slicer, vars, unitX, unitY) {
69 if (vars.type === "cubic") {
70 segment = [segment];
71 } else {
72 vars.fromCurrent !== false && segment.unshift(_getPropNum(target, x, unitX), y ? _getPropNum(target, y, unitY) : 0);
73 vars.relative && _relativize(segment);
74 var pointFunc = y ? pointsToSegment : flatPointsToSegment;
75 segment = [pointFunc(segment, vars.curviness)];
76 }
77
78 segment = slicer(_align(segment, target, vars));
79
80 _addDimensionalPropTween(plugin, target, x, segment, "x", unitX);
81
82 y && _addDimensionalPropTween(plugin, target, y, segment, "y", unitY);
83 return cacheRawPathMeasurements(segment, vars.resolution || (vars.curviness === 0 ? 20 : 12)); //when curviness is 0, it creates control points right on top of the anchors which makes it more sensitive to resolution, thus we change the default accordingly.
84},
85 _emptyFunc = function _emptyFunc(v) {
86 return v;
87},
88 _numExp = /[-+\.]*\d+\.?(?:e-|e\+)?\d*/g,
89 _originToPoint = function _originToPoint(element, origin, parentMatrix) {
90 // origin is an array of normalized values (0-1) in relation to the width/height, so [0.5, 0.5] would be the center. It can also be "auto" in which case it will be the top left unless it's a <path>, when it will start at the beginning of the path itself.
91 var m = getGlobalMatrix(element),
92 x = 0,
93 y = 0,
94 svg;
95
96 if ((element.tagName + "").toLowerCase() === "svg") {
97 svg = element.viewBox.baseVal;
98 svg.width || (svg = {
99 width: +element.getAttribute("width"),
100 height: +element.getAttribute("height")
101 });
102 } else {
103 svg = origin && element.getBBox && element.getBBox();
104 }
105
106 if (origin && origin !== "auto") {
107 x = origin.push ? origin[0] * (svg ? svg.width : element.offsetWidth || 0) : origin.x;
108 y = origin.push ? origin[1] * (svg ? svg.height : element.offsetHeight || 0) : origin.y;
109 }
110
111 return parentMatrix.apply(x || y ? m.apply({
112 x: x,
113 y: y
114 }) : {
115 x: m.e,
116 y: m.f
117 });
118},
119 _getAlignMatrix = function _getAlignMatrix(fromElement, toElement, fromOrigin, toOrigin) {
120 var parentMatrix = getGlobalMatrix(fromElement.parentNode, true, true),
121 m = parentMatrix.clone().multiply(getGlobalMatrix(toElement)),
122 fromPoint = _originToPoint(fromElement, fromOrigin, parentMatrix),
123 _originToPoint2 = _originToPoint(toElement, toOrigin, parentMatrix),
124 x = _originToPoint2.x,
125 y = _originToPoint2.y,
126 p;
127
128 m.e = m.f = 0;
129
130 if (toOrigin === "auto" && toElement.getTotalLength && toElement.tagName.toLowerCase() === "path") {
131 p = toElement.getAttribute("d").match(_numExp) || [];
132 p = m.apply({
133 x: +p[0],
134 y: +p[1]
135 });
136 x += p.x;
137 y += p.y;
138 }
139
140 if (p || toElement.getBBox && fromElement.getBBox && toElement.ownerSVGElement === fromElement.ownerSVGElement) {
141 p = m.apply(toElement.getBBox());
142 x -= p.x;
143 y -= p.y;
144 }
145
146 m.e = x - fromPoint.x;
147 m.f = y - fromPoint.y;
148 return m;
149},
150 _align = function _align(rawPath, target, _ref) {
151 var align = _ref.align,
152 matrix = _ref.matrix,
153 offsetX = _ref.offsetX,
154 offsetY = _ref.offsetY,
155 alignOrigin = _ref.alignOrigin;
156
157 var x = rawPath[0][0],
158 y = rawPath[0][1],
159 curX = _getPropNum(target, "x"),
160 curY = _getPropNum(target, "y"),
161 alignTarget,
162 m,
163 p;
164
165 if (!rawPath || !rawPath.length) {
166 return getRawPath("M0,0L0,0");
167 }
168
169 if (align) {
170 if (align === "self" || (alignTarget = _toArray(align)[0] || target) === target) {
171 transformRawPath(rawPath, 1, 0, 0, 1, curX - x, curY - y);
172 } else {
173 if (alignOrigin && alignOrigin[2] !== false) {
174 gsap.set(target, {
175 transformOrigin: alignOrigin[0] * 100 + "% " + alignOrigin[1] * 100 + "%"
176 });
177 } else {
178 alignOrigin = [_getPropNum(target, "xPercent") / -100, _getPropNum(target, "yPercent") / -100];
179 }
180
181 m = _getAlignMatrix(target, alignTarget, alignOrigin, "auto");
182 p = m.apply({
183 x: x,
184 y: y
185 });
186 transformRawPath(rawPath, m.a, m.b, m.c, m.d, curX + m.e - (p.x - m.e), curY + m.f - (p.y - m.f));
187 }
188 }
189
190 if (matrix) {
191 transformRawPath(rawPath, matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f);
192 } else if (offsetX || offsetY) {
193 transformRawPath(rawPath, 1, 0, 0, 1, offsetX || 0, offsetY || 0);
194 }
195
196 return rawPath;
197},
198 _addDimensionalPropTween = function _addDimensionalPropTween(plugin, target, property, rawPath, pathProperty, forceUnit) {
199 var cache = target._gsap,
200 harness = cache.harness,
201 alias = harness && harness.aliases && harness.aliases[property],
202 prop = alias && alias.indexOf(",") < 0 ? alias : property,
203 pt = plugin._pt = new PropTween(plugin._pt, target, prop, 0, 0, _emptyFunc, 0, cache.set(target, prop, plugin));
204 pt.u = _getUnit(cache.get(target, prop, forceUnit)) || 0;
205 pt.path = rawPath;
206 pt.pp = pathProperty;
207
208 plugin._props.push(prop);
209},
210 _sliceModifier = function _sliceModifier(start, end) {
211 return function (rawPath) {
212 return start || end !== 1 ? sliceRawPath(rawPath, start, end) : rawPath;
213 };
214};
215
216export var MotionPathPlugin = {
217 version: "3.10.3",
218 name: "motionPath",
219 register: function register(core, Plugin, propTween) {
220 gsap = core;
221 _getUnit = gsap.utils.getUnit;
222 _toArray = gsap.utils.toArray;
223 PropTween = propTween;
224 },
225 init: function init(target, vars) {
226 if (!gsap) {
227 console.warn("Please gsap.registerPlugin(MotionPathPlugin)");
228 return false;
229 }
230
231 if (!(typeof vars === "object" && !vars.style) || !vars.path) {
232 vars = {
233 path: vars
234 };
235 }
236
237 var rawPaths = [],
238 _vars = vars,
239 path = _vars.path,
240 autoRotate = _vars.autoRotate,
241 unitX = _vars.unitX,
242 unitY = _vars.unitY,
243 x = _vars.x,
244 y = _vars.y,
245 firstObj = path[0],
246 slicer = _sliceModifier(vars.start, "end" in vars ? vars.end : 1),
247 rawPath,
248 p;
249
250 this.rawPaths = rawPaths;
251 this.target = target;
252
253 if (this.rotate = autoRotate || autoRotate === 0) {
254 //get the rotational data FIRST so that the setTransform() method is called in the correct order in the render() loop - rotation gets set last.
255 this.rOffset = parseFloat(autoRotate) || 0;
256 this.radians = !!vars.useRadians;
257 this.rProp = vars.rotation || "rotation"; // rotation property
258
259 this.rSet = target._gsap.set(target, this.rProp, this); // rotation setter
260
261 this.ru = _getUnit(target._gsap.get(target, this.rProp)) || 0; // rotation units
262 }
263
264 if (Array.isArray(path) && !("closed" in path) && typeof firstObj !== "number") {
265 for (p in firstObj) {
266 if (!x && ~_xProps.indexOf(p)) {
267 x = p;
268 } else if (!y && ~_yProps.indexOf(p)) {
269 y = p;
270 }
271 }
272
273 if (x && y) {
274 //correlated values
275 rawPaths.push(_segmentToRawPath(this, _populateSegmentFromArray(_populateSegmentFromArray([], path, x, 0), path, y, 1), target, x, y, slicer, vars, unitX || _getUnit(path[0][x]), unitY || _getUnit(path[0][y])));
276 } else {
277 x = y = 0;
278 }
279
280 for (p in firstObj) {
281 p !== x && p !== y && rawPaths.push(_segmentToRawPath(this, _populateSegmentFromArray([], path, p, 2), target, p, 0, slicer, vars, _getUnit(path[0][p])));
282 }
283 } else {
284 rawPath = slicer(_align(getRawPath(vars.path), target, vars));
285 cacheRawPathMeasurements(rawPath, vars.resolution);
286 rawPaths.push(rawPath);
287
288 _addDimensionalPropTween(this, target, vars.x || "x", rawPath, "x", vars.unitX || "px");
289
290 _addDimensionalPropTween(this, target, vars.y || "y", rawPath, "y", vars.unitY || "px");
291 }
292 },
293 render: function render(ratio, data) {
294 var rawPaths = data.rawPaths,
295 i = rawPaths.length,
296 pt = data._pt;
297
298 if (ratio > 1) {
299 ratio = 1;
300 } else if (ratio < 0) {
301 ratio = 0;
302 }
303
304 while (i--) {
305 getPositionOnPath(rawPaths[i], ratio, !i && data.rotate, rawPaths[i]);
306 }
307
308 while (pt) {
309 pt.set(pt.t, pt.p, pt.path[pt.pp] + pt.u, pt.d, ratio);
310 pt = pt._next;
311 }
312
313 data.rotate && data.rSet(data.target, data.rProp, rawPaths[0].angle * (data.radians ? _DEG2RAD : 1) + data.rOffset + data.ru, data, ratio);
314 },
315 getLength: function getLength(path) {
316 return cacheRawPathMeasurements(getRawPath(path)).totalLength;
317 },
318 sliceRawPath: sliceRawPath,
319 getRawPath: getRawPath,
320 pointsToSegment: pointsToSegment,
321 stringToRawPath: stringToRawPath,
322 rawPathToString: rawPathToString,
323 transformRawPath: transformRawPath,
324 getGlobalMatrix: getGlobalMatrix,
325 getPositionOnPath: getPositionOnPath,
326 cacheRawPathMeasurements: cacheRawPathMeasurements,
327 convertToPath: function convertToPath(targets, swap) {
328 return _toArray(targets).map(function (target) {
329 return _convertToPath(target, swap !== false);
330 });
331 },
332 convertCoordinates: function convertCoordinates(fromElement, toElement, point) {
333 var m = getGlobalMatrix(toElement, true, true).multiply(getGlobalMatrix(fromElement));
334 return point ? m.apply(point) : m;
335 },
336 getAlignMatrix: _getAlignMatrix,
337 getRelativePosition: function getRelativePosition(fromElement, toElement, fromOrigin, toOrigin) {
338 var m = _getAlignMatrix(fromElement, toElement, fromOrigin, toOrigin);
339
340 return {
341 x: m.e,
342 y: m.f
343 };
344 },
345 arrayToRawPath: function arrayToRawPath(value, vars) {
346 vars = vars || {};
347
348 var segment = _populateSegmentFromArray(_populateSegmentFromArray([], value, vars.x || "x", 0), value, vars.y || "y", 1);
349
350 vars.relative && _relativize(segment);
351 return [vars.type === "cubic" ? segment : pointsToSegment(segment, vars.curviness)];
352 }
353};
354_getGSAP() && gsap.registerPlugin(MotionPathPlugin);
355export { MotionPathPlugin as default };
\No newline at end of file