modern-path2d 0.0.3 → 0.0.5

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/index.cjs CHANGED
@@ -181,8 +181,8 @@ class Curve {
181
181
  getTangentAt(u, output = new Point2D()) {
182
182
  return this.getTangent(this.getUtoTmapping(u), output);
183
183
  }
184
- getPathData() {
185
- return this.getPathCommands().map((cmd) => {
184
+ getData() {
185
+ return this.getCommands().map((cmd) => {
186
186
  switch (cmd.type) {
187
187
  case "M":
188
188
  return `M ${cmd.x} ${cmd.y}`;
@@ -238,7 +238,7 @@ class CircleCurve extends Curve {
238
238
  const _t = t * (end - start) + start - 0.5 * Math.PI;
239
239
  return new Point2D(Math.cos(_t), Math.sin(_t));
240
240
  }
241
- getPathCommands() {
241
+ getCommands() {
242
242
  return [];
243
243
  }
244
244
  drawTo(_ctx) {
@@ -307,7 +307,7 @@ class CubicBezierCurve extends Curve {
307
307
  max.y = Math.max(max.y, v0.y, v1.y, v2.y, v3.y);
308
308
  return { min, max };
309
309
  }
310
- getPathCommands() {
310
+ getCommands() {
311
311
  const { v0, v1, v2, v3 } = this;
312
312
  return [
313
313
  { type: "M", x: v0.x, y: v0.y },
@@ -379,7 +379,7 @@ class EllipseCurve extends Curve {
379
379
  }
380
380
  return output.set(_x, _y);
381
381
  }
382
- getPathCommands() {
382
+ getCommands() {
383
383
  const { x, y, rx, ry, startAngle, endAngle, clockwise } = this;
384
384
  const anticlockwise = !clockwise;
385
385
  const startX = x + rx * Math.cos(startAngle);
@@ -459,7 +459,7 @@ class LineCurve extends Curve {
459
459
  getTangentAt(u, output = new Point2D()) {
460
460
  return this.getTangent(u, output);
461
461
  }
462
- getPathCommands() {
462
+ getCommands() {
463
463
  const { v1, v2 } = this;
464
464
  return [
465
465
  { type: "M", x: v1.x, y: v1.y },
@@ -555,8 +555,8 @@ class HeartCurve extends Curve {
555
555
  const line = this.getCurrentLine(value);
556
556
  return new Point2D(line.v2.y - line.v1.y, -(line.v2.x - line.v1.x)).normalize();
557
557
  }
558
- getPathCommands() {
559
- return this.curves.flatMap((curve) => curve.getPathCommands());
558
+ getCommands() {
559
+ return this.curves.flatMap((curve) => curve.getCommands());
560
560
  }
561
561
  drawTo(ctx) {
562
562
  this.curves.forEach((curve) => curve.drawTo(ctx));
@@ -613,8 +613,8 @@ class PloygonCurve extends Curve {
613
613
  const line = this.getCurrentLine(value);
614
614
  return new Point2D(line.v2.y - line.v1.y, -(line.v2.x - line.v1.x)).normalize();
615
615
  }
616
- getPathCommands() {
617
- return this.curves.flatMap((curve) => curve.getPathCommands());
616
+ getCommands() {
617
+ return this.curves.flatMap((curve) => curve.getCommands());
618
618
  }
619
619
  getMinMax(min = Point2D.MAX, max = Point2D.MIN) {
620
620
  this.curves.forEach((curve) => curve.getMinMax(min, max));
@@ -640,7 +640,7 @@ class QuadraticBezierCurve extends Curve {
640
640
  );
641
641
  return output;
642
642
  }
643
- getPathCommands() {
643
+ getCommands() {
644
644
  const { v0, v1, v2 } = this;
645
645
  return [
646
646
  { type: "M", x: v0.x, y: v0.y },
@@ -747,8 +747,8 @@ class RectangularCurve extends Curve {
747
747
  const { v1, v2 } = this.getCurrentLine(value);
748
748
  return new Point2D(v2.y - v1.y, -(v2.x - v1.x)).normalize();
749
749
  }
750
- getPathCommands() {
751
- return this.curves.flatMap((curve) => curve.getPathCommands());
750
+ getCommands() {
751
+ return this.curves.flatMap((curve) => curve.getCommands());
752
752
  }
753
753
  getMinMax(min = Point2D.MAX, max = Point2D.MIN) {
754
754
  this.curves.forEach((curve) => curve.getMinMax(min, max));
@@ -782,7 +782,7 @@ class SplineCurve extends Curve {
782
782
  );
783
783
  return output;
784
784
  }
785
- getPathCommands() {
785
+ getCommands() {
786
786
  return [];
787
787
  }
788
788
  drawTo(_ctx) {
@@ -975,8 +975,8 @@ class CurvePath extends Curve {
975
975
  this.currentPoint.copy(curve.getPoint(1));
976
976
  return this;
977
977
  }
978
- getPathCommands() {
979
- return this.curves.flatMap((curve) => curve.getPathCommands());
978
+ getCommands() {
979
+ return this.curves.flatMap((curve) => curve.getCommands());
980
980
  }
981
981
  getMinMax(min = Point2D.MAX, max = Point2D.MIN) {
982
982
  this.curves.forEach((curve) => curve.getMinMax(min, max));
@@ -1005,14 +1005,52 @@ var __publicField = (obj, key, value) => {
1005
1005
  return value;
1006
1006
  };
1007
1007
  class Path2D {
1008
- constructor() {
1008
+ constructor(path) {
1009
1009
  __publicField(this, "currentPath", new CurvePath());
1010
1010
  __publicField(this, "paths", [this.currentPath]);
1011
+ if (path) {
1012
+ if (path instanceof Path2D) {
1013
+ this.addPath(path);
1014
+ } else if (Array.isArray(path)) {
1015
+ this.addCommands(path);
1016
+ } else {
1017
+ this.addData(path);
1018
+ }
1019
+ }
1011
1020
  }
1012
1021
  addPath(path) {
1013
1022
  this.paths.push(...path.paths.map((v) => v.clone()));
1014
1023
  return this;
1015
1024
  }
1025
+ addCommands(commands) {
1026
+ for (let i = 0, len = commands.length; i < len; i++) {
1027
+ const cmd = commands[i];
1028
+ switch (cmd.type) {
1029
+ case "M":
1030
+ this.moveTo(cmd.x, cmd.y);
1031
+ break;
1032
+ case "L":
1033
+ this.lineTo(cmd.x, cmd.y);
1034
+ break;
1035
+ case "C":
1036
+ this.bezierCurveTo(cmd.x2, cmd.y2, cmd.x1, cmd.y1, cmd.x, cmd.y);
1037
+ break;
1038
+ case "Q":
1039
+ this.quadraticCurveTo(cmd.x1, cmd.y1, cmd.x, cmd.y);
1040
+ break;
1041
+ case "A":
1042
+ break;
1043
+ case "Z":
1044
+ this.closePath();
1045
+ break;
1046
+ }
1047
+ }
1048
+ return this;
1049
+ }
1050
+ addData(data) {
1051
+ console.error("TODO", data);
1052
+ return this;
1053
+ }
1016
1054
  closePath() {
1017
1055
  this.currentPath.closePath();
1018
1056
  return this;
@@ -1085,11 +1123,11 @@ class Path2D {
1085
1123
  this.paths.forEach((path) => path.curves.forEach((curve) => curve.getMinMax(min, max)));
1086
1124
  return { min, max };
1087
1125
  }
1088
- getPathCommands() {
1089
- return this.paths.flatMap((path) => path.curves.flatMap((curve) => curve.getPathCommands()));
1126
+ getCommands() {
1127
+ return this.paths.flatMap((path) => path.curves.flatMap((curve) => curve.getCommands()));
1090
1128
  }
1091
- getPathData() {
1092
- return this.paths.map((path) => path.getPathData()).join(" ");
1129
+ getData() {
1130
+ return this.paths.map((path) => path.getData()).join(" ");
1093
1131
  }
1094
1132
  getBoundingBox() {
1095
1133
  const min = Point2D.MAX;
@@ -1104,7 +1142,7 @@ class Path2D {
1104
1142
  }
1105
1143
  getSvgString() {
1106
1144
  const { x, y, width, height } = this.getBoundingBox();
1107
- return `<svg viewBox="${x} ${y} ${width} ${height}" xmlns="http://www.w3.org/2000/svg"><path fill="none" stroke="currentColor" d="${this.getPathData()}"></path></svg>`;
1145
+ return `<svg viewBox="${x} ${y} ${width} ${height}" xmlns="http://www.w3.org/2000/svg"><path fill="none" stroke="currentColor" d="${this.getData()}"></path></svg>`;
1108
1146
  }
1109
1147
  getSvgDataUri() {
1110
1148
  return `data:image/svg+xml;base64,${btoa(this.getSvgString())}`;
package/dist/index.d.cts CHANGED
@@ -60,7 +60,7 @@ declare abstract class Curve {
60
60
  protected _cacheArcLengths?: number[];
61
61
  protected _needsUpdate: boolean;
62
62
  abstract getPoint(t: number, output?: Point2D): Point2D;
63
- abstract getPathCommands(): PathCommand[];
63
+ abstract getCommands(): PathCommand[];
64
64
  abstract drawTo(ctx: CanvasRenderingContext2D): void;
65
65
  getMinMax(min?: Point2D, max?: Point2D): {
66
66
  min: Point2D;
@@ -76,7 +76,7 @@ declare abstract class Curve {
76
76
  getUtoTmapping(u: number, distance?: number): number;
77
77
  getTangent(t: number, output?: Point2D): Point2D;
78
78
  getTangentAt(u: number, output?: Point2D): Point2D;
79
- getPathData(): string;
79
+ getData(): string;
80
80
  clone(): this;
81
81
  copy(source: Curve): this;
82
82
  }
@@ -106,7 +106,7 @@ declare class CurvePath extends Curve {
106
106
  absarc(x: number, y: number, radius: number, startAngle: number, endAngle: number, clockwise?: boolean): this;
107
107
  ellipse(x: number, y: number, xRadius: number, yRadius: number, startAngle: number, endAngle: number, clockwise?: boolean, rotation?: number): this;
108
108
  absellipse(x: number, y: number, xRadius: number, yRadius: number, startAngle: number, endAngle: number, clockwise?: boolean, rotation?: number): this;
109
- getPathCommands(): PathCommand[];
109
+ getCommands(): PathCommand[];
110
110
  getMinMax(min?: Point2D, max?: Point2D): {
111
111
  min: Point2D;
112
112
  max: Point2D;
@@ -128,7 +128,7 @@ declare class CircleCurve extends Curve {
128
128
  getPoint(t: number): Point2D;
129
129
  getTangent(t: number): Point2D;
130
130
  getNormal(t: number): Point2D;
131
- getPathCommands(): PathCommand[];
131
+ getCommands(): PathCommand[];
132
132
  drawTo(_ctx: CanvasRenderingContext2D): void;
133
133
  }
134
134
 
@@ -143,7 +143,7 @@ declare class CubicBezierCurve extends Curve {
143
143
  min: Point2D;
144
144
  max: Point2D;
145
145
  };
146
- getPathCommands(): PathCommand[];
146
+ getCommands(): PathCommand[];
147
147
  drawTo(ctx: CanvasRenderingContext2D): void;
148
148
  copy(source: CubicBezierCurve): this;
149
149
  }
@@ -160,7 +160,7 @@ declare class EllipseCurve extends Curve {
160
160
  constructor(x?: number, y?: number, rx?: number, ry?: number, startAngle?: number, endAngle?: number, clockwise?: boolean, rotation?: number);
161
161
  getDivisions(divisions?: number): number;
162
162
  getPoint(t: number, output?: Point2D): Point2D;
163
- getPathCommands(): PathCommand[];
163
+ getCommands(): PathCommand[];
164
164
  drawTo(ctx: CanvasRenderingContext2D): void;
165
165
  copy(source: EllipseCurve): this;
166
166
  }
@@ -178,7 +178,7 @@ declare class HeartCurve extends Curve {
178
178
  getCurrentLine(value: number): Curve;
179
179
  getTangent(value: number): Point2D;
180
180
  getNormal(value: number): Point2D;
181
- getPathCommands(): PathCommand[];
181
+ getCommands(): PathCommand[];
182
182
  drawTo(ctx: CanvasRenderingContext2D): void;
183
183
  }
184
184
 
@@ -191,7 +191,7 @@ declare class LineCurve extends Curve {
191
191
  getPointAt(u: number, output?: Point2D): Point2D;
192
192
  getTangent(t: number, output?: Point2D): Point2D;
193
193
  getTangentAt(u: number, output?: Point2D): Point2D;
194
- getPathCommands(): PathCommand[];
194
+ getCommands(): PathCommand[];
195
195
  getMinMax(min?: Point2D, max?: Point2D): {
196
196
  min: Point2D;
197
197
  max: Point2D;
@@ -216,7 +216,7 @@ declare class PloygonCurve extends Curve {
216
216
  getCurrentLine(value: number): LineCurve;
217
217
  getTangent(value: number): Point2D;
218
218
  getNormal(value: number): Point2D;
219
- getPathCommands(): PathCommand[];
219
+ getCommands(): PathCommand[];
220
220
  getMinMax(min?: Point2D, max?: Point2D): {
221
221
  min: Point2D;
222
222
  max: Point2D;
@@ -230,7 +230,7 @@ declare class QuadraticBezierCurve extends Curve {
230
230
  v2: Point2D;
231
231
  constructor(v0?: Point2D, v1?: Point2D, v2?: Point2D);
232
232
  getPoint(t: number, output?: Point2D): Point2D;
233
- getPathCommands(): PathCommand[];
233
+ getCommands(): PathCommand[];
234
234
  getMinMax(min?: Point2D, max?: Point2D): {
235
235
  min: Point2D;
236
236
  max: Point2D;
@@ -257,7 +257,7 @@ declare class RectangularCurve extends Curve {
257
257
  getCurrentLine(t: number): LineCurve;
258
258
  getTangent(t: number): Point2D;
259
259
  getNormal(value: number): Point2D;
260
- getPathCommands(): PathCommand[];
260
+ getCommands(): PathCommand[];
261
261
  getMinMax(min?: Point2D, max?: Point2D): {
262
262
  min: Point2D;
263
263
  max: Point2D;
@@ -270,7 +270,7 @@ declare class SplineCurve extends Curve {
270
270
  constructor(points?: Point2D[]);
271
271
  getDivisions(divisions?: number): number;
272
272
  getPoint(t: number, output?: Point2D): Point2D;
273
- getPathCommands(): PathCommand[];
273
+ getCommands(): PathCommand[];
274
274
  drawTo(_ctx: CanvasRenderingContext2D): void;
275
275
  copy(source: SplineCurve): this;
276
276
  }
@@ -281,7 +281,10 @@ declare class SplineCurve extends Curve {
281
281
  declare class Path2D {
282
282
  currentPath: CurvePath;
283
283
  paths: CurvePath[];
284
+ constructor(path?: Path2D | PathCommand[] | string);
284
285
  addPath(path: Path2D): this;
286
+ addCommands(commands: PathCommand[]): this;
287
+ addData(data: string): this;
285
288
  closePath(): this;
286
289
  moveTo(x: number, y: number): this;
287
290
  lineTo(x: number, y: number): this;
@@ -289,15 +292,15 @@ declare class Path2D {
289
292
  quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): this;
290
293
  arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): this;
291
294
  arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): this;
292
- ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise: number): this;
295
+ ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): this;
293
296
  rect(x: number, y: number, w: number, h: number): this;
294
297
  splineThru(points: Point2D[]): this;
295
298
  getMinMax(min?: Point2D, max?: Point2D): {
296
299
  min: Point2D;
297
300
  max: Point2D;
298
301
  };
299
- getPathCommands(): PathCommand[];
300
- getPathData(): string;
302
+ getCommands(): PathCommand[];
303
+ getData(): string;
301
304
  getBoundingBox(): {
302
305
  x: number;
303
306
  y: number;
package/dist/index.d.mts CHANGED
@@ -60,7 +60,7 @@ declare abstract class Curve {
60
60
  protected _cacheArcLengths?: number[];
61
61
  protected _needsUpdate: boolean;
62
62
  abstract getPoint(t: number, output?: Point2D): Point2D;
63
- abstract getPathCommands(): PathCommand[];
63
+ abstract getCommands(): PathCommand[];
64
64
  abstract drawTo(ctx: CanvasRenderingContext2D): void;
65
65
  getMinMax(min?: Point2D, max?: Point2D): {
66
66
  min: Point2D;
@@ -76,7 +76,7 @@ declare abstract class Curve {
76
76
  getUtoTmapping(u: number, distance?: number): number;
77
77
  getTangent(t: number, output?: Point2D): Point2D;
78
78
  getTangentAt(u: number, output?: Point2D): Point2D;
79
- getPathData(): string;
79
+ getData(): string;
80
80
  clone(): this;
81
81
  copy(source: Curve): this;
82
82
  }
@@ -106,7 +106,7 @@ declare class CurvePath extends Curve {
106
106
  absarc(x: number, y: number, radius: number, startAngle: number, endAngle: number, clockwise?: boolean): this;
107
107
  ellipse(x: number, y: number, xRadius: number, yRadius: number, startAngle: number, endAngle: number, clockwise?: boolean, rotation?: number): this;
108
108
  absellipse(x: number, y: number, xRadius: number, yRadius: number, startAngle: number, endAngle: number, clockwise?: boolean, rotation?: number): this;
109
- getPathCommands(): PathCommand[];
109
+ getCommands(): PathCommand[];
110
110
  getMinMax(min?: Point2D, max?: Point2D): {
111
111
  min: Point2D;
112
112
  max: Point2D;
@@ -128,7 +128,7 @@ declare class CircleCurve extends Curve {
128
128
  getPoint(t: number): Point2D;
129
129
  getTangent(t: number): Point2D;
130
130
  getNormal(t: number): Point2D;
131
- getPathCommands(): PathCommand[];
131
+ getCommands(): PathCommand[];
132
132
  drawTo(_ctx: CanvasRenderingContext2D): void;
133
133
  }
134
134
 
@@ -143,7 +143,7 @@ declare class CubicBezierCurve extends Curve {
143
143
  min: Point2D;
144
144
  max: Point2D;
145
145
  };
146
- getPathCommands(): PathCommand[];
146
+ getCommands(): PathCommand[];
147
147
  drawTo(ctx: CanvasRenderingContext2D): void;
148
148
  copy(source: CubicBezierCurve): this;
149
149
  }
@@ -160,7 +160,7 @@ declare class EllipseCurve extends Curve {
160
160
  constructor(x?: number, y?: number, rx?: number, ry?: number, startAngle?: number, endAngle?: number, clockwise?: boolean, rotation?: number);
161
161
  getDivisions(divisions?: number): number;
162
162
  getPoint(t: number, output?: Point2D): Point2D;
163
- getPathCommands(): PathCommand[];
163
+ getCommands(): PathCommand[];
164
164
  drawTo(ctx: CanvasRenderingContext2D): void;
165
165
  copy(source: EllipseCurve): this;
166
166
  }
@@ -178,7 +178,7 @@ declare class HeartCurve extends Curve {
178
178
  getCurrentLine(value: number): Curve;
179
179
  getTangent(value: number): Point2D;
180
180
  getNormal(value: number): Point2D;
181
- getPathCommands(): PathCommand[];
181
+ getCommands(): PathCommand[];
182
182
  drawTo(ctx: CanvasRenderingContext2D): void;
183
183
  }
184
184
 
@@ -191,7 +191,7 @@ declare class LineCurve extends Curve {
191
191
  getPointAt(u: number, output?: Point2D): Point2D;
192
192
  getTangent(t: number, output?: Point2D): Point2D;
193
193
  getTangentAt(u: number, output?: Point2D): Point2D;
194
- getPathCommands(): PathCommand[];
194
+ getCommands(): PathCommand[];
195
195
  getMinMax(min?: Point2D, max?: Point2D): {
196
196
  min: Point2D;
197
197
  max: Point2D;
@@ -216,7 +216,7 @@ declare class PloygonCurve extends Curve {
216
216
  getCurrentLine(value: number): LineCurve;
217
217
  getTangent(value: number): Point2D;
218
218
  getNormal(value: number): Point2D;
219
- getPathCommands(): PathCommand[];
219
+ getCommands(): PathCommand[];
220
220
  getMinMax(min?: Point2D, max?: Point2D): {
221
221
  min: Point2D;
222
222
  max: Point2D;
@@ -230,7 +230,7 @@ declare class QuadraticBezierCurve extends Curve {
230
230
  v2: Point2D;
231
231
  constructor(v0?: Point2D, v1?: Point2D, v2?: Point2D);
232
232
  getPoint(t: number, output?: Point2D): Point2D;
233
- getPathCommands(): PathCommand[];
233
+ getCommands(): PathCommand[];
234
234
  getMinMax(min?: Point2D, max?: Point2D): {
235
235
  min: Point2D;
236
236
  max: Point2D;
@@ -257,7 +257,7 @@ declare class RectangularCurve extends Curve {
257
257
  getCurrentLine(t: number): LineCurve;
258
258
  getTangent(t: number): Point2D;
259
259
  getNormal(value: number): Point2D;
260
- getPathCommands(): PathCommand[];
260
+ getCommands(): PathCommand[];
261
261
  getMinMax(min?: Point2D, max?: Point2D): {
262
262
  min: Point2D;
263
263
  max: Point2D;
@@ -270,7 +270,7 @@ declare class SplineCurve extends Curve {
270
270
  constructor(points?: Point2D[]);
271
271
  getDivisions(divisions?: number): number;
272
272
  getPoint(t: number, output?: Point2D): Point2D;
273
- getPathCommands(): PathCommand[];
273
+ getCommands(): PathCommand[];
274
274
  drawTo(_ctx: CanvasRenderingContext2D): void;
275
275
  copy(source: SplineCurve): this;
276
276
  }
@@ -281,7 +281,10 @@ declare class SplineCurve extends Curve {
281
281
  declare class Path2D {
282
282
  currentPath: CurvePath;
283
283
  paths: CurvePath[];
284
+ constructor(path?: Path2D | PathCommand[] | string);
284
285
  addPath(path: Path2D): this;
286
+ addCommands(commands: PathCommand[]): this;
287
+ addData(data: string): this;
285
288
  closePath(): this;
286
289
  moveTo(x: number, y: number): this;
287
290
  lineTo(x: number, y: number): this;
@@ -289,15 +292,15 @@ declare class Path2D {
289
292
  quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): this;
290
293
  arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): this;
291
294
  arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): this;
292
- ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise: number): this;
295
+ ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): this;
293
296
  rect(x: number, y: number, w: number, h: number): this;
294
297
  splineThru(points: Point2D[]): this;
295
298
  getMinMax(min?: Point2D, max?: Point2D): {
296
299
  min: Point2D;
297
300
  max: Point2D;
298
301
  };
299
- getPathCommands(): PathCommand[];
300
- getPathData(): string;
302
+ getCommands(): PathCommand[];
303
+ getData(): string;
301
304
  getBoundingBox(): {
302
305
  x: number;
303
306
  y: number;
package/dist/index.d.ts CHANGED
@@ -60,7 +60,7 @@ declare abstract class Curve {
60
60
  protected _cacheArcLengths?: number[];
61
61
  protected _needsUpdate: boolean;
62
62
  abstract getPoint(t: number, output?: Point2D): Point2D;
63
- abstract getPathCommands(): PathCommand[];
63
+ abstract getCommands(): PathCommand[];
64
64
  abstract drawTo(ctx: CanvasRenderingContext2D): void;
65
65
  getMinMax(min?: Point2D, max?: Point2D): {
66
66
  min: Point2D;
@@ -76,7 +76,7 @@ declare abstract class Curve {
76
76
  getUtoTmapping(u: number, distance?: number): number;
77
77
  getTangent(t: number, output?: Point2D): Point2D;
78
78
  getTangentAt(u: number, output?: Point2D): Point2D;
79
- getPathData(): string;
79
+ getData(): string;
80
80
  clone(): this;
81
81
  copy(source: Curve): this;
82
82
  }
@@ -106,7 +106,7 @@ declare class CurvePath extends Curve {
106
106
  absarc(x: number, y: number, radius: number, startAngle: number, endAngle: number, clockwise?: boolean): this;
107
107
  ellipse(x: number, y: number, xRadius: number, yRadius: number, startAngle: number, endAngle: number, clockwise?: boolean, rotation?: number): this;
108
108
  absellipse(x: number, y: number, xRadius: number, yRadius: number, startAngle: number, endAngle: number, clockwise?: boolean, rotation?: number): this;
109
- getPathCommands(): PathCommand[];
109
+ getCommands(): PathCommand[];
110
110
  getMinMax(min?: Point2D, max?: Point2D): {
111
111
  min: Point2D;
112
112
  max: Point2D;
@@ -128,7 +128,7 @@ declare class CircleCurve extends Curve {
128
128
  getPoint(t: number): Point2D;
129
129
  getTangent(t: number): Point2D;
130
130
  getNormal(t: number): Point2D;
131
- getPathCommands(): PathCommand[];
131
+ getCommands(): PathCommand[];
132
132
  drawTo(_ctx: CanvasRenderingContext2D): void;
133
133
  }
134
134
 
@@ -143,7 +143,7 @@ declare class CubicBezierCurve extends Curve {
143
143
  min: Point2D;
144
144
  max: Point2D;
145
145
  };
146
- getPathCommands(): PathCommand[];
146
+ getCommands(): PathCommand[];
147
147
  drawTo(ctx: CanvasRenderingContext2D): void;
148
148
  copy(source: CubicBezierCurve): this;
149
149
  }
@@ -160,7 +160,7 @@ declare class EllipseCurve extends Curve {
160
160
  constructor(x?: number, y?: number, rx?: number, ry?: number, startAngle?: number, endAngle?: number, clockwise?: boolean, rotation?: number);
161
161
  getDivisions(divisions?: number): number;
162
162
  getPoint(t: number, output?: Point2D): Point2D;
163
- getPathCommands(): PathCommand[];
163
+ getCommands(): PathCommand[];
164
164
  drawTo(ctx: CanvasRenderingContext2D): void;
165
165
  copy(source: EllipseCurve): this;
166
166
  }
@@ -178,7 +178,7 @@ declare class HeartCurve extends Curve {
178
178
  getCurrentLine(value: number): Curve;
179
179
  getTangent(value: number): Point2D;
180
180
  getNormal(value: number): Point2D;
181
- getPathCommands(): PathCommand[];
181
+ getCommands(): PathCommand[];
182
182
  drawTo(ctx: CanvasRenderingContext2D): void;
183
183
  }
184
184
 
@@ -191,7 +191,7 @@ declare class LineCurve extends Curve {
191
191
  getPointAt(u: number, output?: Point2D): Point2D;
192
192
  getTangent(t: number, output?: Point2D): Point2D;
193
193
  getTangentAt(u: number, output?: Point2D): Point2D;
194
- getPathCommands(): PathCommand[];
194
+ getCommands(): PathCommand[];
195
195
  getMinMax(min?: Point2D, max?: Point2D): {
196
196
  min: Point2D;
197
197
  max: Point2D;
@@ -216,7 +216,7 @@ declare class PloygonCurve extends Curve {
216
216
  getCurrentLine(value: number): LineCurve;
217
217
  getTangent(value: number): Point2D;
218
218
  getNormal(value: number): Point2D;
219
- getPathCommands(): PathCommand[];
219
+ getCommands(): PathCommand[];
220
220
  getMinMax(min?: Point2D, max?: Point2D): {
221
221
  min: Point2D;
222
222
  max: Point2D;
@@ -230,7 +230,7 @@ declare class QuadraticBezierCurve extends Curve {
230
230
  v2: Point2D;
231
231
  constructor(v0?: Point2D, v1?: Point2D, v2?: Point2D);
232
232
  getPoint(t: number, output?: Point2D): Point2D;
233
- getPathCommands(): PathCommand[];
233
+ getCommands(): PathCommand[];
234
234
  getMinMax(min?: Point2D, max?: Point2D): {
235
235
  min: Point2D;
236
236
  max: Point2D;
@@ -257,7 +257,7 @@ declare class RectangularCurve extends Curve {
257
257
  getCurrentLine(t: number): LineCurve;
258
258
  getTangent(t: number): Point2D;
259
259
  getNormal(value: number): Point2D;
260
- getPathCommands(): PathCommand[];
260
+ getCommands(): PathCommand[];
261
261
  getMinMax(min?: Point2D, max?: Point2D): {
262
262
  min: Point2D;
263
263
  max: Point2D;
@@ -270,7 +270,7 @@ declare class SplineCurve extends Curve {
270
270
  constructor(points?: Point2D[]);
271
271
  getDivisions(divisions?: number): number;
272
272
  getPoint(t: number, output?: Point2D): Point2D;
273
- getPathCommands(): PathCommand[];
273
+ getCommands(): PathCommand[];
274
274
  drawTo(_ctx: CanvasRenderingContext2D): void;
275
275
  copy(source: SplineCurve): this;
276
276
  }
@@ -281,7 +281,10 @@ declare class SplineCurve extends Curve {
281
281
  declare class Path2D {
282
282
  currentPath: CurvePath;
283
283
  paths: CurvePath[];
284
+ constructor(path?: Path2D | PathCommand[] | string);
284
285
  addPath(path: Path2D): this;
286
+ addCommands(commands: PathCommand[]): this;
287
+ addData(data: string): this;
285
288
  closePath(): this;
286
289
  moveTo(x: number, y: number): this;
287
290
  lineTo(x: number, y: number): this;
@@ -289,15 +292,15 @@ declare class Path2D {
289
292
  quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): this;
290
293
  arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): this;
291
294
  arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): this;
292
- ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise: number): this;
295
+ ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): this;
293
296
  rect(x: number, y: number, w: number, h: number): this;
294
297
  splineThru(points: Point2D[]): this;
295
298
  getMinMax(min?: Point2D, max?: Point2D): {
296
299
  min: Point2D;
297
300
  max: Point2D;
298
301
  };
299
- getPathCommands(): PathCommand[];
300
- getPathData(): string;
302
+ getCommands(): PathCommand[];
303
+ getData(): string;
301
304
  getBoundingBox(): {
302
305
  x: number;
303
306
  y: number;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- (function(g,r){typeof exports=="object"&&typeof module<"u"?r(exports):typeof define=="function"&&define.amd?define(["exports"],r):(g=typeof globalThis<"u"?globalThis:g||self,r(g.modernPath2d={}))})(this,function(g){"use strict";var O=Object.defineProperty;var H=(g,r,x)=>r in g?O(g,r,{enumerable:!0,configurable:!0,writable:!0,value:x}):g[r]=x;var p=(g,r,x)=>H(g,typeof r!="symbol"?r+"":r,x);class r{constructor(e=0,t=0){this.x=e,this.y=t}static get MAX(){return new r(1/0,1/0)}static get MIN(){return new r(-1/0,-1/0)}set(e,t){return this.x=e,this.y=t,this}add(e){return this.x+=e.x,this.y+=e.y,this}sub(e){return this.x-=e.x,this.y-=e.y,this}distanceTo(e){return Math.sqrt(this.distanceToSquared(e))}distanceToSquared(e){const t=this.x-e.x,s=this.y-e.y;return t*t+s*s}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}multiplyScalar(e){return this.x*=e,this.y*=e,this}divideScalar(e){return this.multiplyScalar(1/e)}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this}normalize(){return this.divideScalar(this.length()||1)}lerpVectors(e,t,s){return this.x=e.x+(t.x-e.x)*s,this.y=e.y+(t.y-e.y)*s,this}equals(e){return this.x===e.x&&this.y===e.y}copy(e){return this.x=e.x,this.y=e.y,this}clone(){return new r(this.x,this.y)}}class x{constructor(){p(this,"arcLengthDivisions",200);p(this,"_cacheArcLengths");p(this,"_needsUpdate",!1)}getMinMax(e=r.MAX,t=r.MIN){return{min:e,max:t}}getDivisions(e){return e}getPointAt(e,t=new r){return this.getPoint(this.getUtoTmapping(e),t)}getPoints(e=5){const t=[];for(let s=0;s<=e;s++)t.push(this.getPoint(s/e));return t}getSpacedPoints(e=5){const t=[];for(let s=0;s<=e;s++)t.push(this.getPointAt(s/e));return t}getLength(){const e=this.getLengths();return e[e.length-1]}getLengths(e=this.arcLengthDivisions){if(this._cacheArcLengths&&this._cacheArcLengths.length===e+1&&!this._needsUpdate)return this._cacheArcLengths;this._needsUpdate=!1;const t=[];let s,n=this.getPoint(0),i=0;t.push(0);for(let h=1;h<=e;h++)s=this.getPoint(h/e),i+=s.distanceTo(n),t.push(i),n=s;return this._cacheArcLengths=t,t}updateArcLengths(){this._needsUpdate=!0,this.getLengths()}getUtoTmapping(e,t){const s=this.getLengths();let n=0;const i=s.length;let h;t?h=t:h=e*s[i-1];let o=0,a=i-1,u;for(;o<=a;)if(n=Math.floor(o+(a-o)/2),u=s[n]-h,u<0)o=n+1;else if(u>0)a=n-1;else{a=n;break}if(n=a,s[n]===h)return n/(i-1);const l=s[n],v=s[n+1]-l,M=(h-l)/v;return(n+M)/(i-1)}getTangent(e,t=new r){let n=e-1e-4,i=e+1e-4;return n<0&&(n=0),i>1&&(i=1),t.copy(this.getPoint(i)).sub(this.getPoint(n)).normalize()}getTangentAt(e,t=new r){return this.getTangent(this.getUtoTmapping(e),t)}getPathData(){return this.getPathCommands().map(e=>{switch(e.type){case"M":return`M ${e.x} ${e.y}`;case"L":return`L ${e.x} ${e.y}`;case"C":return`C ${e.x1} ${e.y1} ${e.x2} ${e.y2} ${e.x} ${e.y}`;case"Q":return`Q ${e.x1} ${e.y1} ${e.x} ${e.y}`;case"A":return`A ${e.rx} ${e.ry} ${e.xAxisRotation} ${e.largeArcFlag} ${e.sweepFlag} ${e.x} ${e.y}`;case"Z":return"Z";default:return""}}).join(" ")}clone(){return new this.constructor().copy(this)}copy(e){return this.arcLengthDivisions=e.arcLengthDivisions,this}}class L extends x{constructor(e,t,s=0,n=Math.PI*2){super(),this.center=e,this.radius=t,this.start=s,this.end=n}getMinMax(e=r.MAX,t=r.MIN){return e.x=Math.min(e.x,this.center.x-this.radius),e.y=Math.min(e.y,this.center.y-this.radius),t.x=Math.max(t.x,this.center.x+this.radius),t.y=Math.max(t.y,this.center.y+this.radius),{min:e,max:t}}getPoint(e){const{radius:t,center:s}=this;return s.clone().add(this.getNormal(e).clone().multiplyScalar(t))}getTangent(e){const{x:t,y:s}=this.getNormal(e);return new r(-s,t)}getNormal(e){const{start:t,end:s}=this,n=e*(s-t)+t-.5*Math.PI;return new r(Math.cos(n),Math.sin(n))}getPathCommands(){return[]}drawTo(e){}}function m(c,e,t,s,n){const i=(s-e)*.5,h=(n-t)*.5,o=c*c,a=c*o;return(2*t-2*s+i+h)*a+(-3*t+3*s-2*i-h)*o+i*c+t}function D(c,e){const t=1-c;return t*t*e}function X(c,e){return 2*(1-c)*c*e}function E(c,e){return c*c*e}function I(c,e,t,s){return D(c,e)+X(c,t)+E(c,s)}function k(c,e){const t=1-c;return t*t*t*e}function F(c,e){const t=1-c;return 3*t*t*c*e}function Q(c,e){return 3*(1-c)*c*c*e}function U(c,e){return c*c*c*e}function z(c,e,t,s,n){return k(c,e)+F(c,t)+Q(c,s)+U(c,n)}class R extends x{constructor(e=new r,t=new r,s=new r,n=new r){super(),this.v0=e,this.v1=t,this.v2=s,this.v3=n}getPoint(e,t=new r){const{v0:s,v1:n,v2:i,v3:h}=this;return t.set(z(e,s.x,n.x,i.x,h.x),z(e,s.y,n.y,i.y,h.y)),t}getMinMax(e=r.MAX,t=r.MIN){const{v0:s,v1:n,v2:i,v3:h}=this;return e.x=Math.min(e.x,s.x,n.x,i.x,h.x),e.y=Math.min(e.y,s.y,n.y,i.y,h.y),t.x=Math.max(t.x,s.x,n.x,i.x,h.x),t.y=Math.max(t.y,s.y,n.y,i.y,h.y),{min:e,max:t}}getPathCommands(){const{v0:e,v1:t,v2:s,v3:n}=this;return[{type:"M",x:e.x,y:e.y},{type:"C",x1:t.x,y1:t.y,x2:s.x,y2:s.y,x:n.x,y:n.y}]}drawTo(e){const{v0:t,v1:s,v2:n,v3:i}=this;e.moveTo(t.x,t.y),e.bezierCurveTo(s.x,s.y,n.x,n.y,i.x,i.y)}copy(e){return super.copy(e),this.v0.copy(e.v0),this.v1.copy(e.v1),this.v2.copy(e.v2),this.v3.copy(e.v3),this}}class S extends x{constructor(e=0,t=0,s=1,n=1,i=0,h=Math.PI*2,o=!1,a=0){super(),this.x=e,this.y=t,this.rx=s,this.ry=n,this.startAngle=i,this.endAngle=h,this.clockwise=o,this.rotation=a}getDivisions(e=12){return e*2}getPoint(e,t=new r){const s=Math.PI*2;let n=this.endAngle-this.startAngle;const i=Math.abs(n)<Number.EPSILON;for(;n<0;)n+=s;for(;n>s;)n-=s;n<Number.EPSILON&&(i?n=0:n=s),this.clockwise&&!i&&(n===s?n=-s:n=n-s);const h=this.startAngle+e*n;let o=this.x+this.rx*Math.cos(h),a=this.y+this.ry*Math.sin(h);if(this.rotation!==0){const u=Math.cos(this.rotation),l=Math.sin(this.rotation),y=o-this.x,v=a-this.y;o=y*u-v*l+this.x,a=y*l+v*u+this.y}return t.set(o,a)}getPathCommands(){const{x:e,y:t,rx:s,ry:n,startAngle:i,endAngle:h,clockwise:o}=this,a=!o,u=e+s*Math.cos(i),l=t+n*Math.sin(i),y=e+s*Math.cos(h),v=t+n*Math.sin(h),M=Math.abs(i-h),d=M>Math.PI?1:0,P=a?0:1,w=e+s*Math.cos(i+(h-i)/2),T=t+n*Math.sin(i+(h-i)/2);return M>=2*Math.PI?[{type:"M",x:u,y:l},{type:"A",rx:s,ry:n,xAxisRotation:0,largeArcFlag:1,sweepFlag:P,x:w,y:T},{type:"A",rx:s,ry:n,xAxisRotation:0,largeArcFlag:1,sweepFlag:P,x:u,y:l}]:[{type:"M",x:u,y:l},{type:"A",rx:s,ry:n,xAxisRotation:0,largeArcFlag:d,sweepFlag:P,x:y,y:v}]}drawTo(e){const{x:t,y:s,rx:n,ry:i,startAngle:h}=this,o=t+n*Math.cos(h),a=s+i*Math.sin(h);e.moveTo(o,a),e.arc(this.x,this.y,this.rx,this.startAngle,this.endAngle,!this.clockwise)}copy(e){return super.copy(e),this.x=e.x,this.y=e.y,this.rx=e.rx,this.ry=e.ry,this.startAngle=e.startAngle,this.endAngle=e.endAngle,this.clockwise=e.clockwise,this.rotation=e.rotation,this}}class f extends x{constructor(e=new r,t=new r){super(),this.v1=e,this.v2=t}getDivisions(){return 1}getPoint(e,t=new r){return e===1?t.copy(this.v2):(t.copy(this.v2).sub(this.v1),t.multiplyScalar(e).add(this.v1)),t}getPointAt(e,t=new r){return this.getPoint(e,t)}getTangent(e,t=new r){return t.subVectors(this.v2,this.v1).normalize()}getTangentAt(e,t=new r){return this.getTangent(e,t)}getPathCommands(){const{v1:e,v2:t}=this;return[{type:"M",x:e.x,y:e.y},{type:"L",x:t.x,y:t.y}]}getMinMax(e=r.MAX,t=r.MIN){const{v1:s,v2:n}=this;return e.x=Math.min(e.x,s.x,n.x),e.y=Math.min(e.y,s.y,n.y),t.x=Math.max(t.x,s.x,n.x),t.y=Math.max(t.y,s.y,n.y),{min:e,max:t}}drawTo(e){const{v1:t,v2:s}=this;e.moveTo(t.x,t.y),e.lineTo(s.x,s.y)}copy(e){return super.copy(e),this.v1.copy(e.v1),this.v2.copy(e.v2),this}}class V extends x{constructor(t,s,n=0,i=1){super();p(this,"curves");p(this,"pointT",0);this.center=t,this.size=s,this.start=n,this.end=i;const{x:h,y:o}=this.center,a=new r(h+.5*this.size,o-.5*this.size),u=new r(h-.5*this.size,o-.5*this.size),l=new r(h,o+.5*this.size),y=new L(a,Math.SQRT1_2*this.size,-.25*Math.PI,.75*Math.PI),v=new L(u,Math.SQRT1_2*this.size,-.75*Math.PI,.25*Math.PI),M=new L(l,.5*Math.SQRT1_2*this.size,.75*Math.PI,1.25*Math.PI),d=new r(h,o+this.size),P=new r(h+this.size,o),w=new r().lerpVectors(P,d,.75),T=new r(h-this.size,o),$=new r().lerpVectors(T,d,.75),C=new f(P,w),_=new f($,T);this.curves=[y,C,M,_,v]}getPoint(t){return this.getCurrentLine(t).getPoint(this.pointT)}getPointAt(t){return this.getPoint(t)}getCurrentLine(t){let s=(t*(this.end-this.start)+this.start)%1;s<0&&(s+=1),s*=9*Math.PI/8+1.5;let n;const i=.5*Math.PI;return s<i?(n=0,this.pointT=s/i):s<i+.75?(n=1,this.pointT=(s-i)/.75):s<5*Math.PI/8+.75?(n=2,this.pointT=(s-i-.75)/(Math.PI/8)):s<5*Math.PI/8+1.5?(n=3,this.pointT=(s-5*Math.PI/8-.75)/.75):(n=4,this.pointT=(s-5*Math.PI/8-1.5)/i),this.curves[n]}getTangent(t){return this.getCurrentLine(t).getTangent(this.pointT).normalize()}getNormal(t){const s=this.getCurrentLine(t);return new r(s.v2.y-s.v1.y,-(s.v2.x-s.v1.x)).normalize()}getPathCommands(){return this.curves.flatMap(t=>t.getPathCommands())}drawTo(t){this.curves.forEach(s=>s.drawTo(t))}}class Y extends x{constructor(t,s=0,n=0,i=0,h=1){super();p(this,"curves",[]);p(this,"points",[]);this.center=t,this.radius=s,this.num=n,this.start=i,this.end=h;for(let o=0;o<this.num;o++){let a=o*2*Math.PI/this.num;a-=.5*Math.PI;const u=new r(this.radius*Math.cos(a),this.radius*Math.sin(a));u.add(this.center),this.points.push(u)}for(let o=0;o<this.num;o++)this.curves.push(new f(this.points[o],this.points[(o+1)%this.num]))}getPoint(t){return this.getCurrentLine(t),this.currentLine.getPoint(this.pointK)}getPointAt(t){return this.getPoint(t)}getCurrentLine(t){let s=(t*(this.end-this.start)+this.start)%1;s<0&&(s+=1);const n=s*this.num,i=Math.floor(n);return this.pointK=n-i,this.currentLine=this.curves[i],this.currentLine}getTangent(t){return this.getCurrentLine(t).getTangent(0).normalize()}getNormal(t){const s=this.getCurrentLine(t);return new r(s.v2.y-s.v1.y,-(s.v2.x-s.v1.x)).normalize()}getPathCommands(){return this.curves.flatMap(t=>t.getPathCommands())}getMinMax(t=r.MAX,s=r.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}drawTo(t){this.curves.forEach(s=>s.drawTo(t))}}class B extends x{constructor(e=new r,t=new r,s=new r){super(),this.v0=e,this.v1=t,this.v2=s}getPoint(e,t=new r){const{v0:s,v1:n,v2:i}=this;return t.set(I(e,s.x,n.x,i.x),I(e,s.y,n.y,i.y)),t}getPathCommands(){const{v0:e,v1:t,v2:s}=this;return[{type:"M",x:e.x,y:e.y},{type:"Q",x1:t.x,y1:t.y,x:s.x,y:s.y}]}getMinMax(e=r.MAX,t=r.MIN){const{v0:s,v1:n,v2:i}=this,h=.5*(s.x+n.x),o=.5*(s.y+n.y),a=.5*(s.x+i.x),u=.5*(s.y+i.y);return e.x=Math.min(e.x,s.x,i.x,h,a),e.y=Math.min(e.y,s.y,i.y,o,u),t.x=Math.max(t.x,s.x,i.x,h,a),t.y=Math.max(t.y,s.y,i.y,o,u),{min:e,max:t}}drawTo(e){const{v0:t,v1:s,v2:n}=this;e.moveTo(t.x,t.y),e.quadraticCurveTo(s.x,s.y,n.x,n.y)}copy(e){return super.copy(e),this.v0.copy(e.v0),this.v1.copy(e.v1),this.v2.copy(e.v2),this}}class q extends x{constructor(t,s,n=1,i=0,h=1){super();p(this,"curves",[]);p(this,"pointT",0);this.center=t,this.rx=s,this.aspectRatio=n,this.start=i,this.end=h;const{x:o,y:a}=this.center,u=this.rx,l=this.rx/this.aspectRatio,y=[new r(o-u,a-l),new r(o+u,a-l),new r(o+u,a+l),new r(o-u,a+l)];for(let v=0;v<4;v++)this.curves.push(new f(y[v],y[(v+1)%4]))}get x(){return this.center.x-this.rx}get y(){return this.center.y-this.rx/this.aspectRatio}get width(){return this.rx*2}get height(){return this.rx/this.aspectRatio*2}getPoint(t){return this.getCurrentLine(t).getPoint(this.pointT)}getPointAt(t){return this.getPoint(t)}getCurrentLine(t){let s=(t*(this.end-this.start)+this.start)%1;s<0&&(s+=1),s*=(1+this.aspectRatio)*2;let n;return s<this.aspectRatio?(n=0,this.pointT=s/this.aspectRatio):s<this.aspectRatio+1?(n=1,this.pointT=(s-this.aspectRatio)/1):s<2*this.aspectRatio+1?(n=2,this.pointT=(s-this.aspectRatio-1)/this.aspectRatio):(n=3,this.pointT=(s-2*this.aspectRatio-1)/1),this.curves[n]}getTangent(t){return this.getCurrentLine(t).getTangent(0).normalize()}getNormal(t){const{v1:s,v2:n}=this.getCurrentLine(t);return new r(n.y-s.y,-(n.x-s.x)).normalize()}getPathCommands(){return this.curves.flatMap(t=>t.getPathCommands())}getMinMax(t=r.MAX,s=r.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}drawTo(t){this.curves.forEach(s=>s.drawTo(t))}}class N extends x{constructor(e=[]){super(),this.points=e}getDivisions(e=12){return e*this.points.length}getPoint(e,t=new r){const{points:s}=this,n=(s.length-1)*e,i=Math.floor(n),h=n-i,o=s[i===0?i:i-1],a=s[i],u=s[i>s.length-2?s.length-1:i+1],l=s[i>s.length-3?s.length-1:i+2];return t.set(m(h,o.x,a.x,u.x,l.x),m(h,o.y,a.y,u.y,l.y)),t}getPathCommands(){return[]}drawTo(e){}copy(e){super.copy(e),this.points=[];for(let t=0,s=e.points.length;t<s;t++)this.points.push(e.points[t].clone());return this}}class b extends x{constructor(t){super();p(this,"curves",[]);p(this,"currentPoint",new r);p(this,"autoClose",!1);p(this,"_cacheLengths",[]);t&&this.setFromPoints(t)}addCurve(t){return this.curves.push(t),this}closePath(){const t=this.curves[0].getPoint(0),s=this.curves[this.curves.length-1].getPoint(1);return t.equals(s)||this.curves.push(new f(s,t)),this}getPoint(t,s=new r){const n=t*this.getLength(),i=this.getCurveLengths();let h=0;for(;h<i.length;){if(i[h]>=n){const o=i[h]-n,a=this.curves[h],u=a.getLength();return a.getPointAt(u===0?0:1-o/u,s)}h++}return s}getLength(){const t=this.getCurveLengths();return t[t.length-1]}updateArcLengths(){super.updateArcLengths(),this._cacheLengths=[],this.getCurveLengths()}getCurveLengths(){if(this._cacheLengths.length===this.curves.length)return this._cacheLengths;const t=[];let s=0;for(let n=0,i=this.curves.length;n<i;n++)s+=this.curves[n].getLength(),t.push(s);return this._cacheLengths=t,t}getSpacedPoints(t=40){const s=[];for(let n=0;n<=t;n++)s.push(this.getPoint(n/t));return this.autoClose&&s.push(s[0]),s}getPoints(t=12){const s=[];let n;for(let i=0,h=this.curves;i<h.length;i++){const o=h[i],a=o.getPoints(o.getDivisions(t));for(let u=0;u<a.length;u++){const l=a[u];n&&n.equals(l)||(s.push(l),n=l)}}return this.autoClose&&s.length>1&&!s[s.length-1].equals(s[0])&&s.push(s[0]),s}setFromPoints(t){this.moveTo(t[0].x,t[0].y);for(let s=1,n=t.length;s<n;s++)this.lineTo(t[s].x,t[s].y);return this}bezierCurveTo(t,s,n,i,h,o){return this.curves.push(new R(this.currentPoint.clone(),new r(t,s),new r(n,i),new r(h,o))),this.currentPoint.set(h,o),this}lineTo(t,s){const n=new f(this.currentPoint.clone(),new r(t,s));return this.curves.push(n),this.currentPoint.set(t,s),this}moveTo(t,s){return this.currentPoint.set(t,s),this}quadraticCurveTo(t,s,n,i){return this.curves.push(new B(this.currentPoint.clone(),new r(t,s),new r(n,i))),this.currentPoint.set(n,i),this}rect(t,s,n,i){return this.curves.push(new q(new r(t+n/2,s+i/2),n/2,n/i)),this.currentPoint.set(t,s),this}splineThru(t){const s=[this.currentPoint.clone()].concat(t);return this.curves.push(new N(s)),this.currentPoint.copy(t[t.length-1]),this}arc(t,s,n,i,h,o=!1){const a=this.currentPoint;return this.absarc(t+a.x,s+a.y,n,i,h,o),this}absarc(t,s,n,i,h,o=!1){return this.absellipse(t,s,n,n,i,h,o),this}ellipse(t,s,n,i,h,o,a=!1,u=0){const l=this.currentPoint;return this.absellipse(t+l.x,s+l.y,n,i,h,o,a,u),this}absellipse(t,s,n,i,h,o,a=!1,u=0){const l=new S(t,s,n,i,h,o,a,u);if(this.curves.length>0){const y=l.getPoint(0);y.equals(this.currentPoint)||this.lineTo(y.x,y.y)}return this.curves.push(l),this.currentPoint.copy(l.getPoint(1)),this}getPathCommands(){return this.curves.flatMap(t=>t.getPathCommands())}getMinMax(t=r.MAX,s=r.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}drawTo(t){this.curves.forEach(s=>s.drawTo(t))}copy(t){super.copy(t),this.curves=[];for(let s=0,n=t.curves.length;s<n;s++){const i=t.curves[s];this.curves.push(i.clone())}return this.autoClose=t.autoClose,this.currentPoint.copy(t.currentPoint),this}}class j{constructor(){p(this,"currentPath",new b);p(this,"paths",[this.currentPath])}addPath(e){return this.paths.push(...e.paths.map(t=>t.clone())),this}closePath(){return this.currentPath.closePath(),this}moveTo(e,t){return this.currentPath=new b,this.paths.push(this.currentPath),this.currentPath.moveTo(e,t),this}lineTo(e,t){return this.currentPath.lineTo(e,t),this}bezierCurveTo(e,t,s,n,i,h){return this.currentPath.bezierCurveTo(e,t,s,n,i,h),this}quadraticCurveTo(e,t,s,n){return this.currentPath.quadraticCurveTo(e,t,s,n),this}arc(e,t,s,n,i,h){return this.currentPath.absarc(e,t,s,n,i,!h),this}arcTo(e,t,s,n,i){const h=this.currentPath.currentPoint,o=h.x,a=h.y,u=e-o,l=t-a,y=s-e,v=n-t,M=Math.sqrt(u*u+l*l),d=Math.sqrt(y*y+v*v);if(M<i||d<i)return this.lineTo(s,n),this;const P={x:u/M,y:l/M},w={x:y/d,y:v/d},T=e-P.y*i,$=t+P.x*i,C=Math.atan2(P.y,P.x);let A=Math.atan2(w.y,w.x)-C;return A>Math.PI?A-=2*Math.PI:A<-Math.PI&&(A+=2*Math.PI),this.arc(T,$,i,C,C+A,!1),this.lineTo(s,n),this}ellipse(e,t,s,n,i,h,o,a){return this.currentPath.absellipse(e,t,s,n,h,o,!a,i),this}rect(e,t,s,n){return this.currentPath.rect(e,t,s,n),this}splineThru(e){return this.currentPath.splineThru(e),this}getMinMax(e=new r,t=new r){return this.paths.forEach(s=>s.curves.forEach(n=>n.getMinMax(e,t))),{min:e,max:t}}getPathCommands(){return this.paths.flatMap(e=>e.curves.flatMap(t=>t.getPathCommands()))}getPathData(){return this.paths.map(e=>e.getPathData()).join(" ")}getBoundingBox(){const e=r.MAX,t=r.MIN;return this.paths.forEach(s=>s.getMinMax(e,t)),{x:e.x,y:e.y,width:t.x-e.x,height:t.y-e.y}}getSvgString(){const{x:e,y:t,width:s,height:n}=this.getBoundingBox();return`<svg viewBox="${e} ${t} ${s} ${n}" xmlns="http://www.w3.org/2000/svg"><path fill="none" stroke="currentColor" d="${this.getPathData()}"></path></svg>`}getSvgDataUri(){return`data:image/svg+xml;base64,${btoa(this.getSvgString())}`}drawTo(e){this.paths.forEach(t=>{t.curves.forEach(s=>{s.drawTo(e)})})}strokeTo(e){this.drawTo(e),e.stroke()}fillTo(e){this.drawTo(e),e.fill()}}g.CircleCurve=L,g.CubicBezierCurve=R,g.Curve=x,g.CurvePath=b,g.EllipseCurve=S,g.HeartCurve=V,g.LineCurve=f,g.Path2D=j,g.PloygonCurve=Y,g.Point2D=r,g.QuadraticBezierCurve=B,g.RectangularCurve=q,g.SplineCurve=N,g.catmullRom=m,g.cubicBezier=z,g.quadraticBezier=I,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"})});
1
+ (function(g,r){typeof exports=="object"&&typeof module<"u"?r(exports):typeof define=="function"&&define.amd?define(["exports"],r):(g=typeof globalThis<"u"?globalThis:g||self,r(g.modernPath2d={}))})(this,function(g){"use strict";var j=Object.defineProperty;var Z=(g,r,x)=>r in g?j(g,r,{enumerable:!0,configurable:!0,writable:!0,value:x}):g[r]=x;var p=(g,r,x)=>Z(g,typeof r!="symbol"?r+"":r,x);class r{constructor(e=0,t=0){this.x=e,this.y=t}static get MAX(){return new r(1/0,1/0)}static get MIN(){return new r(-1/0,-1/0)}set(e,t){return this.x=e,this.y=t,this}add(e){return this.x+=e.x,this.y+=e.y,this}sub(e){return this.x-=e.x,this.y-=e.y,this}distanceTo(e){return Math.sqrt(this.distanceToSquared(e))}distanceToSquared(e){const t=this.x-e.x,s=this.y-e.y;return t*t+s*s}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}multiplyScalar(e){return this.x*=e,this.y*=e,this}divideScalar(e){return this.multiplyScalar(1/e)}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this}normalize(){return this.divideScalar(this.length()||1)}lerpVectors(e,t,s){return this.x=e.x+(t.x-e.x)*s,this.y=e.y+(t.y-e.y)*s,this}equals(e){return this.x===e.x&&this.y===e.y}copy(e){return this.x=e.x,this.y=e.y,this}clone(){return new r(this.x,this.y)}}class x{constructor(){p(this,"arcLengthDivisions",200);p(this,"_cacheArcLengths");p(this,"_needsUpdate",!1)}getMinMax(e=r.MAX,t=r.MIN){return{min:e,max:t}}getDivisions(e){return e}getPointAt(e,t=new r){return this.getPoint(this.getUtoTmapping(e),t)}getPoints(e=5){const t=[];for(let s=0;s<=e;s++)t.push(this.getPoint(s/e));return t}getSpacedPoints(e=5){const t=[];for(let s=0;s<=e;s++)t.push(this.getPointAt(s/e));return t}getLength(){const e=this.getLengths();return e[e.length-1]}getLengths(e=this.arcLengthDivisions){if(this._cacheArcLengths&&this._cacheArcLengths.length===e+1&&!this._needsUpdate)return this._cacheArcLengths;this._needsUpdate=!1;const t=[];let s,n=this.getPoint(0),i=0;t.push(0);for(let h=1;h<=e;h++)s=this.getPoint(h/e),i+=s.distanceTo(n),t.push(i),n=s;return this._cacheArcLengths=t,t}updateArcLengths(){this._needsUpdate=!0,this.getLengths()}getUtoTmapping(e,t){const s=this.getLengths();let n=0;const i=s.length;let h;t?h=t:h=e*s[i-1];let o=0,a=i-1,u;for(;o<=a;)if(n=Math.floor(o+(a-o)/2),u=s[n]-h,u<0)o=n+1;else if(u>0)a=n-1;else{a=n;break}if(n=a,s[n]===h)return n/(i-1);const l=s[n],v=s[n+1]-l,M=(h-l)/v;return(n+M)/(i-1)}getTangent(e,t=new r){let n=e-1e-4,i=e+1e-4;return n<0&&(n=0),i>1&&(i=1),t.copy(this.getPoint(i)).sub(this.getPoint(n)).normalize()}getTangentAt(e,t=new r){return this.getTangent(this.getUtoTmapping(e),t)}getData(){return this.getCommands().map(e=>{switch(e.type){case"M":return`M ${e.x} ${e.y}`;case"L":return`L ${e.x} ${e.y}`;case"C":return`C ${e.x1} ${e.y1} ${e.x2} ${e.y2} ${e.x} ${e.y}`;case"Q":return`Q ${e.x1} ${e.y1} ${e.x} ${e.y}`;case"A":return`A ${e.rx} ${e.ry} ${e.xAxisRotation} ${e.largeArcFlag} ${e.sweepFlag} ${e.x} ${e.y}`;case"Z":return"Z";default:return""}}).join(" ")}clone(){return new this.constructor().copy(this)}copy(e){return this.arcLengthDivisions=e.arcLengthDivisions,this}}class m extends x{constructor(e,t,s=0,n=Math.PI*2){super(),this.center=e,this.radius=t,this.start=s,this.end=n}getMinMax(e=r.MAX,t=r.MIN){return e.x=Math.min(e.x,this.center.x-this.radius),e.y=Math.min(e.y,this.center.y-this.radius),t.x=Math.max(t.x,this.center.x+this.radius),t.y=Math.max(t.y,this.center.y+this.radius),{min:e,max:t}}getPoint(e){const{radius:t,center:s}=this;return s.clone().add(this.getNormal(e).clone().multiplyScalar(t))}getTangent(e){const{x:t,y:s}=this.getNormal(e);return new r(-s,t)}getNormal(e){const{start:t,end:s}=this,n=e*(s-t)+t-.5*Math.PI;return new r(Math.cos(n),Math.sin(n))}getCommands(){return[]}drawTo(e){}}function L(c,e,t,s,n){const i=(s-e)*.5,h=(n-t)*.5,o=c*c,a=c*o;return(2*t-2*s+i+h)*a+(-3*t+3*s-2*i-h)*o+i*c+t}function _(c,e){const t=1-c;return t*t*e}function X(c,e){return 2*(1-c)*c*e}function E(c,e){return c*c*e}function z(c,e,t,s){return _(c,e)+X(c,t)+E(c,s)}function F(c,e){const t=1-c;return t*t*t*e}function Q(c,e){const t=1-c;return 3*t*t*c*e}function U(c,e){return 3*(1-c)*c*c*e}function V(c,e){return c*c*c*e}function I(c,e,t,s,n){return F(c,e)+Q(c,t)+U(c,s)+V(c,n)}class S extends x{constructor(e=new r,t=new r,s=new r,n=new r){super(),this.v0=e,this.v1=t,this.v2=s,this.v3=n}getPoint(e,t=new r){const{v0:s,v1:n,v2:i,v3:h}=this;return t.set(I(e,s.x,n.x,i.x,h.x),I(e,s.y,n.y,i.y,h.y)),t}getMinMax(e=r.MAX,t=r.MIN){const{v0:s,v1:n,v2:i,v3:h}=this;return e.x=Math.min(e.x,s.x,n.x,i.x,h.x),e.y=Math.min(e.y,s.y,n.y,i.y,h.y),t.x=Math.max(t.x,s.x,n.x,i.x,h.x),t.y=Math.max(t.y,s.y,n.y,i.y,h.y),{min:e,max:t}}getCommands(){const{v0:e,v1:t,v2:s,v3:n}=this;return[{type:"M",x:e.x,y:e.y},{type:"C",x1:t.x,y1:t.y,x2:s.x,y2:s.y,x:n.x,y:n.y}]}drawTo(e){const{v0:t,v1:s,v2:n,v3:i}=this;e.moveTo(t.x,t.y),e.bezierCurveTo(s.x,s.y,n.x,n.y,i.x,i.y)}copy(e){return super.copy(e),this.v0.copy(e.v0),this.v1.copy(e.v1),this.v2.copy(e.v2),this.v3.copy(e.v3),this}}class q extends x{constructor(e=0,t=0,s=1,n=1,i=0,h=Math.PI*2,o=!1,a=0){super(),this.x=e,this.y=t,this.rx=s,this.ry=n,this.startAngle=i,this.endAngle=h,this.clockwise=o,this.rotation=a}getDivisions(e=12){return e*2}getPoint(e,t=new r){const s=Math.PI*2;let n=this.endAngle-this.startAngle;const i=Math.abs(n)<Number.EPSILON;for(;n<0;)n+=s;for(;n>s;)n-=s;n<Number.EPSILON&&(i?n=0:n=s),this.clockwise&&!i&&(n===s?n=-s:n=n-s);const h=this.startAngle+e*n;let o=this.x+this.rx*Math.cos(h),a=this.y+this.ry*Math.sin(h);if(this.rotation!==0){const u=Math.cos(this.rotation),l=Math.sin(this.rotation),y=o-this.x,v=a-this.y;o=y*u-v*l+this.x,a=y*l+v*u+this.y}return t.set(o,a)}getCommands(){const{x:e,y:t,rx:s,ry:n,startAngle:i,endAngle:h,clockwise:o}=this,a=!o,u=e+s*Math.cos(i),l=t+n*Math.sin(i),y=e+s*Math.cos(h),v=t+n*Math.sin(h),M=Math.abs(i-h),f=M>Math.PI?1:0,d=a?0:1,w=e+s*Math.cos(i+(h-i)/2),T=t+n*Math.sin(i+(h-i)/2);return M>=2*Math.PI?[{type:"M",x:u,y:l},{type:"A",rx:s,ry:n,xAxisRotation:0,largeArcFlag:1,sweepFlag:d,x:w,y:T},{type:"A",rx:s,ry:n,xAxisRotation:0,largeArcFlag:1,sweepFlag:d,x:u,y:l}]:[{type:"M",x:u,y:l},{type:"A",rx:s,ry:n,xAxisRotation:0,largeArcFlag:f,sweepFlag:d,x:y,y:v}]}drawTo(e){const{x:t,y:s,rx:n,ry:i,startAngle:h}=this,o=t+n*Math.cos(h),a=s+i*Math.sin(h);e.moveTo(o,a),e.arc(this.x,this.y,this.rx,this.startAngle,this.endAngle,!this.clockwise)}copy(e){return super.copy(e),this.x=e.x,this.y=e.y,this.rx=e.rx,this.ry=e.ry,this.startAngle=e.startAngle,this.endAngle=e.endAngle,this.clockwise=e.clockwise,this.rotation=e.rotation,this}}class P extends x{constructor(e=new r,t=new r){super(),this.v1=e,this.v2=t}getDivisions(){return 1}getPoint(e,t=new r){return e===1?t.copy(this.v2):(t.copy(this.v2).sub(this.v1),t.multiplyScalar(e).add(this.v1)),t}getPointAt(e,t=new r){return this.getPoint(e,t)}getTangent(e,t=new r){return t.subVectors(this.v2,this.v1).normalize()}getTangentAt(e,t=new r){return this.getTangent(e,t)}getCommands(){const{v1:e,v2:t}=this;return[{type:"M",x:e.x,y:e.y},{type:"L",x:t.x,y:t.y}]}getMinMax(e=r.MAX,t=r.MIN){const{v1:s,v2:n}=this;return e.x=Math.min(e.x,s.x,n.x),e.y=Math.min(e.y,s.y,n.y),t.x=Math.max(t.x,s.x,n.x),t.y=Math.max(t.y,s.y,n.y),{min:e,max:t}}drawTo(e){const{v1:t,v2:s}=this;e.moveTo(t.x,t.y),e.lineTo(s.x,s.y)}copy(e){return super.copy(e),this.v1.copy(e.v1),this.v2.copy(e.v2),this}}class Y extends x{constructor(t,s,n=0,i=1){super();p(this,"curves");p(this,"pointT",0);this.center=t,this.size=s,this.start=n,this.end=i;const{x:h,y:o}=this.center,a=new r(h+.5*this.size,o-.5*this.size),u=new r(h-.5*this.size,o-.5*this.size),l=new r(h,o+.5*this.size),y=new m(a,Math.SQRT1_2*this.size,-.25*Math.PI,.75*Math.PI),v=new m(u,Math.SQRT1_2*this.size,-.75*Math.PI,.25*Math.PI),M=new m(l,.5*Math.SQRT1_2*this.size,.75*Math.PI,1.25*Math.PI),f=new r(h,o+this.size),d=new r(h+this.size,o),w=new r().lerpVectors(d,f,.75),T=new r(h-this.size,o),R=new r().lerpVectors(T,f,.75),C=new P(d,w),D=new P(R,T);this.curves=[y,C,M,D,v]}getPoint(t){return this.getCurrentLine(t).getPoint(this.pointT)}getPointAt(t){return this.getPoint(t)}getCurrentLine(t){let s=(t*(this.end-this.start)+this.start)%1;s<0&&(s+=1),s*=9*Math.PI/8+1.5;let n;const i=.5*Math.PI;return s<i?(n=0,this.pointT=s/i):s<i+.75?(n=1,this.pointT=(s-i)/.75):s<5*Math.PI/8+.75?(n=2,this.pointT=(s-i-.75)/(Math.PI/8)):s<5*Math.PI/8+1.5?(n=3,this.pointT=(s-5*Math.PI/8-.75)/.75):(n=4,this.pointT=(s-5*Math.PI/8-1.5)/i),this.curves[n]}getTangent(t){return this.getCurrentLine(t).getTangent(this.pointT).normalize()}getNormal(t){const s=this.getCurrentLine(t);return new r(s.v2.y-s.v1.y,-(s.v2.x-s.v1.x)).normalize()}getCommands(){return this.curves.flatMap(t=>t.getCommands())}drawTo(t){this.curves.forEach(s=>s.drawTo(t))}}class O extends x{constructor(t,s=0,n=0,i=0,h=1){super();p(this,"curves",[]);p(this,"points",[]);this.center=t,this.radius=s,this.num=n,this.start=i,this.end=h;for(let o=0;o<this.num;o++){let a=o*2*Math.PI/this.num;a-=.5*Math.PI;const u=new r(this.radius*Math.cos(a),this.radius*Math.sin(a));u.add(this.center),this.points.push(u)}for(let o=0;o<this.num;o++)this.curves.push(new P(this.points[o],this.points[(o+1)%this.num]))}getPoint(t){return this.getCurrentLine(t),this.currentLine.getPoint(this.pointK)}getPointAt(t){return this.getPoint(t)}getCurrentLine(t){let s=(t*(this.end-this.start)+this.start)%1;s<0&&(s+=1);const n=s*this.num,i=Math.floor(n);return this.pointK=n-i,this.currentLine=this.curves[i],this.currentLine}getTangent(t){return this.getCurrentLine(t).getTangent(0).normalize()}getNormal(t){const s=this.getCurrentLine(t);return new r(s.v2.y-s.v1.y,-(s.v2.x-s.v1.x)).normalize()}getCommands(){return this.curves.flatMap(t=>t.getCommands())}getMinMax(t=r.MAX,s=r.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}drawTo(t){this.curves.forEach(s=>s.drawTo(t))}}class B extends x{constructor(e=new r,t=new r,s=new r){super(),this.v0=e,this.v1=t,this.v2=s}getPoint(e,t=new r){const{v0:s,v1:n,v2:i}=this;return t.set(z(e,s.x,n.x,i.x),z(e,s.y,n.y,i.y)),t}getCommands(){const{v0:e,v1:t,v2:s}=this;return[{type:"M",x:e.x,y:e.y},{type:"Q",x1:t.x,y1:t.y,x:s.x,y:s.y}]}getMinMax(e=r.MAX,t=r.MIN){const{v0:s,v1:n,v2:i}=this,h=.5*(s.x+n.x),o=.5*(s.y+n.y),a=.5*(s.x+i.x),u=.5*(s.y+i.y);return e.x=Math.min(e.x,s.x,i.x,h,a),e.y=Math.min(e.y,s.y,i.y,o,u),t.x=Math.max(t.x,s.x,i.x,h,a),t.y=Math.max(t.y,s.y,i.y,o,u),{min:e,max:t}}drawTo(e){const{v0:t,v1:s,v2:n}=this;e.moveTo(t.x,t.y),e.quadraticCurveTo(s.x,s.y,n.x,n.y)}copy(e){return super.copy(e),this.v0.copy(e.v0),this.v1.copy(e.v1),this.v2.copy(e.v2),this}}class k extends x{constructor(t,s,n=1,i=0,h=1){super();p(this,"curves",[]);p(this,"pointT",0);this.center=t,this.rx=s,this.aspectRatio=n,this.start=i,this.end=h;const{x:o,y:a}=this.center,u=this.rx,l=this.rx/this.aspectRatio,y=[new r(o-u,a-l),new r(o+u,a-l),new r(o+u,a+l),new r(o-u,a+l)];for(let v=0;v<4;v++)this.curves.push(new P(y[v],y[(v+1)%4]))}get x(){return this.center.x-this.rx}get y(){return this.center.y-this.rx/this.aspectRatio}get width(){return this.rx*2}get height(){return this.rx/this.aspectRatio*2}getPoint(t){return this.getCurrentLine(t).getPoint(this.pointT)}getPointAt(t){return this.getPoint(t)}getCurrentLine(t){let s=(t*(this.end-this.start)+this.start)%1;s<0&&(s+=1),s*=(1+this.aspectRatio)*2;let n;return s<this.aspectRatio?(n=0,this.pointT=s/this.aspectRatio):s<this.aspectRatio+1?(n=1,this.pointT=(s-this.aspectRatio)/1):s<2*this.aspectRatio+1?(n=2,this.pointT=(s-this.aspectRatio-1)/this.aspectRatio):(n=3,this.pointT=(s-2*this.aspectRatio-1)/1),this.curves[n]}getTangent(t){return this.getCurrentLine(t).getTangent(0).normalize()}getNormal(t){const{v1:s,v2:n}=this.getCurrentLine(t);return new r(n.y-s.y,-(n.x-s.x)).normalize()}getCommands(){return this.curves.flatMap(t=>t.getCommands())}getMinMax(t=r.MAX,s=r.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}drawTo(t){this.curves.forEach(s=>s.drawTo(t))}}class N extends x{constructor(e=[]){super(),this.points=e}getDivisions(e=12){return e*this.points.length}getPoint(e,t=new r){const{points:s}=this,n=(s.length-1)*e,i=Math.floor(n),h=n-i,o=s[i===0?i:i-1],a=s[i],u=s[i>s.length-2?s.length-1:i+1],l=s[i>s.length-3?s.length-1:i+2];return t.set(L(h,o.x,a.x,u.x,l.x),L(h,o.y,a.y,u.y,l.y)),t}getCommands(){return[]}drawTo(e){}copy(e){super.copy(e),this.points=[];for(let t=0,s=e.points.length;t<s;t++)this.points.push(e.points[t].clone());return this}}class b extends x{constructor(t){super();p(this,"curves",[]);p(this,"currentPoint",new r);p(this,"autoClose",!1);p(this,"_cacheLengths",[]);t&&this.setFromPoints(t)}addCurve(t){return this.curves.push(t),this}closePath(){const t=this.curves[0].getPoint(0),s=this.curves[this.curves.length-1].getPoint(1);return t.equals(s)||this.curves.push(new P(s,t)),this}getPoint(t,s=new r){const n=t*this.getLength(),i=this.getCurveLengths();let h=0;for(;h<i.length;){if(i[h]>=n){const o=i[h]-n,a=this.curves[h],u=a.getLength();return a.getPointAt(u===0?0:1-o/u,s)}h++}return s}getLength(){const t=this.getCurveLengths();return t[t.length-1]}updateArcLengths(){super.updateArcLengths(),this._cacheLengths=[],this.getCurveLengths()}getCurveLengths(){if(this._cacheLengths.length===this.curves.length)return this._cacheLengths;const t=[];let s=0;for(let n=0,i=this.curves.length;n<i;n++)s+=this.curves[n].getLength(),t.push(s);return this._cacheLengths=t,t}getSpacedPoints(t=40){const s=[];for(let n=0;n<=t;n++)s.push(this.getPoint(n/t));return this.autoClose&&s.push(s[0]),s}getPoints(t=12){const s=[];let n;for(let i=0,h=this.curves;i<h.length;i++){const o=h[i],a=o.getPoints(o.getDivisions(t));for(let u=0;u<a.length;u++){const l=a[u];n&&n.equals(l)||(s.push(l),n=l)}}return this.autoClose&&s.length>1&&!s[s.length-1].equals(s[0])&&s.push(s[0]),s}setFromPoints(t){this.moveTo(t[0].x,t[0].y);for(let s=1,n=t.length;s<n;s++)this.lineTo(t[s].x,t[s].y);return this}bezierCurveTo(t,s,n,i,h,o){return this.curves.push(new S(this.currentPoint.clone(),new r(t,s),new r(n,i),new r(h,o))),this.currentPoint.set(h,o),this}lineTo(t,s){const n=new P(this.currentPoint.clone(),new r(t,s));return this.curves.push(n),this.currentPoint.set(t,s),this}moveTo(t,s){return this.currentPoint.set(t,s),this}quadraticCurveTo(t,s,n,i){return this.curves.push(new B(this.currentPoint.clone(),new r(t,s),new r(n,i))),this.currentPoint.set(n,i),this}rect(t,s,n,i){return this.curves.push(new k(new r(t+n/2,s+i/2),n/2,n/i)),this.currentPoint.set(t,s),this}splineThru(t){const s=[this.currentPoint.clone()].concat(t);return this.curves.push(new N(s)),this.currentPoint.copy(t[t.length-1]),this}arc(t,s,n,i,h,o=!1){const a=this.currentPoint;return this.absarc(t+a.x,s+a.y,n,i,h,o),this}absarc(t,s,n,i,h,o=!1){return this.absellipse(t,s,n,n,i,h,o),this}ellipse(t,s,n,i,h,o,a=!1,u=0){const l=this.currentPoint;return this.absellipse(t+l.x,s+l.y,n,i,h,o,a,u),this}absellipse(t,s,n,i,h,o,a=!1,u=0){const l=new q(t,s,n,i,h,o,a,u);if(this.curves.length>0){const y=l.getPoint(0);y.equals(this.currentPoint)||this.lineTo(y.x,y.y)}return this.curves.push(l),this.currentPoint.copy(l.getPoint(1)),this}getCommands(){return this.curves.flatMap(t=>t.getCommands())}getMinMax(t=r.MAX,s=r.MIN){return this.curves.forEach(n=>n.getMinMax(t,s)),{min:t,max:s}}drawTo(t){this.curves.forEach(s=>s.drawTo(t))}copy(t){super.copy(t),this.curves=[];for(let s=0,n=t.curves.length;s<n;s++){const i=t.curves[s];this.curves.push(i.clone())}return this.autoClose=t.autoClose,this.currentPoint.copy(t.currentPoint),this}}class ${constructor(e){p(this,"currentPath",new b);p(this,"paths",[this.currentPath]);e&&(e instanceof $?this.addPath(e):Array.isArray(e)?this.addCommands(e):this.addData(e))}addPath(e){return this.paths.push(...e.paths.map(t=>t.clone())),this}addCommands(e){for(let t=0,s=e.length;t<s;t++){const n=e[t];switch(n.type){case"M":this.moveTo(n.x,n.y);break;case"L":this.lineTo(n.x,n.y);break;case"C":this.bezierCurveTo(n.x2,n.y2,n.x1,n.y1,n.x,n.y);break;case"Q":this.quadraticCurveTo(n.x1,n.y1,n.x,n.y);break;case"A":break;case"Z":this.closePath();break}}return this}addData(e){return console.error("TODO",e),this}closePath(){return this.currentPath.closePath(),this}moveTo(e,t){return this.currentPath=new b,this.paths.push(this.currentPath),this.currentPath.moveTo(e,t),this}lineTo(e,t){return this.currentPath.lineTo(e,t),this}bezierCurveTo(e,t,s,n,i,h){return this.currentPath.bezierCurveTo(e,t,s,n,i,h),this}quadraticCurveTo(e,t,s,n){return this.currentPath.quadraticCurveTo(e,t,s,n),this}arc(e,t,s,n,i,h){return this.currentPath.absarc(e,t,s,n,i,!h),this}arcTo(e,t,s,n,i){const h=this.currentPath.currentPoint,o=h.x,a=h.y,u=e-o,l=t-a,y=s-e,v=n-t,M=Math.sqrt(u*u+l*l),f=Math.sqrt(y*y+v*v);if(M<i||f<i)return this.lineTo(s,n),this;const d={x:u/M,y:l/M},w={x:y/f,y:v/f},T=e-d.y*i,R=t+d.x*i,C=Math.atan2(d.y,d.x);let A=Math.atan2(w.y,w.x)-C;return A>Math.PI?A-=2*Math.PI:A<-Math.PI&&(A+=2*Math.PI),this.arc(T,R,i,C,C+A,!1),this.lineTo(s,n),this}ellipse(e,t,s,n,i,h,o,a){return this.currentPath.absellipse(e,t,s,n,h,o,!a,i),this}rect(e,t,s,n){return this.currentPath.rect(e,t,s,n),this}splineThru(e){return this.currentPath.splineThru(e),this}getMinMax(e=new r,t=new r){return this.paths.forEach(s=>s.curves.forEach(n=>n.getMinMax(e,t))),{min:e,max:t}}getCommands(){return this.paths.flatMap(e=>e.curves.flatMap(t=>t.getCommands()))}getData(){return this.paths.map(e=>e.getData()).join(" ")}getBoundingBox(){const e=r.MAX,t=r.MIN;return this.paths.forEach(s=>s.getMinMax(e,t)),{x:e.x,y:e.y,width:t.x-e.x,height:t.y-e.y}}getSvgString(){const{x:e,y:t,width:s,height:n}=this.getBoundingBox();return`<svg viewBox="${e} ${t} ${s} ${n}" xmlns="http://www.w3.org/2000/svg"><path fill="none" stroke="currentColor" d="${this.getData()}"></path></svg>`}getSvgDataUri(){return`data:image/svg+xml;base64,${btoa(this.getSvgString())}`}drawTo(e){this.paths.forEach(t=>{t.curves.forEach(s=>{s.drawTo(e)})})}strokeTo(e){this.drawTo(e),e.stroke()}fillTo(e){this.drawTo(e),e.fill()}}g.CircleCurve=m,g.CubicBezierCurve=S,g.Curve=x,g.CurvePath=b,g.EllipseCurve=q,g.HeartCurve=Y,g.LineCurve=P,g.Path2D=$,g.PloygonCurve=O,g.Point2D=r,g.QuadraticBezierCurve=B,g.RectangularCurve=k,g.SplineCurve=N,g.catmullRom=L,g.cubicBezier=I,g.quadraticBezier=z,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"})});
package/dist/index.mjs CHANGED
@@ -179,8 +179,8 @@ class Curve {
179
179
  getTangentAt(u, output = new Point2D()) {
180
180
  return this.getTangent(this.getUtoTmapping(u), output);
181
181
  }
182
- getPathData() {
183
- return this.getPathCommands().map((cmd) => {
182
+ getData() {
183
+ return this.getCommands().map((cmd) => {
184
184
  switch (cmd.type) {
185
185
  case "M":
186
186
  return `M ${cmd.x} ${cmd.y}`;
@@ -236,7 +236,7 @@ class CircleCurve extends Curve {
236
236
  const _t = t * (end - start) + start - 0.5 * Math.PI;
237
237
  return new Point2D(Math.cos(_t), Math.sin(_t));
238
238
  }
239
- getPathCommands() {
239
+ getCommands() {
240
240
  return [];
241
241
  }
242
242
  drawTo(_ctx) {
@@ -305,7 +305,7 @@ class CubicBezierCurve extends Curve {
305
305
  max.y = Math.max(max.y, v0.y, v1.y, v2.y, v3.y);
306
306
  return { min, max };
307
307
  }
308
- getPathCommands() {
308
+ getCommands() {
309
309
  const { v0, v1, v2, v3 } = this;
310
310
  return [
311
311
  { type: "M", x: v0.x, y: v0.y },
@@ -377,7 +377,7 @@ class EllipseCurve extends Curve {
377
377
  }
378
378
  return output.set(_x, _y);
379
379
  }
380
- getPathCommands() {
380
+ getCommands() {
381
381
  const { x, y, rx, ry, startAngle, endAngle, clockwise } = this;
382
382
  const anticlockwise = !clockwise;
383
383
  const startX = x + rx * Math.cos(startAngle);
@@ -457,7 +457,7 @@ class LineCurve extends Curve {
457
457
  getTangentAt(u, output = new Point2D()) {
458
458
  return this.getTangent(u, output);
459
459
  }
460
- getPathCommands() {
460
+ getCommands() {
461
461
  const { v1, v2 } = this;
462
462
  return [
463
463
  { type: "M", x: v1.x, y: v1.y },
@@ -553,8 +553,8 @@ class HeartCurve extends Curve {
553
553
  const line = this.getCurrentLine(value);
554
554
  return new Point2D(line.v2.y - line.v1.y, -(line.v2.x - line.v1.x)).normalize();
555
555
  }
556
- getPathCommands() {
557
- return this.curves.flatMap((curve) => curve.getPathCommands());
556
+ getCommands() {
557
+ return this.curves.flatMap((curve) => curve.getCommands());
558
558
  }
559
559
  drawTo(ctx) {
560
560
  this.curves.forEach((curve) => curve.drawTo(ctx));
@@ -611,8 +611,8 @@ class PloygonCurve extends Curve {
611
611
  const line = this.getCurrentLine(value);
612
612
  return new Point2D(line.v2.y - line.v1.y, -(line.v2.x - line.v1.x)).normalize();
613
613
  }
614
- getPathCommands() {
615
- return this.curves.flatMap((curve) => curve.getPathCommands());
614
+ getCommands() {
615
+ return this.curves.flatMap((curve) => curve.getCommands());
616
616
  }
617
617
  getMinMax(min = Point2D.MAX, max = Point2D.MIN) {
618
618
  this.curves.forEach((curve) => curve.getMinMax(min, max));
@@ -638,7 +638,7 @@ class QuadraticBezierCurve extends Curve {
638
638
  );
639
639
  return output;
640
640
  }
641
- getPathCommands() {
641
+ getCommands() {
642
642
  const { v0, v1, v2 } = this;
643
643
  return [
644
644
  { type: "M", x: v0.x, y: v0.y },
@@ -745,8 +745,8 @@ class RectangularCurve extends Curve {
745
745
  const { v1, v2 } = this.getCurrentLine(value);
746
746
  return new Point2D(v2.y - v1.y, -(v2.x - v1.x)).normalize();
747
747
  }
748
- getPathCommands() {
749
- return this.curves.flatMap((curve) => curve.getPathCommands());
748
+ getCommands() {
749
+ return this.curves.flatMap((curve) => curve.getCommands());
750
750
  }
751
751
  getMinMax(min = Point2D.MAX, max = Point2D.MIN) {
752
752
  this.curves.forEach((curve) => curve.getMinMax(min, max));
@@ -780,7 +780,7 @@ class SplineCurve extends Curve {
780
780
  );
781
781
  return output;
782
782
  }
783
- getPathCommands() {
783
+ getCommands() {
784
784
  return [];
785
785
  }
786
786
  drawTo(_ctx) {
@@ -973,8 +973,8 @@ class CurvePath extends Curve {
973
973
  this.currentPoint.copy(curve.getPoint(1));
974
974
  return this;
975
975
  }
976
- getPathCommands() {
977
- return this.curves.flatMap((curve) => curve.getPathCommands());
976
+ getCommands() {
977
+ return this.curves.flatMap((curve) => curve.getCommands());
978
978
  }
979
979
  getMinMax(min = Point2D.MAX, max = Point2D.MIN) {
980
980
  this.curves.forEach((curve) => curve.getMinMax(min, max));
@@ -1003,14 +1003,52 @@ var __publicField = (obj, key, value) => {
1003
1003
  return value;
1004
1004
  };
1005
1005
  class Path2D {
1006
- constructor() {
1006
+ constructor(path) {
1007
1007
  __publicField(this, "currentPath", new CurvePath());
1008
1008
  __publicField(this, "paths", [this.currentPath]);
1009
+ if (path) {
1010
+ if (path instanceof Path2D) {
1011
+ this.addPath(path);
1012
+ } else if (Array.isArray(path)) {
1013
+ this.addCommands(path);
1014
+ } else {
1015
+ this.addData(path);
1016
+ }
1017
+ }
1009
1018
  }
1010
1019
  addPath(path) {
1011
1020
  this.paths.push(...path.paths.map((v) => v.clone()));
1012
1021
  return this;
1013
1022
  }
1023
+ addCommands(commands) {
1024
+ for (let i = 0, len = commands.length; i < len; i++) {
1025
+ const cmd = commands[i];
1026
+ switch (cmd.type) {
1027
+ case "M":
1028
+ this.moveTo(cmd.x, cmd.y);
1029
+ break;
1030
+ case "L":
1031
+ this.lineTo(cmd.x, cmd.y);
1032
+ break;
1033
+ case "C":
1034
+ this.bezierCurveTo(cmd.x2, cmd.y2, cmd.x1, cmd.y1, cmd.x, cmd.y);
1035
+ break;
1036
+ case "Q":
1037
+ this.quadraticCurveTo(cmd.x1, cmd.y1, cmd.x, cmd.y);
1038
+ break;
1039
+ case "A":
1040
+ break;
1041
+ case "Z":
1042
+ this.closePath();
1043
+ break;
1044
+ }
1045
+ }
1046
+ return this;
1047
+ }
1048
+ addData(data) {
1049
+ console.error("TODO", data);
1050
+ return this;
1051
+ }
1014
1052
  closePath() {
1015
1053
  this.currentPath.closePath();
1016
1054
  return this;
@@ -1083,11 +1121,11 @@ class Path2D {
1083
1121
  this.paths.forEach((path) => path.curves.forEach((curve) => curve.getMinMax(min, max)));
1084
1122
  return { min, max };
1085
1123
  }
1086
- getPathCommands() {
1087
- return this.paths.flatMap((path) => path.curves.flatMap((curve) => curve.getPathCommands()));
1124
+ getCommands() {
1125
+ return this.paths.flatMap((path) => path.curves.flatMap((curve) => curve.getCommands()));
1088
1126
  }
1089
- getPathData() {
1090
- return this.paths.map((path) => path.getPathData()).join(" ");
1127
+ getData() {
1128
+ return this.paths.map((path) => path.getData()).join(" ");
1091
1129
  }
1092
1130
  getBoundingBox() {
1093
1131
  const min = Point2D.MAX;
@@ -1102,7 +1140,7 @@ class Path2D {
1102
1140
  }
1103
1141
  getSvgString() {
1104
1142
  const { x, y, width, height } = this.getBoundingBox();
1105
- return `<svg viewBox="${x} ${y} ${width} ${height}" xmlns="http://www.w3.org/2000/svg"><path fill="none" stroke="currentColor" d="${this.getPathData()}"></path></svg>`;
1143
+ return `<svg viewBox="${x} ${y} ${width} ${height}" xmlns="http://www.w3.org/2000/svg"><path fill="none" stroke="currentColor" d="${this.getData()}"></path></svg>`;
1106
1144
  }
1107
1145
  getSvgDataUri() {
1108
1146
  return `data:image/svg+xml;base64,${btoa(this.getSvgString())}`;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "modern-path2d",
3
3
  "type": "module",
4
- "version": "0.0.3",
4
+ "version": "0.0.5",
5
5
  "packageManager": "pnpm@9.9.0",
6
6
  "description": "A modern Path2D library, fully compatible with Web Path2D, with additional support for path animation, path deformation, path playback, etc.",
7
7
  "author": "wxm",