@remotion/paths 4.0.45 → 4.0.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  import type { BoundingBox, ReducedInstruction } from './helpers/types';
2
+ export declare const getBoundingBoxFromInstructions: (instructions: ReducedInstruction[]) => BoundingBox;
2
3
  /**
3
4
  * @description Returns the bounding box of the given path, suitable for calculating the viewBox value that you need to pass to an SVG.
4
5
  * @param {string} d
5
6
  * @see [Documentation](https://www.remotion.dev/docs/paths/get-bounding-box)
6
7
  */
7
8
  export declare const getBoundingBox: (d: string) => BoundingBox;
8
- export declare const getBoundingBoxFromInstructions: (instructions: ReducedInstruction[]) => BoundingBox;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getBoundingBoxFromInstructions = exports.getBoundingBox = void 0;
3
+ exports.getBoundingBox = exports.getBoundingBoxFromInstructions = void 0;
4
4
  const remove_a_s_t_curves_1 = require("./helpers/remove-a-s-t-curves");
5
5
  const normalize_path_1 = require("./normalize-path");
6
6
  const parse_path_1 = require("./parse-path");
@@ -67,17 +67,6 @@ function minmaxC(A) {
67
67
  }
68
68
  return [min, max];
69
69
  }
70
- /**
71
- * @description Returns the bounding box of the given path, suitable for calculating the viewBox value that you need to pass to an SVG.
72
- * @param {string} d
73
- * @see [Documentation](https://www.remotion.dev/docs/paths/get-bounding-box)
74
- */
75
- const getBoundingBox = (d) => {
76
- const parsed = (0, parse_path_1.parsePath)(d);
77
- const unarced = (0, remove_a_s_t_curves_1.removeATSHVInstructions)((0, normalize_path_1.normalizeInstructions)(parsed));
78
- return (0, exports.getBoundingBoxFromInstructions)(unarced);
79
- };
80
- exports.getBoundingBox = getBoundingBox;
81
70
  const getBoundingBoxFromInstructions = (instructions) => {
82
71
  let minX = Infinity;
83
72
  let minY = Infinity;
@@ -183,3 +172,14 @@ const getBoundingBoxFromInstructions = (instructions) => {
183
172
  };
184
173
  };
185
174
  exports.getBoundingBoxFromInstructions = getBoundingBoxFromInstructions;
