@remotion/paths 4.0.527 → 4.0.529
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.
- package/dist/esm/index.mjs +122 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/interpolate-paths.d.ts +6 -0
- package/dist/interpolate-paths.js +128 -0
- package/dist/normalize-path.js +2 -2
- package/dist/parse-path.js +29 -2
- package/package.json +5 -2
package/dist/esm/index.mjs
CHANGED
|
@@ -1144,9 +1144,31 @@ var makeInstructions = (arr, instruction, cb) => {
|
|
|
1144
1144
|
};
|
|
1145
1145
|
var segmentRegExp = /([astvzqmhlc])([^astvzqmhlc]*)/gi;
|
|
1146
1146
|
var numberRegExp = /-?[0-9]*\.?[0-9]+(?:e[-+]?\d+)?/gi;
|
|
1147
|
+
var arcNumberRegExp = /[\s,]*([-+]?(?:[0-9]+\.?[0-9]*|\.[0-9]+)(?:e[-+]?\d+)?)/iy;
|
|
1148
|
+
var arcFlagRegExp = /[\s,]*([01])/y;
|
|
1147
1149
|
var parseValues = (args, instructionType) => {
|
|
1148
|
-
|
|
1149
|
-
if (
|
|
1150
|
+
let numbers;
|
|
1151
|
+
if (instructionType === "A" || instructionType === "a") {
|
|
1152
|
+
numbers = [];
|
|
1153
|
+
let match;
|
|
1154
|
+
let lastIndex = 0;
|
|
1155
|
+
do {
|
|
1156
|
+
const regExp = numbers.length % 7 === 3 || numbers.length % 7 === 4 ? arcFlagRegExp : arcNumberRegExp;
|
|
1157
|
+
regExp.lastIndex = lastIndex;
|
|
1158
|
+
match = regExp.exec(args);
|
|
1159
|
+
if (match) {
|
|
1160
|
+
numbers.push(match[1]);
|
|
1161
|
+
lastIndex = regExp.lastIndex;
|
|
1162
|
+
}
|
|
1163
|
+
} while (match);
|
|
1164
|
+
const rest = args.slice(lastIndex);
|
|
1165
|
+
if (!/^[\s,]*$/.test(rest)) {
|
|
1166
|
+
throw new Error(`Malformed path data: ${instructionType} has an invalid value at "${rest.trim()}"`);
|
|
1167
|
+
}
|
|
1168
|
+
} else {
|
|
1169
|
+
numbers = args.match(numberRegExp);
|
|
1170
|
+
}
|
|
1171
|
+
if (!numbers || numbers.length === 0) {
|
|
1150
1172
|
if (instructionType === "Z" || instructionType === "z") {
|
|
1151
1173
|
return [];
|
|
1152
1174
|
}
|
|
@@ -1788,8 +1810,8 @@ var normalizeInstructions = (instructions) => {
|
|
|
1788
1810
|
moveX = instruction.x;
|
|
1789
1811
|
moveY = instruction.y;
|
|
1790
1812
|
} else if (instruction.type === "m") {
|
|
1791
|
-
moveX
|
|
1792
|
-
moveY
|
|
1813
|
+
moveX = x + instruction.dx;
|
|
1814
|
+
moveY = y + instruction.dy;
|
|
1793
1815
|
}
|
|
1794
1816
|
if (instruction.type === "A" || instruction.type === "C" || instruction.type === "L" || instruction.type === "M" || instruction.type === "Q" || instruction.type === "S" || instruction.type === "T") {
|
|
1795
1817
|
normalized.push(instruction);
|
|
@@ -3275,6 +3297,101 @@ var interpolatePath = (value, firstPath, secondPath) => {
|
|
|
3275
3297
|
const commandInterpolator = interpolateInstructions(aCommands, bCommands);
|
|
3276
3298
|
return serializeInstructions(commandInterpolator(value));
|
|
3277
3299
|
};
|
|
3300
|
+
// src/interpolate-paths.ts
|
|
3301
|
+
import {
|
|
3302
|
+
interpolate
|
|
3303
|
+
} from "remotion/no-react";
|
|
3304
|
+
var normalizeInterpolatedPath = (path) => {
|
|
3305
|
+
return path.replace(/-?\d*\.?\d+(?:e[+-]?\d+)?/gi, (value) => {
|
|
3306
|
+
const number = Number(value);
|
|
3307
|
+
return Number.isInteger(number) ? value : String(Number(number.toPrecision(15)));
|
|
3308
|
+
});
|
|
3309
|
+
};
|
|
3310
|
+
var interpolatePaths = (input, inputRange, outputRange, options) => {
|
|
3311
|
+
if (!Array.isArray(outputRange)) {
|
|
3312
|
+
throw new TypeError("outputRange must be an array of SVG path strings");
|
|
3313
|
+
}
|
|
3314
|
+
for (const path of outputRange) {
|
|
3315
|
+
if (typeof path !== "string") {
|
|
3316
|
+
throw new TypeError("outputRange must contain only SVG path strings");
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
for (const side of ["extrapolateLeft", "extrapolateRight"]) {
|
|
3320
|
+
const extrapolation = options?.[side];
|
|
3321
|
+
if (extrapolation !== undefined && extrapolation !== "extend" && extrapolation !== "clamp" && extrapolation !== "wrap") {
|
|
3322
|
+
throw new TypeError(`${side} must be "extend", "clamp", or "wrap" for interpolatePaths()`);
|
|
3323
|
+
}
|
|
3324
|
+
}
|
|
3325
|
+
const weights = interpolate(input, inputRange, outputRange.map((_, pathIndex) => outputRange.map((__, index) => index === pathIndex ? 1 : 0)), options);
|
|
3326
|
+
const exactPathIndex = weights.findIndex((weight, index) => weight === 1 && weights.every((otherWeight, otherIndex) => otherIndex === index ? true : otherWeight === 0));
|
|
3327
|
+
if (exactPathIndex !== -1) {
|
|
3328
|
+
return outputRange[exactPathIndex];
|
|
3329
|
+
}
|
|
3330
|
+
const contributingPaths = outputRange.map((path, index) => ({ path, weight: weights[index] })).filter(({ weight }) => weight !== 0);
|
|
3331
|
+
const paths = contributingPaths.map(({ path }) => {
|
|
3332
|
+
const commands = reduceInstructions(parsePath(path));
|
|
3333
|
+
if (commands.length === 0) {
|
|
3334
|
+
throw new TypeError(`SVG Path "${path}" is not valid`);
|
|
3335
|
+
}
|
|
3336
|
+
return commands;
|
|
3337
|
+
});
|
|
3338
|
+
const closed = paths.every((commands) => commands[commands.length - 1].type === "Z");
|
|
3339
|
+
const openPaths = paths.map((commands) => commands[commands.length - 1].type === "Z" ? commands.slice(0, -1) : commands);
|
|
3340
|
+
const reference = openPaths.reduce((longest, commands) => commands.length > longest.length ? commands : longest);
|
|
3341
|
+
const extendedPaths = openPaths.map((commands) => commands.length < reference.length ? extendInstruction(commands, reference) : commands);
|
|
3342
|
+
const result = reference.map((_, instructionIndex) => {
|
|
3343
|
+
const commands = extendedPaths.map((path) => path[instructionIndex]);
|
|
3344
|
+
if (commands.some((command) => command.type === "Z")) {
|
|
3345
|
+
if (commands.every((command) => command.type === "Z")) {
|
|
3346
|
+
return { type: "Z" };
|
|
3347
|
+
}
|
|
3348
|
+
throw new TypeError("Cannot interpolate SVG paths with different subpath structures");
|
|
3349
|
+
}
|
|
3350
|
+
const target = commands.find((command) => command.type === "C") ?? commands[0];
|
|
3351
|
+
const normalized = commands.map((command, pathIndex) => {
|
|
3352
|
+
if (command.type === "M" !== (target.type === "M")) {
|
|
3353
|
+
throw new TypeError("Cannot interpolate SVG paths with different subpath structures");
|
|
3354
|
+
}
|
|
3355
|
+
return convertToSameInstructionType(command, target, getEndPosition(extendedPaths[pathIndex].slice(0, instructionIndex)));
|
|
3356
|
+
});
|
|
3357
|
+
const coordinates = normalized.map((command) => {
|
|
3358
|
+
if (command.type === "Z") {
|
|
3359
|
+
return [];
|
|
3360
|
+
}
|
|
3361
|
+
return command.type === "C" ? [
|
|
3362
|
+
command.x,
|
|
3363
|
+
command.y,
|
|
3364
|
+
command.cp1x,
|
|
3365
|
+
command.cp1y,
|
|
3366
|
+
command.cp2x,
|
|
3367
|
+
command.cp2y
|
|
3368
|
+
] : [command.x, command.y];
|
|
3369
|
+
});
|
|
3370
|
+
const values = coordinates[0].map((base, coordinateIndex) => {
|
|
3371
|
+
const interpolated = coordinates.reduce((value, path, pathIndex) => value + (path[coordinateIndex] - base) * contributingPaths[pathIndex].weight, base);
|
|
3372
|
+
if (Number.isFinite(interpolated)) {
|
|
3373
|
+
return interpolated;
|
|
3374
|
+
}
|
|
3375
|
+
return coordinates.reduce((sum, path, pathIndex) => sum + path[coordinateIndex] * contributingPaths[pathIndex].weight, 0);
|
|
3376
|
+
});
|
|
3377
|
+
if (target.type === "C") {
|
|
3378
|
+
return {
|
|
3379
|
+
type: "C",
|
|
3380
|
+
x: values[0],
|
|
3381
|
+
y: values[1],
|
|
3382
|
+
cp1x: values[2],
|
|
3383
|
+
cp1y: values[3],
|
|
3384
|
+
cp2x: values[4],
|
|
3385
|
+
cp2y: values[5]
|
|
3386
|
+
};
|
|
3387
|
+
}
|
|
3388
|
+
return { type: target.type, x: values[0], y: values[1] };
|
|
3389
|
+
});
|
|
3390
|
+
if (closed) {
|
|
3391
|
+
result.push({ type: "Z" });
|
|
3392
|
+
}
|
|
3393
|
+
return normalizeInterpolatedPath(serializeInstructions(result));
|
|
3394
|
+
};
|
|
3278
3395
|
// src/reset-path.ts
|
|
3279
3396
|
var resetPath = (d) => {
|
|
3280
3397
|
const box = getBoundingBox(d);
|
|
@@ -3735,6 +3852,7 @@ export {
|
|
|
3735
3852
|
reduceInstructions,
|
|
3736
3853
|
parsePath,
|
|
3737
3854
|
normalizePath,
|
|
3855
|
+
interpolatePaths,
|
|
3738
3856
|
interpolatePath,
|
|
3739
3857
|
getTangentAtLength,
|
|
3740
3858
|
getSubpaths,
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export { getSubpaths } from './get-subpaths';
|
|
|
10
10
|
export { getTangentAtLength } from './get-tangent-at-length';
|
|
11
11
|
export { AbsoluteInstruction, BoundingBox, Instruction, Part, ReducedInstruction, } from './helpers/types';
|
|
12
12
|
export { interpolatePath } from './interpolate-path/interpolate-path';
|
|
13
|
+
export { interpolatePaths, type InterpolatePathsOptions, } from './interpolate-paths';
|
|
13
14
|
export { normalizePath } from './normalize-path';
|
|
14
15
|
export { parsePath } from './parse-path';
|
|
15
16
|
export { reduceInstructions } from './reduce-instructions';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PathInternals = exports.warpPath = exports.translatePath = exports.serializeInstructions = exports.scalePath = exports.reversePath = exports.resetPath = exports.reduceInstructions = exports.parsePath = exports.normalizePath = exports.interpolatePath = exports.getTangentAtLength = exports.getSubpaths = exports.getPointAtLength = exports.getLength = exports.getInstructionIndexAtLength = exports.getBoundingBox = exports.extendViewBox = exports.evolvePath = exports.cutPath = exports.centerPath = void 0;
|
|
3
|
+
exports.PathInternals = exports.warpPath = exports.translatePath = exports.serializeInstructions = exports.scalePath = exports.reversePath = exports.resetPath = exports.reduceInstructions = exports.parsePath = exports.normalizePath = exports.interpolatePaths = exports.interpolatePath = exports.getTangentAtLength = exports.getSubpaths = exports.getPointAtLength = exports.getLength = exports.getInstructionIndexAtLength = exports.getBoundingBox = exports.extendViewBox = exports.evolvePath = exports.cutPath = exports.centerPath = void 0;
|
|
4
4
|
const cut_path_1 = require("./cut-path");
|
|
5
5
|
const debug_path_1 = require("./debug-path");
|
|
6
6
|
const get_bounding_box_1 = require("./get-bounding-box");
|
|
@@ -26,6 +26,8 @@ const get_tangent_at_length_1 = require("./get-tangent-at-length");
|
|
|
26
26
|
Object.defineProperty(exports, "getTangentAtLength", { enumerable: true, get: function () { return get_tangent_at_length_1.getTangentAtLength; } });
|
|
27
27
|
const interpolate_path_1 = require("./interpolate-path/interpolate-path");
|
|
28
28
|
Object.defineProperty(exports, "interpolatePath", { enumerable: true, get: function () { return interpolate_path_1.interpolatePath; } });
|
|
29
|
+
const interpolate_paths_1 = require("./interpolate-paths");
|
|
30
|
+
Object.defineProperty(exports, "interpolatePaths", { enumerable: true, get: function () { return interpolate_paths_1.interpolatePaths; } });
|
|
29
31
|
const normalize_path_1 = require("./normalize-path");
|
|
30
32
|
Object.defineProperty(exports, "normalizePath", { enumerable: true, get: function () { return normalize_path_1.normalizePath; } });
|
|
31
33
|
const parse_path_1 = require("./parse-path");
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type ExtrapolateType, type InterpolateOptions } from 'remotion/no-react';
|
|
2
|
+
export type InterpolatePathsOptions = Pick<InterpolateOptions, 'easing' | 'posterize'> & {
|
|
3
|
+
extrapolateLeft?: Exclude<ExtrapolateType, 'identity'>;
|
|
4
|
+
extrapolateRight?: Exclude<ExtrapolateType, 'identity'>;
|
|
5
|
+
};
|
|
6
|
+
export declare const interpolatePaths: (input: number, inputRange: readonly number[], outputRange: readonly string[], options?: InterpolatePathsOptions | undefined) => string;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.interpolatePaths = void 0;
|
|
4
|
+
const no_react_1 = require("remotion/no-react");
|
|
5
|
+
const get_end_position_1 = require("./get-end-position");
|
|
6
|
+
const convert_to_same_instruction_type_1 = require("./interpolate-path/convert-to-same-instruction-type");
|
|
7
|
+
const extend_command_1 = require("./interpolate-path/extend-command");
|
|
8
|
+
const parse_path_1 = require("./parse-path");
|
|
9
|
+
const reduce_instructions_1 = require("./reduce-instructions");
|
|
10
|
+
const serialize_instructions_1 = require("./serialize-instructions");
|
|
11
|
+
const normalizeInterpolatedPath = (path) => {
|
|
12
|
+
// Remove floating-point artifacts without rounding small coordinates to zero.
|
|
13
|
+
return path.replace(/-?\d*\.?\d+(?:e[+-]?\d+)?/gi, (value) => {
|
|
14
|
+
const number = Number(value);
|
|
15
|
+
return Number.isInteger(number)
|
|
16
|
+
? value
|
|
17
|
+
: String(Number(number.toPrecision(15)));
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
/*
|
|
21
|
+
* @description Interpolates between multiple SVG paths, with keyframes, easing, and extrapolation.
|
|
22
|
+
* @see [Documentation](https://www.remotion.dev/docs/paths/interpolate-paths)
|
|
23
|
+
*/
|
|
24
|
+
const interpolatePaths = (input, inputRange, outputRange, options) => {
|
|
25
|
+
if (!Array.isArray(outputRange)) {
|
|
26
|
+
throw new TypeError('outputRange must be an array of SVG path strings');
|
|
27
|
+
}
|
|
28
|
+
for (const path of outputRange) {
|
|
29
|
+
if (typeof path !== 'string') {
|
|
30
|
+
throw new TypeError('outputRange must contain only SVG path strings');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
for (const side of ['extrapolateLeft', 'extrapolateRight']) {
|
|
34
|
+
const extrapolation = options === null || options === void 0 ? void 0 : options[side];
|
|
35
|
+
if (extrapolation !== undefined &&
|
|
36
|
+
extrapolation !== 'extend' &&
|
|
37
|
+
extrapolation !== 'clamp' &&
|
|
38
|
+
extrapolation !== 'wrap') {
|
|
39
|
+
throw new TypeError(`${side} must be "extend", "clamp", or "wrap" for interpolatePaths()`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Interpolating a basis vector for each path preserves segment selection,
|
|
43
|
+
// easing overshoot, and the contributions of earlier spring segments.
|
|
44
|
+
const weights = (0, no_react_1.interpolate)(input, inputRange, outputRange.map((_, pathIndex) => outputRange.map((__, index) => (index === pathIndex ? 1 : 0))), options);
|
|
45
|
+
const exactPathIndex = weights.findIndex((weight, index) => weight === 1 &&
|
|
46
|
+
weights.every((otherWeight, otherIndex) => otherIndex === index ? true : otherWeight === 0));
|
|
47
|
+
if (exactPathIndex !== -1) {
|
|
48
|
+
return outputRange[exactPathIndex];
|
|
49
|
+
}
|
|
50
|
+
const contributingPaths = outputRange
|
|
51
|
+
.map((path, index) => ({ path, weight: weights[index] }))
|
|
52
|
+
.filter(({ weight }) => weight !== 0);
|
|
53
|
+
const paths = contributingPaths.map(({ path }) => {
|
|
54
|
+
const commands = (0, reduce_instructions_1.reduceInstructions)((0, parse_path_1.parsePath)(path));
|
|
55
|
+
if (commands.length === 0) {
|
|
56
|
+
throw new TypeError(`SVG Path "${path}" is not valid`);
|
|
57
|
+
}
|
|
58
|
+
return commands;
|
|
59
|
+
});
|
|
60
|
+
const closed = paths.every((commands) => commands[commands.length - 1].type === 'Z');
|
|
61
|
+
const openPaths = paths.map((commands) => commands[commands.length - 1].type === 'Z'
|
|
62
|
+
? commands.slice(0, -1)
|
|
63
|
+
: commands);
|
|
64
|
+
const reference = openPaths.reduce((longest, commands) => commands.length > longest.length ? commands : longest);
|
|
65
|
+
const extendedPaths = openPaths.map((commands) => commands.length < reference.length
|
|
66
|
+
? (0, extend_command_1.extendInstruction)(commands, reference)
|
|
67
|
+
: commands);
|
|
68
|
+
const result = reference.map((_, instructionIndex) => {
|
|
69
|
+
var _a;
|
|
70
|
+
const commands = extendedPaths.map((path) => path[instructionIndex]);
|
|
71
|
+
if (commands.some((command) => command.type === 'Z')) {
|
|
72
|
+
if (commands.every((command) => command.type === 'Z')) {
|
|
73
|
+
return { type: 'Z' };
|
|
74
|
+
}
|
|
75
|
+
throw new TypeError('Cannot interpolate SVG paths with different subpath structures');
|
|
76
|
+
}
|
|
77
|
+
// A common cubic command preserves every curve while allowing paths with
|
|
78
|
+
// different instruction types to share the same coordinate interpolation.
|
|
79
|
+
const target = (_a = commands.find((command) => command.type === 'C')) !== null && _a !== void 0 ? _a : commands[0];
|
|
80
|
+
const normalized = commands.map((command, pathIndex) => {
|
|
81
|
+
if ((command.type === 'M') !== (target.type === 'M')) {
|
|
82
|
+
throw new TypeError('Cannot interpolate SVG paths with different subpath structures');
|
|
83
|
+
}
|
|
84
|
+
return (0, convert_to_same_instruction_type_1.convertToSameInstructionType)(command, target, (0, get_end_position_1.getEndPosition)(extendedPaths[pathIndex].slice(0, instructionIndex)));
|
|
85
|
+
});
|
|
86
|
+
const coordinates = normalized.map((command) => {
|
|
87
|
+
if (command.type === 'Z') {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
return command.type === 'C'
|
|
91
|
+
? [
|
|
92
|
+
command.x,
|
|
93
|
+
command.y,
|
|
94
|
+
command.cp1x,
|
|
95
|
+
command.cp1y,
|
|
96
|
+
command.cp2x,
|
|
97
|
+
command.cp2y,
|
|
98
|
+
]
|
|
99
|
+
: [command.x, command.y];
|
|
100
|
+
});
|
|
101
|
+
const values = coordinates[0].map((base, coordinateIndex) => {
|
|
102
|
+
const interpolated = coordinates.reduce((value, path, pathIndex) => value +
|
|
103
|
+
(path[coordinateIndex] - base) * contributingPaths[pathIndex].weight, base);
|
|
104
|
+
if (Number.isFinite(interpolated)) {
|
|
105
|
+
return interpolated;
|
|
106
|
+
}
|
|
107
|
+
// Opposite large coordinates can overflow when subtracting the base.
|
|
108
|
+
return coordinates.reduce((sum, path, pathIndex) => sum + path[coordinateIndex] * contributingPaths[pathIndex].weight, 0);
|
|
109
|
+
});
|
|
110
|
+
if (target.type === 'C') {
|
|
111
|
+
return {
|
|
112
|
+
type: 'C',
|
|
113
|
+
x: values[0],
|
|
114
|
+
y: values[1],
|
|
115
|
+
cp1x: values[2],
|
|
116
|
+
cp1y: values[3],
|
|
117
|
+
cp2x: values[4],
|
|
118
|
+
cp2y: values[5],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return { type: target.type, x: values[0], y: values[1] };
|
|
122
|
+
});
|
|
123
|
+
if (closed) {
|
|
124
|
+
result.push({ type: 'Z' });
|
|
125
|
+
}
|
|
126
|
+
return normalizeInterpolatedPath((0, serialize_instructions_1.serializeInstructions)(result));
|
|
127
|
+
};
|
|
128
|
+
exports.interpolatePaths = interpolatePaths;
|
package/dist/normalize-path.js
CHANGED
|
@@ -17,8 +17,8 @@ const normalizeInstructions = (instructions) => {
|
|
|
17
17
|
moveY = instruction.y;
|
|
18
18
|
}
|
|
19
19
|
else if (instruction.type === 'm') {
|
|
20
|
-
moveX
|
|
21
|
-
moveY
|
|
20
|
+
moveX = x + instruction.dx;
|
|
21
|
+
moveY = y + instruction.dy;
|
|
22
22
|
}
|
|
23
23
|
if (instruction.type === 'A' ||
|
|
24
24
|
instruction.type === 'C' ||
|
package/dist/parse-path.js
CHANGED
|
@@ -42,9 +42,36 @@ 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 arcNumberRegExp = /[\s,]*([-+]?(?:[0-9]+\.?[0-9]*|\.[0-9]+)(?:e[-+]?\d+)?)/iy;
|
|
46
|
+
const arcFlagRegExp = /[\s,]*([01])/y;
|
|
45
47
|
const parseValues = (args, instructionType) => {
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
+
let numbers;
|
|
49
|
+
if (instructionType === 'A' || instructionType === 'a') {
|
|
50
|
+
// Arc flags are a single "0" or "1" and don't need a separator,
|
|
51
|
+
// e.g. "A1 1 0 011 1" (https://www.w3.org/TR/SVG2/paths.html#PathDataBNF)
|
|
52
|
+
numbers = [];
|
|
53
|
+
let match;
|
|
54
|
+
let lastIndex = 0;
|
|
55
|
+
do {
|
|
56
|
+
const regExp = numbers.length % 7 === 3 || numbers.length % 7 === 4
|
|
57
|
+
? arcFlagRegExp
|
|
58
|
+
: arcNumberRegExp;
|
|
59
|
+
regExp.lastIndex = lastIndex;
|
|
60
|
+
match = regExp.exec(args);
|
|
61
|
+
if (match) {
|
|
62
|
+
numbers.push(match[1]);
|
|
63
|
+
lastIndex = regExp.lastIndex;
|
|
64
|
+
}
|
|
65
|
+
} while (match);
|
|
66
|
+
const rest = args.slice(lastIndex);
|
|
67
|
+
if (!/^[\s,]*$/.test(rest)) {
|
|
68
|
+
throw new Error(`Malformed path data: ${instructionType} has an invalid value at "${rest.trim()}"`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
numbers = args.match(numberRegExp);
|
|
73
|
+
}
|
|
74
|
+
if (!numbers || numbers.length === 0) {
|
|
48
75
|
if (instructionType === 'Z' || instructionType === 'z') {
|
|
49
76
|
return [];
|
|
50
77
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/paths"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/paths",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.529",
|
|
7
7
|
"description": "Utilities for working with SVG paths",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"types": "dist/index.d.ts",
|
|
@@ -26,10 +26,13 @@
|
|
|
26
26
|
"utilities"
|
|
27
27
|
],
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
29
|
+
"@remotion/eslint-config-internal": "4.0.529",
|
|
30
30
|
"eslint": "9.19.0",
|
|
31
31
|
"@typescript/native-preview": "7.0.0-dev.20260217.1"
|
|
32
32
|
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"remotion": "4.0.529"
|
|
35
|
+
},
|
|
33
36
|
"exports": {
|
|
34
37
|
"./package.json": "./package.json",
|
|
35
38
|
".": {
|