@remotion/paths 4.0.0-alpha.130 → 4.0.0-alpha.185

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.
@@ -0,0 +1,8 @@
1
+ import type { Part } from './helpers/types';
2
+ /**
3
+ * @description Splits a valid SVG path into it's parts.
4
+ * @param {string} path A valid SVG path
5
+ * @see [Documentation](https://remotion.dev/docs/paths/get-parts)
6
+ * @deprecated In favor of getSubpaths()
7
+ */
8
+ export declare const getParts: (path: string) => Part[];
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getParts = void 0;
4
+ const construct_1 = require("./helpers/construct");
5
+ /**
6
+ * @description Splits a valid SVG path into it's parts.
7
+ * @param {string} path A valid SVG path
8
+ * @see [Documentation](https://remotion.dev/docs/paths/get-parts)
9
+ * @deprecated In favor of getSubpaths()
10
+ */
11
+ const getParts = (path) => {
12
+ const parts = [];
13
+ const constructed = (0, construct_1.construct)(path);
14
+ let i = 0;
15
+ for (const fn of constructed.functions) {
16
+ if (!fn) {
17
+ i++;
18
+ continue;
19
+ }
20
+ const properties = {
21
+ start: fn.getPointAtLength(0),
22
+ end: fn.getPointAtLength(constructed.partial_lengths[i] - constructed.partial_lengths[i - 1]),
23
+ length: constructed.partial_lengths[i] - constructed.partial_lengths[i - 1],
24
+ getPointAtLength: fn.getPointAtLength,
25
+ getTangentAtLength: fn.getTangentAtLength,
26
+ };
27
+ i++;
28
+ parts.push(properties);
29
+ }
30
+ return parts;
31
+ };
32
+ exports.getParts = getParts;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getSubpaths = void 0;
4
4
  const construct_1 = require("./helpers/construct");
5
+ const parse_path_1 = require("./parse-path");
5
6
  const serialize_instructions_1 = require("./serialize-instructions");
6
7
  /**
7
8
  * @description Splits a valid SVG path into it's parts.
@@ -9,7 +10,8 @@ const serialize_instructions_1 = require("./serialize-instructions");
9
10
  * @see [Documentation](https://remotion.dev/docs/paths/get-subpaths)
10
11
  */