175
+ /**
176
+ * @description Returns the bounding box of the given path, suitable for calculating the viewBox value that you need to pass to an SVG.
177
+ * @param {string} d
178
+ * @see [Documentation](https://www.remotion.dev/docs/paths/get-bounding-box)
179
+ */
180
+ const getBoundingBox = (d) => {
181
+ const parsed = (0, parse_path_1.parsePath)(d);
182
+ const unarced = (0, remove_a_s_t_curves_1.removeATSHVInstructions)((0, normalize_path_1.normalizeInstructions)(parsed));
183
+ return (0, exports.getBoundingBoxFromInstructions)(unarced);
184
+ };
185
+ exports.getBoundingBox = getBoundingBox;
@@ -2,79 +2,25 @@
2
2
  // Copied from: https://github.com/rveciana/svg-path-properties
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.makeArc = void 0;
5
- const makeArc = ({ x0, y0, rx, ry, xAxisRotate, LargeArcFlag, SweepFlag, x1, y1, }) => {
6
- const lengthProperties = approximateArcLengthOfCurve(300, (t) => {
7
- return pointOnEllipticalArc({
8
- p0: { x: x0, y: y0 },
9
- rx,
10
- ry,
11
- xAxisRotation: xAxisRotate,
12
- largeArcFlag: LargeArcFlag,
13
- sweepFlag: SweepFlag,
14
- p1: { x: x1, y: y1 },
15
- t,
16
- });
17
- });
18
- const length = lengthProperties.arcLength;
19
- const getTotalLength = () => {
20
- return length;
21
- };
22
- const getPointAtLength = (fractionLength) => {
23
- if (fractionLength < 0) {
24
- fractionLength = 0;
25
- }
26
- else if (fractionLength > length) {
27
- fractionLength = length;
28
- }
29
- const position = pointOnEllipticalArc({
30
- p0: { x: x0, y: y0 },
31
- rx,
32
- ry,
33
- xAxisRotation: xAxisRotate,
34
- largeArcFlag: LargeArcFlag,
35
- sweepFlag: SweepFlag,
36
- p1: { x: x1, y: y1 },
37
- t: fractionLength / length,
38
- });
39
- return { x: position.x, y: position.y };
40
- };
41
- const getTangentAtLength = (fractionLength) => {
42
- if (fractionLength < 0) {
43
- fractionLength = 0;
44
- }
45
- else if (fractionLength > length) {
46
- fractionLength = length;
47
- }
48
- const point_dist = 0.05; // needs testing
49
- const p1 = getPointAtLength(fractionLength);
50
- let p2;
51
- if (fractionLength < 0) {
52
- fractionLength = 0;
53
- }
54
- else if (fractionLength > length) {
55
- fractionLength = length;
56
- }
57
- if (fractionLength < length - point_dist) {
58
- p2 = getPointAtLength(fractionLength + point_dist);
59
- }
60
- else {
61
- p2 = getPointAtLength(fractionLength - point_dist);
62
- }
63
- const xDist = p2.x - p1.x;
64
- const yDist = p2.y - p1.y;
65
- const dist = Math.sqrt(xDist * xDist + yDist * yDist);
66
- if (fractionLength < length - point_dist) {
67
- return { x: -xDist / dist, y: -yDist / dist };
68
- }
69
- return { x: xDist / dist, y: yDist / dist };
70
- };
71
- return {
72
- getPointAtLength,
73
- getTangentAtLength,
74
- getTotalLength,
75
- };
5
+ const mod = (x, m) => {
6
+ return ((x % m) + m) % m;
7
+ };
8
+ const toRadians = (angle) => {
9
+ return angle * (Math.PI / 180);
10
+ };
11
+ const distance = (p0, p1) => {
12
+ return Math.sqrt((p1.x - p0.x) ** 2 + (p1.y - p0.y) ** 2);
13
+ };
14
+ const clamp = (val, min, max) => {
15
+ return Math.min(Math.max(val, min), max);
16
+ };
17
+ const angleBetween = (v0, v1) => {
18
+ const p = v0.x * v1.x + v0.y * v1.y;
19
+ const n = Math.sqrt((v0.x ** 2 + v0.y ** 2) * (v1.x ** 2 + v1.y ** 2));
20
+ const sign = v0.x * v1.y - v0.y * v1.x < 0 ? -1 : 1;
21
+ const angle = sign * Math.acos(p / n);
22
+ return angle;
76
23
  };
77
- exports.makeArc = makeArc;
78
24
  const pointOnEllipticalArc = ({ p0, rx, ry, xAxisRotation, largeArcFlag, sweepFlag, p1, t, }) => {
79
25
  // In accordance to: http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters
80
26
  rx = Math.abs(rx);
@@ -205,22 +151,76 @@ const approximateArcLengthOfCurve = (resolution, pointOnCurveFunc) => {
205
151
  approximationLines,
206
152
  };
207
153
  };
208
- const mod = (x, m) => {
209
- return ((x % m) + m) % m;
210
- };
211
- const toRadians = (angle) => {
212
- return angle * (Math.PI / 180);
213
- };
214
- const distance = (p0, p1) => {
215
- return Math.sqrt((p1.x - p0.x) ** 2 + (p1.y - p0.y) ** 2);
216
- };
217
- const clamp = (val, min, max) => {
218
- return Math.min(Math.max(val, min), max);
219
- };
220
- const angleBetween = (v0, v1) => {
221
- const p = v0.x * v1.x + v0.y * v1.y;
222
- const n = Math.sqrt((v0.x ** 2 + v0.y ** 2) * (v1.x ** 2 + v1.y ** 2));
223
- const sign = v0.x * v1.y - v0.y * v1.x < 0 ? -1 : 1;
224
- const angle = sign * Math.acos(p / n);
225
- return angle;
154
+ const makeArc = ({ x0, y0, rx, ry, xAxisRotate, LargeArcFlag, SweepFlag, x1, y1, }) => {
155
+ const lengthProperties = approximateArcLengthOfCurve(300, (t) => {
156
+ return pointOnEllipticalArc({
157
+ p0: { x: x0, y: y0 },
158
+ rx,
159
+ ry,
160
+ xAxisRotation: xAxisRotate,
161
+ largeArcFlag: LargeArcFlag,
162
+ sweepFlag: SweepFlag,
163
+ p1: { x: x1, y: y1 },
164
+ t,
165
+ });
166
+ });
167
+ const length = lengthProperties.arcLength;
168
+ const getTotalLength = () => {
169
+ return length;
170
+ };
171
+ const getPointAtLength = (fractionLength) => {
172
+ if (fractionLength < 0) {
173
+ fractionLength = 0;
174
+ }
175
+ else if (fractionLength > length) {
176
+ fractionLength = length;
177
+ }
178
+ const position = pointOnEllipticalArc({
179
+ p0: { x: x0, y: y0 },
180
+ rx,
181
+ ry,
182
+ xAxisRotation: xAxisRotate,
183
+ largeArcFlag: LargeArcFlag,
184
+ sweepFlag: SweepFlag,
185
+ p1: { x: x1, y: y1 },
186
+ t: fractionLength / length,
187
+ });
188
+ return { x: position.x, y: position.y };
189
+ };
190
+ const getTangentAtLength = (fractionLength) => {
191
+ if (fractionLength < 0) {
192
+ fractionLength = 0;
193
+ }
194
+ else if (fractionLength > length) {
195
+ fractionLength = length;
196
+ }
197
+ const point_dist = 0.05; // needs testing
198
+ const p1 = getPointAtLength(fractionLength);
199
+ let p2;
200
+ if (fractionLength < 0) {
201
+ fractionLength = 0;
202
+ }
203
+ else if (fractionLength > length) {
204
+ fractionLength = length;
205
+ }
206
+ if (fractionLength < length - point_dist) {
207
+ p2 = getPointAtLength(fractionLength + point_dist);
208
+ }
209
+ else {
210
+ p2 = getPointAtLength(fractionLength - point_dist);
211
+ }
212
+ const xDist = p2.x - p1.x;
213
+ const yDist = p2.y - p1.y;
214
+ const dist = Math.sqrt(xDist * xDist + yDist * yDist);
215
+ if (fractionLength < length - point_dist) {
216
+ return { x: -xDist / dist, y: -yDist / dist };
217
+ }
218
+ return { x: xDist / dist, y: yDist / dist };
219
+ };
220
+ return {
221
+ getPointAtLength,
222
+ getTangentAtLength,
223
+ getTotalLength,
224
+ };
226
225
  };
226
+ exports.makeArc = makeArc;
@@ -1,8 +1,8 @@
1
1
  import type { Point } from './types';
2
2
  export declare const cubicPoint: (xs: number[], ys: number[], t: number) => Point;
3
- export declare const cubicDerivative: (xs: number[], ys: number[], t: number) => Point;
4
3
  export declare const getCubicArcLength: (xs: number[], ys: number[], t: number) => number;
5
4
  export declare const quadraticPoint: (xs: number[], ys: number[], t: number) => Point;
5
+ export declare const cubicDerivative: (xs: number[], ys: number[], t: number) => Point;
6
6
  export declare const getQuadraticArcLength: (xs: number[], ys: number[], t: number) => number;
7
7
  export declare const quadraticDerivative: (xs: number[], ys: number[], t: number) => {
8
8
  x: number;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.t2length = exports.quadraticDerivative = exports.getQuadraticArcLength = exports.quadraticPoint = exports.getCubicArcLength = exports.cubicDerivative = exports.cubicPoint = void 0;
3
+ exports.t2length = exports.quadraticDerivative = exports.getQuadraticArcLength = exports.cubicDerivative = exports.quadraticPoint = exports.getCubicArcLength = exports.cubicPoint = void 0;
4
4
  const bezier_values_1 = require("./bezier-values");
5
5
  const cubicPoint = (xs, ys, t) => {
6
6
  const x = (1 - t) * (1 - t) * (1 - t) * xs[0] +
@@ -14,11 +14,38 @@ const cubicPoint = (xs, ys, t) => {
14
14
  return { x, y };
15
15
  };
16
16
  exports.cubicPoint = cubicPoint;
17
- const cubicDerivative = (xs, ys, t) => {
18
- const derivative = (0, exports.quadraticPoint)([3 * (xs[1] - xs[0]), 3 * (xs[2] - xs[1]), 3 * (xs[3] - xs[2])], [3 * (ys[1] - ys[0]), 3 * (ys[2] - ys[1]), 3 * (ys[3] - ys[2])], t);
19
- return derivative;
17
+ /**
18
+ * Compute the curve derivative (hodograph) at t.
19
+ */
20
+ const getDerivative = (derivative, t, vs) => {
21
+ // the derivative of any 't'-less function is zero.
22
+ const n = vs.length - 1;
23
+ let value;
24
+ if (n === 0) {
25
+ return 0;
26
+ }
27
+ // direct values? compute!
28
+ if (derivative === 0) {
29
+ value = 0;
30
+ for (let k = 0; k <= n; k++) {
31
+ value += bezier_values_1.binomialCoefficients[n][k] * (1 - t) ** (n - k) * t ** k * vs[k];
32
+ }
33
+ return value;
34
+ }
35
+ // Still some derivative? go down one order, then try
36
+ // for the lower order curve's.
37
+ const _vs = new Array(n);
38
+ for (let k = 0; k < n; k++) {
39
+ _vs[k] = n * (vs[k + 1] - vs[k]);
40
+ }
41
+ return getDerivative(derivative - 1, t, _vs);
20
42
  };
21
- exports.cubicDerivative = cubicDerivative;
43
+ function bFunc(xs, ys, t) {
44
+ const xbase = getDerivative(1, t, xs);
45
+ const ybase = getDerivative(1, t, ys);
46
+ const combined = xbase * xbase + ybase * ybase;
47
+ return Math.sqrt(combined);
48
+ }
22
49
  const getCubicArcLength = (xs, ys, t) => {
23
50
  let correctedT;
24
51
  const n = 20;
@@ -37,6 +64,11 @@ const quadraticPoint = (xs, ys, t) => {
37
64
  return { x, y };
38
65
  };
39
66
  exports.quadraticPoint = quadraticPoint;
67
+ const cubicDerivative = (xs, ys, t) => {
68
+ const derivative = (0, exports.quadraticPoint)([3 * (xs[1] - xs[0]), 3 * (xs[2] - xs[1]), 3 * (xs[3] - xs[2])], [3 * (ys[1] - ys[0]), 3 * (ys[2] - ys[1]), 3 * (ys[3] - ys[2])], t);
69
+ return derivative;
70
+ };
71
+ exports.cubicDerivative = cubicDerivative;
40
72
  const getQuadraticArcLength = (xs, ys, t) => {
41
73
  if (t === undefined) {
42
74
  t = 1;
@@ -70,38 +102,6 @@ const quadraticDerivative = (xs, ys, t) => {
70
102
  };
71
103
  };
72
104
  exports.quadraticDerivative = quadraticDerivative;
73
- function bFunc(xs, ys, t) {
74
- const xbase = getDerivative(1, t, xs);
75
- const ybase = getDerivative(1, t, ys);
76
- const combined = xbase * xbase + ybase * ybase;
77
- return Math.sqrt(combined);
78
- }
79
- /**
80
- * Compute the curve derivative (hodograph) at t.
81
- */
82
- const getDerivative = (derivative, t, vs) => {
83
- // the derivative of any 't'-less function is zero.
84
- const n = vs.length - 1;
85
- let value;
86
- if (n === 0) {
87
- return 0;
88
- }
89
- // direct values? compute!
90
- if (derivative === 0) {
91
- value = 0;
92
- for (let k = 0; k <= n; k++) {
93
- value += bezier_values_1.binomialCoefficients[n][k] * (1 - t) ** (n - k) * t ** k * vs[k];
94
- }
95
- return value;
96
- }
97
- // Still some derivative? go down one order, then try
98
- // for the lower order curve's.
99
- const _vs = new Array(n);
100
- for (let k = 0; k < n; k++) {
101
- _vs[k] = n * (vs[k + 1] - vs[k]);
102
- }
103
- return getDerivative(derivative - 1, t, _vs);
104
- };
105
105
  const t2length = (length, totalLength, func) => {
106
106
  let error = 1;
107
107
  let t = length / totalLength;
@@ -20,6 +20,72 @@ function approximate_unit_arc(theta1, delta_theta) {
20
20
  y2,
21
21
  ];
22
22
  }
23
+ function unit_vector_angle(ux, uy, vx, vy) {
24
+ const sign = ux * vy - uy * vx < 0 ? -1 : 1;
25
+ let dot = ux * vx + uy * vy;
26
+ // Add this to work with arbitrary vectors:
27
+ // dot /= Math.sqrt(ux * ux + uy * uy) * Math.sqrt(vx * vx + vy * vy);
28
+ // rounding errors, e.g. -1.0000000000000002 can screw up this
29
+ if (dot > 1.0) {
30
+ dot = 1.0;
31
+ }
32
+ if (dot < -1.0) {
33
+ dot = -1.0;
34
+ }
35
+ return sign * Math.acos(dot);
36
+ }
37
+ function get_arc_center({ x1, y1, x2, y2, largeArcFlag, sweepFlag, rx, ry, sin_phi, cos_phi, }) {
38
+ // Step 1.
39
+ //
40
+ // Moving an ellipse so origin will be the middlepoint between our two
41
+ // points. After that, rotate it to line up ellipse axes with coordinate
42
+ // axes.
43
+ //
44
+ const x1p = (cos_phi * (x1 - x2)) / 2 + (sin_phi * (y1 - y2)) / 2;
45
+ const y1p = (-sin_phi * (x1 - x2)) / 2 + (cos_phi * (y1 - y2)) / 2;
46
+ const rx_sq = rx * rx;
47
+ const ry_sq = ry * ry;
48
+ const x1p_sq = x1p * x1p;
49
+ const y1p_sq = y1p * y1p;
50
+ // Step 2.
51
+ //
52
+ // Compute coordinates of the centre of this ellipse (cx', cy')
53
+ // in the new coordinate system.
54
+ //
55
+ let radicant = rx_sq * ry_sq - rx_sq * y1p_sq - ry_sq * x1p_sq;
56
+ if (radicant < 0) {
57
+ // due to rounding errors it might be e.g. -1.3877787807814457e-17
58
+ radicant = 0;
59
+ }
60
+ radicant /= rx_sq * y1p_sq + ry_sq * x1p_sq;
61
+ radicant = Math.sqrt(radicant) * (largeArcFlag === sweepFlag ? -1 : 1);
62
+ const cxp = ((radicant * rx) / ry) * y1p;
63
+ const cyp = ((radicant * -ry) / rx) * x1p;
64
+ // Step 3.
65
+ //
66
+ // Transform back to get centre coordinates (cx, cy) in the original
67
+ // coordinate system.
68
+ //
69
+ const cx = cos_phi * cxp - sin_phi * cyp + (x1 + x2) / 2;
70
+ const cy = sin_phi * cxp + cos_phi * cyp + (y1 + y2) / 2;
71
+ // Step 4.
72
+ //
73
+ // Compute angles (theta1, delta_theta).
74
+ //
75
+ const v1x = (x1p - cxp) / rx;
76
+ const v1y = (y1p - cyp) / ry;
77
+ const v2x = (-x1p - cxp) / rx;
78
+ const v2y = (-y1p - cyp) / ry;
79
+ const theta1 = unit_vector_angle(1, 0, v1x, v1y);
80
+ let delta_theta = unit_vector_angle(v1x, v1y, v2x, v2y);
81
+ if (sweepFlag === false && delta_theta > 0) {
82
+ delta_theta -= TAU;
83
+ }
84
+ if (sweepFlag === true && delta_theta < 0) {
85
+ delta_theta += TAU;
86
+ }
87
+ return [cx, cy, theta1, delta_theta];
88
+ }
23
89
  function arcToCircle({ x1, y1, x2, y2, largeArcFlag, sweepFlag, rx, ry, phi, }) {
24
90
  const sin_phi = Math.sin((phi * TAU) / 360);
25
91
  const cos_phi = Math.cos((phi * TAU) / 360);
@@ -203,69 +269,3 @@ const removeATSHVInstructions = (segments) => {
203
269
  });
204
270
  };
205
271
  exports.removeATSHVInstructions = removeATSHVInstructions;
206
- function get_arc_center({ x1, y1, x2, y2, largeArcFlag, sweepFlag, rx, ry, sin_phi, cos_phi, }) {
207
- // Step 1.
208
- //
209
- // Moving an ellipse so origin will be the middlepoint between our two
210
- // points. After that, rotate it to line up ellipse axes with coordinate
211
- // axes.
212
- //
213
- const x1p = (cos_phi * (x1 - x2)) / 2 + (sin_phi * (y1 - y2)) / 2;
214
- const y1p = (-sin_phi * (x1 - x2)) / 2 + (cos_phi * (y1 - y2)) / 2;
215
- const rx_sq = rx * rx;
216
- const ry_sq = ry * ry;
217
- const x1p_sq = x1p * x1p;
218
- const y1p_sq = y1p * y1p;
219
- // Step 2.
220
- //
221
- // Compute coordinates of the centre of this ellipse (cx', cy')
222
- // in the new coordinate system.
223
- //
224
- let radicant = rx_sq * ry_sq - rx_sq * y1p_sq - ry_sq * x1p_sq;
225
- if (radicant < 0) {
226
- // due to rounding errors it might be e.g. -1.3877787807814457e-17
227
- radicant = 0;
228
- }
229
- radicant /= rx_sq * y1p_sq + ry_sq * x1p_sq;
230
- radicant = Math.sqrt(radicant) * (largeArcFlag === sweepFlag ? -1 : 1);
231
- const cxp = ((radicant * rx) / ry) * y1p;
232
- const cyp = ((radicant * -ry) / rx) * x1p;
233
- // Step 3.
234
- //
235
- // Transform back to get centre coordinates (cx, cy) in the original
236
- // coordinate system.
237
- //
238
- const cx = cos_phi * cxp - sin_phi * cyp + (x1 + x2) / 2;
239
- const cy = sin_phi * cxp + cos_phi * cyp + (y1 + y2) / 2;
240
- // Step 4.
241
- //
242
- // Compute angles (theta1, delta_theta).
243
- //
244
- const v1x = (x1p - cxp) / rx;
245
- const v1y = (y1p - cyp) / ry;
246
- const v2x = (-x1p - cxp) / rx;
247
- const v2y = (-y1p - cyp) / ry;
248
- const theta1 = unit_vector_angle(1, 0, v1x, v1y);
249
- let delta_theta = unit_vector_angle(v1x, v1y, v2x, v2y);
250
- if (sweepFlag === false && delta_theta > 0) {
251
- delta_theta -= TAU;
252
- }
253
- if (sweepFlag === true && delta_theta < 0) {
254
- delta_theta += TAU;
255
- }
256
- return [cx, cy, theta1, delta_theta];
257
- }
258
- function unit_vector_angle(ux, uy, vx, vy) {
259
- const sign = ux * vy - uy * vx < 0 ? -1 : 1;
260
- let dot = ux * vx + uy * vy;
261
- // Add this to work with arbitrary vectors:
262
- // dot /= Math.sqrt(ux * ux + uy * uy) * Math.sqrt(vx * vx + vy * vy);
263
- // rounding errors, e.g. -1.0000000000000002 can screw up this
264
- if (dot > 1.0) {
265
- dot = 1.0;
266
- }
267
- if (dot < -1.0) {
268
- dot = -1.0;
269
- }
270
- return sign * Math.acos(dot);
271
- }
@@ -1,8 +1,8 @@
1
1
  import type { AbsoluteInstruction, Instruction } from './helpers/types';
2
+ export declare const normalizeInstructions: (instructions: Instruction[]) => AbsoluteInstruction[];
2
3
  /**
3
4
  * @description Removes all relative coordinates from an SVG path and converts them into absolute coordinates.
4
5
  * @param {string} path A valid SVG path
5
6
  * @see [Documentation](https://remotion.dev/docs/paths/normalize-path)
6
7
  */
7
8
  export declare const normalizePath: (path: string) => string;
8
- export declare const normalizeInstructions: (instructions: Instruction[]) => AbsoluteInstruction[];
@@ -1,19 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.normalizeInstructions = exports.normalizePath = void 0;
3
+ exports.normalizePath = exports.normalizeInstructions = void 0;
4
4
  const parse_path_1 = require("./parse-path");
5
5
  const serialize_instructions_1 = require("./serialize-instructions");
6
- /**
7
- * @description Removes all relative coordinates from an SVG path and converts them into absolute coordinates.
8
- * @param {string} path A valid SVG path
9
- * @see [Documentation](https://remotion.dev/docs/paths/normalize-path)
10
- */
11
- const normalizePath = (path) => {
12
- const instructions = (0, parse_path_1.parsePath)(path);
13
- const normalized = (0, exports.normalizeInstructions)(instructions);
14
- return (0, serialize_instructions_1.serializeInstructions)(normalized);
15
- };
16
- exports.normalizePath = normalizePath;
17
6
  const normalizeInstructions = (instructions) => {
18
7
  // Extended properties must already be normalized
19
8
  const normalized = [];
@@ -162,3 +151,14 @@ const normalizeInstructions = (instructions) => {
162
151
  return normalized;
163
152
  };
164
153
  exports.normalizeInstructions = normalizeInstructions;
154
+ /**
155
+ * @description Removes all relative coordinates from an SVG path and converts them into absolute coordinates.
156
+ * @param {string} path A valid SVG path
157
+ * @see [Documentation](https://remotion.dev/docs/paths/normalize-path)
158
+ */
159
+ const normalizePath = (path) => {
160
+ const instructions = (0, parse_path_1.parsePath)(path);
161
+ const normalized = (0, exports.normalizeInstructions)(instructions);
162
+ return (0, serialize_instructions_1.serializeInstructions)(normalized);
163
+ };
164
+ exports.normalizePath = normalizePath;
@@ -42,6 +42,20 @@ const makeInstructions = (arr, instruction, cb) => {
42
42
  };
43
43
  const segmentRegExp = /([astvzqmhlc])([^astvzqmhlc]*)/gi;
44
44
  const numberRegExp = /-?[0-9]*\.?[0-9]+(?:e[-+]?\d+)?/gi;
45
+ const parseValues = (args, instructionType) => {
46
+ const numbers = args.match(numberRegExp);
47
+ if (!numbers) {
48
+ if (instructionType === 'Z' || instructionType === 'z') {
49
+ return [];
50
+ }
51
+ throw new Error(`Malformed path data: ${instructionType} was expected to have numbers afterwards`);
52
+ }
53
+ const expectedArguments = length[instructionType];
54
+ if (numbers.length % expectedArguments !== 0) {
55
+ throw new Error(`Malformed path data: ${instructionType} was expected to have a multiple of ${expectedArguments} numbers, but got "${instructionType} ${numbers.join(' ')} instead"`);
56
+ }
57
+ return numbers.map(Number);
58
+ };
45
59
  /**
46
60
  * @description Parses an SVG string path into an array of Instruction's.
47
61
  * @param {string} path
@@ -249,17 +263,3 @@ const parsePath = (path) => {
249
263
  .flat(1);
250
264
  };
251
265
  exports.parsePath = parsePath;
252
- const parseValues = (args, instructionType) => {
253
- const numbers = args.match(numberRegExp);
254
- if (!numbers) {
255
- if (instructionType === 'Z' || instructionType === 'z') {
256
- return [];
257
- }
258
- throw new Error(`Malformed path data: ${instructionType} was expected to have numbers afterwards`);
259
- }
260
- const expectedArguments = length[instructionType];
261
- if (numbers.length % expectedArguments !== 0) {
262
- throw new Error(`Malformed path data: ${instructionType} was expected to have a multiple of ${expectedArguments} numbers, but got "${instructionType} ${numbers.join(' ')} instead"`);
263
- }
264
- return numbers.map(Number);
265
- };
@@ -6,9 +6,9 @@ export type WarpPathFn = (point: {
6
6
  x: number;
7
7
  y: number;
8
8
  };
9
+ export declare function split(p: number[][], t?: number): number[][][];
10
+ export declare function interpolateUntil(points: [number, number][], threshold: number, deltaFunction?: (points: [number, number][]) => number): [number, number][][];
11
+ export declare function createLineSegment(points: number[][]): ReducedInstruction;
9
12
  export declare function svgPathInterpolate(path: ReducedInstruction[], threshold: number): ReducedInstruction[];
10
13
  export declare const warpTransform: (path: ReducedInstruction[], transformer: WarpPathFn) => ReducedInstruction[];
11
14
  export declare const fixZInstruction: (instructions: ReducedInstruction[]) => ReducedInstruction[];
12
- export declare function interpolateUntil(points: [number, number][], threshold: number, deltaFunction?: (points: [number, number][]) => number): [number, number][][];
13
- export declare function split(p: number[][], t?: number): number[][][];
14
- export declare function createLineSegment(points: number[][]): ReducedInstruction;
@@ -1,20 +1,94 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createLineSegment = exports.split = exports.interpolateUntil = exports.fixZInstruction = exports.warpTransform = exports.svgPathInterpolate = void 0;
4
- function svgPathInterpolate(path, threshold) {
5
- let didWork = false;
6
- const deltaFunction = (points) => {
7
- const linearPoints = [
8
- points[0].slice(0, 2),
9
- points[points.length - 1].slice(0, 2),
10
- ];
11
- const delta = euclideanDistance(linearPoints);
12
- didWork = didWork || delta > threshold;
13
- return delta;
14
- };
15
- return warpInterpolate(path, threshold, deltaFunction);
3
+ exports.fixZInstruction = exports.warpTransform = exports.svgPathInterpolate = exports.createLineSegment = exports.interpolateUntil = exports.split = void 0;
4
+ const euclideanDistance = (points) => {
5
+ const startPoint = points[0];
6
+ const endPoint = points[points.length - 1];
7
+ let d2 = 0;
8
+ for (let i = 0; i < startPoint.length; i++) {
9
+ const d = endPoint[i] - startPoint[i];
10
+ d2 += d ** 2;
11
+ }
12
+ return Math.sqrt(d2);
13
+ };
14
+ function split(p, t = 0.5) {
15
+ const seg0 = [];
16
+ const seg1 = [];
17
+ const orders = [p];
18
+ while (orders.length < p.length) {
19
+ const q = orders[orders.length - 1];
20
+ const r = [];
21
+ for (let i = 1; i < q.length; i++) {
22
+ const q0 = q[i - 1];
23
+ const q1 = q[i];
24
+ const s = [];
25
+ const dim = Math.max(q0.length, q1.length);
26
+ for (let j = 0; j < dim; j++) {
27
+ const s0 = q0[j] || 0;
28
+ const s1 = q1[j] || 0;
29
+ s.push(s0 + (s1 - s0) * t);
30
+ }
31
+ r.push(s);
32
+ }
33
+ orders.push(r);
34
+ }
35
+ for (let i = 0; i < orders.length; i++) {
36
+ seg0.push(orders[i][0]);
37
+ seg1.push(orders[orders.length - 1 - i][i]);
38
+ }
39
+ return [seg0, seg1];
16
40
  }
17
- exports.svgPathInterpolate = svgPathInterpolate;
41
+ exports.split = split;
42
+ function interpolateUntil(points, threshold, deltaFunction = euclideanDistance) {
43
+ const stack = [points];
44
+ const segments = [];
45
+ while (stack.length > 0) {
46
+ const currentPoints = stack.pop();
47
+ if (deltaFunction(currentPoints) > threshold) {
48
+ const newPoints = split(currentPoints);
49
+ // Add new segments backwards so they end up in correct order
50
+ for (let i = newPoints.length - 1; i >= 0; i--) {
51
+ stack.push(newPoints[i]);
52
+ }
53
+ }
54
+ else {
55
+ segments.push(currentPoints);
56
+ }
57
+ }
58
+ return segments;
59
+ }
60
+ exports.interpolateUntil = interpolateUntil;
61
+ function createLineSegment(points) {
62
+ switch (points.length) {
63
+ case 2:
64
+ return {
65
+ type: 'L',
66
+ x: points[1][0],
67
+ y: points[1][1],
68
+ };
69
+ case 3:
70
+ return {
71
+ type: 'Q',
72
+ cpx: points[1][0],
73
+ cpy: points[1][1],
74
+ x: points[2][0],
75
+ y: points[2][1],
76
+ };
77
+ case 4:
78
+ return {
79
+ type: 'C',
80
+ cp1x: points[1][0],
81
+ cp1y: points[1][1],
82
+ cp2x: points[2][0],
83
+ cp2y: points[2][1],
84
+ x: points[3][0],
85
+ y: points[3][1],
86
+ };
87
+ default:
88
+ throw new Error('Expected 2, 3 or 4 points for a line segment, got ' + points.length);
89
+ }
90
+ }
91
+ exports.createLineSegment = createLineSegment;
18
92
  function warpInterpolate(path, threshold, deltaFunction) {
19
93
  let prexX = 0;
20
94
  let prexY = 0;
@@ -46,6 +120,20 @@ function warpInterpolate(path, threshold, deltaFunction) {
46
120
  })
47
121
  .flat(1);
48
122
  }
123
+ function svgPathInterpolate(path, threshold) {
124
+ let didWork = false;
125
+ const deltaFunction = (points) => {
126
+ const linearPoints = [
127
+ points[0].slice(0, 2),
128
+ points[points.length - 1].slice(0, 2),
129
+ ];
130
+ const delta = euclideanDistance(linearPoints);
131
+ didWork = didWork || delta > threshold;
132
+ return delta;
133
+ };
134
+ return warpInterpolate(path, threshold, deltaFunction);
135
+ }
136
+ exports.svgPathInterpolate = svgPathInterpolate;
49
137
  const warpTransform = (path, transformer) => {
50
138
  return path
51
139
  .map((segment) => {
@@ -139,91 +227,3 @@ const fixZInstruction = (instructions) => {
139
227
  .flat(1);
140
228
  };
141
229
  exports.fixZInstruction = fixZInstruction;
142
- const euclideanDistance = (points) => {
143
- const startPoint = points[0];
144
- const endPoint = points[points.length - 1];
145
- let d2 = 0;
146
- for (let i = 0; i < startPoint.length; i++) {
147
- const d = endPoint[i] - startPoint[i];
148
- d2 += d ** 2;
149
- }
150
- return Math.sqrt(d2);
151
- };
152
- function interpolateUntil(points, threshold, deltaFunction = euclideanDistance) {
153
- const stack = [points];
154
- const segments = [];
155
- while (stack.length > 0) {
156
- const currentPoints = stack.pop();
157
- if (deltaFunction(currentPoints) > threshold) {
158
- const newPoints = split(currentPoints);
159
- // Add new segments backwards so they end up in correct order
160
- for (let i = newPoints.length - 1; i >= 0; i--) {
161
- stack.push(newPoints[i]);
162
- }
163
- }
164
- else {
165
- segments.push(currentPoints);
166
- }
167
- }
168
- return segments;
169
- }
170
- exports.interpolateUntil = interpolateUntil;
171
- function split(p, t = 0.5) {
172
- const seg0 = [];
173
- const seg1 = [];
174
- const orders = [p];
175
- while (orders.length < p.length) {
176
- const q = orders[orders.length - 1];
177
- const r = [];
178
- for (let i = 1; i < q.length; i++) {
179
- const q0 = q[i - 1];
180
- const q1 = q[i];
181
- const s = [];
182
- const dim = Math.max(q0.length, q1.length);
183
- for (let j = 0; j < dim; j++) {
184
- const s0 = q0[j] || 0;
185
- const s1 = q1[j] || 0;
186
- s.push(s0 + (s1 - s0) * t);
187
- }
188
- r.push(s);
189
- }
190
- orders.push(r);
191
- }
192
- for (let i = 0; i < orders.length; i++) {
193
- seg0.push(orders[i][0]);
194
- seg1.push(orders[orders.length - 1 - i][i]);
195
- }
196
- return [seg0, seg1];
197
- }
198
- exports.split = split;
199
- function createLineSegment(points) {
200
- switch (points.length) {
201
- case 2:
202
- return {
203
- type: 'L',
204
- x: points[1][0],
205
- y: points[1][1],
206
- };
207
- case 3:
208
- return {
209
- type: 'Q',
210
- cpx: points[1][0],
211
- cpy: points[1][1],
212
- x: points[2][0],
213
- y: points[2][1],
214
- };
215
- case 4:
216
- return {
217
- type: 'C',
218
- cp1x: points[1][0],
219
- cp1y: points[1][1],
220
- cp2x: points[2][0],
221
- cp2y: points[2][1],
222
- x: points[3][0],
223
- y: points[3][1],
224
- };
225
- default:
226
- throw new Error('Expected 2, 3 or 4 points for a line segment, got ' + points.length);
227
- }
228
- }
229
- exports.createLineSegment = createLineSegment;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/paths",
3
- "version": "4.0.45",
3
+ "version": "4.0.47",
4
4
  "description": "Utility functions for SVG paths",
5
5
  "main": "dist/index.js",
6
6
  "sideEffects": false,
@@ -13,7 +13,7 @@
13
13
  "url": "https://github.com/remotion-dev/remotion/issues"
14
14
  },
15
15
  "devDependencies": {
16
- "@jonny/eslint-config": "3.0.266",
16
+ "@jonny/eslint-config": "3.0.276",
17
17
  "@types/node": "18.14.6",
18
18
  "eslint": "8.42.0",
19
19
  "prettier": "3.0.2",