11
12
  const getSubpaths = (path) => {
12
- const { segments } = (0, construct_1.construct)(path);
13
+ const parsed = (0, parse_path_1.parsePath)(path);
14
+ const { segments } = (0, construct_1.constructFromInstructions)(parsed);
13
15
  return segments.map((seg) => {
14
16
  return (0, serialize_instructions_1.serializeInstructions)(seg);
15
17
  });
@@ -1,4 +1,11 @@
1
1
  import type { Instruction, Point, Properties } from './types';
2
+ export declare const constructFromInstructions: (instructions: Instruction[]) => {
3
+ segments: Instruction[][];
4
+ initial_point: Point | null;
5
+ length: number;
6
+ partial_lengths: number[];
7
+ functions: (Properties | null)[];
8
+ };
2
9
  export declare const construct: (string: string) => {
3
10
  segments: Instruction[][];
4
11
  initial_point: Point | null;
@@ -1,24 +1,23 @@
1
1
  "use strict";
2
2
  // Copied from: https://github.com/rveciana/svg-path-properties
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.construct = void 0;
4
+ exports.construct = exports.constructFromInstructions = void 0;
5
5
  const parse_path_1 = require("../parse-path");
6
6
  const arc_1 = require("./arc");
7
7
  const bezier_1 = require("./bezier");
8
8
  const linear_1 = require("./linear");
9
- const construct = (string) => {
9
+ const constructFromInstructions = (instructions) => {
10
10
  let length = 0;
11
11
  const partial_lengths = [];
12
12
  const functions = [];
13
13
  let initial_point = null;
14
- const parsed = (0, parse_path_1.parsePath)(string);
15
14
  let cur = [0, 0];
16
15
  let prev_point = [0, 0];
17
16
  let curve;
18
17
  let ringStart = [0, 0];
19
18
  const segments = [];
20
- for (let i = 0; i < parsed.length; i++) {
21
- const instruction = parsed[i];
19
+ for (let i = 0; i < instructions.length; i++) {
20
+ const instruction = instructions[i];
22
21
  if (instruction.type !== 'm' &&
23
22
  instruction.type !== 'M' &&
24
23
  segments.length > 0) {
@@ -149,7 +148,7 @@ const construct = (string) => {
149
148
  }
150
149
  }
151
150
  else if (instruction.type === 'S') {
152
- const prev = parsed[i - 1];
151
+ const prev = instructions[i - 1];
153
152
  const prevWasCurve = prev.type === 'C' ||
154
153
  prev.type === 'c' ||
155
154
  prev.type === 'S' ||
@@ -188,7 +187,7 @@ const construct = (string) => {
188
187
  }
189
188
  }
190
189
  else if (instruction.type === 's') {
191
- const prev = parsed[i - 1];
190
+ const prev = instructions[i - 1];
192
191
  const prevWasCurve = prev.type === 'C' ||
193
192
  prev.type === 'c' ||
194
193
  prev.type === 'S' ||
@@ -285,7 +284,7 @@ const construct = (string) => {
285
284
  cur = [instruction.dx + cur[0], instruction.dy + cur[1]];
286
285
  }
287
286
  else if (instruction.type === 'T') {
288
- const prev = parsed[i - 1];
287
+ const prev = instructions[i - 1];
289
288
  const prevWasQ = prev.type === 'Q' ||
290
289
  prev.type === 'q' ||
291
290
  prev.type === 'T' ||
@@ -318,7 +317,7 @@ const construct = (string) => {
318
317
  cur = [instruction.x, instruction.y];
319
318
  }
320
319
  else if (instruction.type === 't') {
321
- const prev = parsed[i - 1];
320
+ const prev = instructions[i - 1];
322
321
  const prevWasQ = prev.type === 'Q' ||
323
322
  prev.type === 'q' ||
324
323
  prev.type === 'T' ||
@@ -392,4 +391,9 @@ const construct = (string) => {
392
391
  functions,
393
392
  };
394
393
  };
394
+ exports.constructFromInstructions = constructFromInstructions;
395
+ const construct = (string) => {
396
+ const parsed = (0, parse_path_1.parsePath)(string);
397
+ return (0, exports.constructFromInstructions)(parsed);
398
+ };
395
399
  exports.construct = construct;
@@ -7,123 +7,77 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.reversePath = void 0;
10
+ const construct_1 = require("./helpers/construct");
10
11
  const normalize_path_1 = require("./normalize-path");
11
- /**
12
- * Normalise an SVG path to absolute coordinates
13
- * and full commands, rather than relative coordinates
14
- * and/or shortcut commands.
15
- */
16
- /**
17
- * Reverse an SVG path.
18
- * As long as the input path is normalised, this is actually really
19
- * simple to do. As all pathing commands are symmetrical, meaning
20
- * that they render the same when you reverse the coordinate order,
21
- * the grand trick here is to reverse the path (making sure to keep
22
- * coordinates ordered pairwise) and shift the operators left by
23
- * one or two coordinate pairs depending on the operator:
24
- *
25
- * - Z is removed (after noting it existed),
26
- * - L moves to 2 spots earlier (skipping one coordinate),
27
- * - Q moves to 2 spots earlier (skipping one coordinate),
28
- * - C moves to 4 spots earlier (skipping two coordinates)
29
- * and its arguments get reversed,
30
- * - the path start becomes M.
31
- * - the path end becomes Z iff it was there to begin with.
32
- */
33
- function reverseNormalizedPath(normalized) {
34
- const terms = normalized.trim().split(' ');
35
- let term;
36
- const tlen = terms.length;
37
- const tlen1 = tlen - 1;
38
- let t;
12
+ const parse_path_1 = require("./parse-path");
13
+ const reduce_instructions_1 = require("./reduce-instructions");
14
+ const serialize_instructions_1 = require("./serialize-instructions");
15
+ function reverseNormalizedPath(instructions) {
39
16
  const reversed = [];
40
- let x;
41
- let y;
42
- let pair;
43
- let pairs;
44
- let shift;
45
- const matcher = /[QAZLCM]/;
46
- const closed = terms.slice(-1)[0].toUpperCase() === 'Z';
47
- for (t = 0; t < tlen; t++) {
48
- term = terms[t];
49
- // Is this an operator? If it is, run through its
50
- // argument list, which we know is fixed length.
51
- if (matcher.test(term)) {
52
- // Arc processing relies on not-just-coordinates
53
- if (term === 'A') {
54
- reversed.push(terms[t + 5] === '0' ? '1' : '0');
55
- reversed.push(terms[t + 4]);
56
- reversed.push(terms[t + 3]);
57
- reversed.push(terms[t + 2]);
58
- reversed.push(terms[t + 1]);
59
- reversed.push(term);
60
- reversed.push(terms[t + 7]);
61
- reversed.push(terms[t + 6]);
62
- t += 7;
63
- continue;
64
- }
65
- // how many coordinate pairs do we need to read,
66
- // and by how many pairs should this operator be
67
- // shifted left?
68
- else if (term === 'C') {
69
- pairs = 3;
70
- shift = 2;
71
- }
72
- else if (term === 'Q') {
73
- pairs = 2;
74
- shift = 1;
75
- }
76
- else if (term === 'L') {
77
- pairs = 1;
78
- shift = 1;
79
- }
80
- else if (term === 'M') {
81
- pairs = 1;
82
- shift = 0;
83
- }
84
- else {
85
- continue;
86
- }
87
- // do the argument reading and operator shifting
88
- if (pairs === shift) {
89
- reversed.push(term);
90
- }
91
- for (pair = 0; pair < pairs; pair++) {
92
- if (pair === shift) {
93
- reversed.push(term);
94
- }
95
- x = terms[++t];
96
- y = terms[++t];
97
- reversed.push(y);
98
- reversed.push(x);
99
- }
17
+ let nextX = 0;
18
+ let nextY = 0;
19
+ for (const term of instructions) {
20
+ if (term.type === 'A') {
21
+ reversed.unshift({
22
+ type: 'A',
23
+ largeArcFlag: term.largeArcFlag,
24
+ rx: term.rx,
25
+ ry: term.ry,
26
+ xAxisRotation: term.xAxisRotation,
27
+ sweepFlag: !term.sweepFlag,
28
+ x: nextX,
29
+ y: nextY,
30
+ });
31
+ }
32
+ else if (term.type === 'C') {
33
+ reversed.unshift({
34
+ type: 'C',
35
+ cp1x: term.cp2x,
36
+ cp1y: term.cp2y,
37
+ cp2x: term.cp1x,
38
+ cp2y: term.cp1y,
39
+ x: nextX,
40
+ y: nextY,
41
+ });
42
+ }
43
+ else if (term.type === 'Q') {
44
+ reversed.unshift({
45
+ type: 'Q',
46
+ cpx: term.cpx,
47
+ cpy: term.cpy,
48
+ x: nextX,
49
+ y: nextY,
50
+ });
51
+ }
52
+ else if (term.type === 'L') {
53
+ reversed.unshift({
54
+ type: 'L',
55
+ x: nextX,
56
+ y: nextY,
57
+ });
58
+ // Do nothing
59
+ }
60
+ else if (term.type === 'M') {
61
+ // Do nothing
62
+ }
63
+ else if (term.type === 'Z') {
64
+ // Do nothing
100
65
  }
101
- // the code has been set up so that every time we
102
- // iterate because of the for() operation, the term
103
- // we see is a pathing operator, not a number. As
104
- // such, if we get to this "else" the path is malformed.
105
66
  else {
106
- const pre = terms.slice(Math.max(t - 3, 0), 3).join(' ');
107
- const post = terms.slice(t + 1, Math.min(t + 4, tlen1)).join(' ');
108
- const range = pre + ' [' + term + '] ' + post;
109
- throw new Error('Error while trying to reverse normalized SVG path, at position ' +
110
- t +
111
- ' (' +
112
- range +
113
- ').\n' +
114
- "Either the path is not normalised, or it's malformed.");
67
+ throw new Error('unnormalized instruction ' + term.type);
68
+ }
69
+ if (term.type !== 'Z') {
70
+ nextX = term.x;
71
+ nextY = term.y;
115
72
  }
116
73
  }
117
- reversed.push('M');
118
- // generating the reversed path string involves
119
- // running through our transformed terms in reverse.
120
- let revstring = '';
121
- const rlen1 = reversed.length - 1;
122
- let r;
123
- for (r = rlen1; r > 0; r--) {
124
- revstring += reversed[r] + ' ';
125
- }
126
- if (closed)
74
+ reversed.unshift({
75
+ type: 'M',
76
+ x: nextX,
77
+ y: nextY,
78
+ });
79
+ let revstring = (0, serialize_instructions_1.serializeInstructions)(reversed);
80
+ if (instructions[instructions.length - 1].type === 'Z')
127
81
  revstring += 'Z';
128
82
  revstring = revstring.replace(/M M/g, 'Z M');
129
83
  return revstring;
@@ -134,12 +88,13 @@ function reverseNormalizedPath(normalized) {
134
88
  * @see [Documentation](https://remotion.dev/docs/paths/reverse-path)
135
89
  */
136
90
  const reversePath = (path) => {
137
- const normalizedPath = (0, normalize_path_1.normalizePath)(path);
138
- const paths = normalizedPath.replace(/M/g, '|M').split('|');
139
- paths.splice(0, 1);
140
- return paths
91
+ const parsed = (0, parse_path_1.parsePath)(path);
92
+ const normalized = (0, normalize_path_1.normalizeInstructions)(parsed);
93
+ const reduced = (0, reduce_instructions_1.reduceInstructions)(normalized);
94
+ const { segments } = (0, construct_1.constructFromInstructions)(reduced);
95
+ return segments
141
96
  .map((spath) => {
142
- return reverseNormalizedPath(spath.trim());
97
+ return reverseNormalizedPath(spath);
143
98
  })
144
99
  .join(' ')
145
100
  .replace(/ +/g, ' ')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/paths",
3
- "version": "4.0.0-alpha.130+167d9bb7f",
3
+ "version": "4.0.0-alpha.185+1b8f0e746",
4
4
  "description": "Utility functions for SVG paths",
5
5
  "main": "dist/index.js",
6
6
  "sideEffects": false,
@@ -35,5 +35,5 @@
35
35
  "publishConfig": {
36
36
  "access": "public"
37
37
  },
38
- "gitHead": "167d9bb7fc36e3cb939dec0e904be7a19a8eebb2"
38
+ "gitHead": "1b8f0e746ea4aa1153c4ecc7bc1063752c405f25"
39
39
  }