modern-path2d 1.3.0 → 1.3.2
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 +192 -246
- package/dist/index.d.cts +6 -2
- package/dist/index.d.mts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +2 -2
- package/dist/index.mjs +192 -246
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1775,32 +1775,6 @@ class Curve {
|
|
|
1775
1775
|
options
|
|
1776
1776
|
);
|
|
1777
1777
|
}
|
|
1778
|
-
toTriangulatedSVGString(result = this.fillTriangulate(), padding = 0) {
|
|
1779
|
-
const { vertices, indices } = result;
|
|
1780
|
-
const min = { x: -padding, y: -padding };
|
|
1781
|
-
const max = { x: padding, y: padding };
|
|
1782
|
-
const getPoint = (indice) => {
|
|
1783
|
-
const x = vertices[indice * 2];
|
|
1784
|
-
const y = vertices[indice * 2 + 1];
|
|
1785
|
-
min.x = Math.min(min.x, x + padding);
|
|
1786
|
-
max.x = Math.max(max.x, x + padding);
|
|
1787
|
-
min.y = Math.min(min.y, y + padding);
|
|
1788
|
-
max.y = Math.max(max.y, y + padding);
|
|
1789
|
-
return [x, y];
|
|
1790
|
-
};
|
|
1791
|
-
let polygonStr = "";
|
|
1792
|
-
for (let i = 0, len = indices.length; i < len; i += 3) {
|
|
1793
|
-
const p1 = getPoint(indices[i]);
|
|
1794
|
-
const p2 = getPoint(indices[i + 1]);
|
|
1795
|
-
const p3 = getPoint(indices[i + 2]);
|
|
1796
|
-
polygonStr += `<polygon points="${p1.join(",")} ${p2.join(",")} ${p3.join(",")}" fill="none" stroke="black" stroke-width="0.5" stroke-linecap="round" stroke-linejoin="round" />`;
|
|
1797
|
-
}
|
|
1798
|
-
const viewBox = [min.x, min.y, max.x - min.x, max.y - min.y];
|
|
1799
|
-
return `<svg width="${viewBox[2]}" height="${viewBox[3]}" viewBox="${viewBox.join(" ")}" xmlns="http://www.w3.org/2000/svg">${polygonStr}</svg>`;
|
|
1800
|
-
}
|
|
1801
|
-
toTriangulatedSVG(result, padding) {
|
|
1802
|
-
return new DOMParser().parseFromString(this.toTriangulatedSVGString(result, padding), "image/svg+xml").documentElement;
|
|
1803
|
-
}
|
|
1804
1778
|
toCommands() {
|
|
1805
1779
|
const comds = [];
|
|
1806
1780
|
const potins = this.getPoints();
|
|
@@ -1976,76 +1950,24 @@ class RoundCurve extends Curve {
|
|
|
1976
1950
|
return [this._center];
|
|
1977
1951
|
}
|
|
1978
1952
|
getAdaptivePointArray(output = []) {
|
|
1979
|
-
const { cx, cy, rx, ry,
|
|
1980
|
-
if (!(rx >= 0 && ry >= 0
|
|
1953
|
+
const { cx, cy, rx, ry, startAngle, endAngle, clockwise } = this;
|
|
1954
|
+
if (!(rx >= 0 && ry >= 0)) {
|
|
1981
1955
|
return output;
|
|
1982
1956
|
}
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
return output;
|
|
1989
|
-
}
|
|
1990
|
-
if (n === 0) {
|
|
1991
|
-
output[0] = output[6] = x + dx;
|
|
1992
|
-
output[1] = output[3] = y + dy;
|
|
1993
|
-
output[2] = output[4] = x - dx;
|
|
1994
|
-
output[5] = output[7] = y - dy;
|
|
1995
|
-
return output;
|
|
1957
|
+
let deltaAngle = endAngle - startAngle;
|
|
1958
|
+
if (!clockwise && deltaAngle > 0) {
|
|
1959
|
+
deltaAngle -= 2 * Math.PI;
|
|
1960
|
+
} else if (clockwise && deltaAngle < 0) {
|
|
1961
|
+
deltaAngle += 2 * Math.PI;
|
|
1996
1962
|
}
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
let
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
let y1 = y + y0;
|
|
2006
|
-
output[j1++] = x1;
|
|
2007
|
-
output[j1++] = y1;
|
|
2008
|
-
output[--j2] = y1;
|
|
2009
|
-
output[--j2] = x2;
|
|
2010
|
-
if (dy) {
|
|
2011
|
-
const y22 = y - y0;
|
|
2012
|
-
output[j3++] = x2;
|
|
2013
|
-
output[j3++] = y22;
|
|
2014
|
-
output[--j4] = y22;
|
|
2015
|
-
output[--j4] = x1;
|
|
2016
|
-
}
|
|
2017
|
-
for (let i = 1; i < n; i++) {
|
|
2018
|
-
const a = Math.PI / 2 * (i / n);
|
|
2019
|
-
const x02 = dx + Math.cos(a) * rx;
|
|
2020
|
-
const y02 = dy + Math.sin(a) * ry;
|
|
2021
|
-
const x12 = x + x02;
|
|
2022
|
-
const x22 = x - x02;
|
|
2023
|
-
const y12 = y + y02;
|
|
2024
|
-
const y22 = y - y02;
|
|
2025
|
-
output[j1++] = x12;
|
|
2026
|
-
output[j1++] = y12;
|
|
2027
|
-
output[--j2] = y12;
|
|
2028
|
-
output[--j2] = x22;
|
|
2029
|
-
output[j3++] = x22;
|
|
2030
|
-
output[j3++] = y22;
|
|
2031
|
-
output[--j4] = y22;
|
|
2032
|
-
output[--j4] = x12;
|
|
2033
|
-
}
|
|
2034
|
-
x0 = dx;
|
|
2035
|
-
y0 = dy + ry;
|
|
2036
|
-
x1 = x + x0;
|
|
2037
|
-
x2 = x - x0;
|
|
2038
|
-
y1 = y + y0;
|
|
2039
|
-
const y2 = y - y0;
|
|
2040
|
-
output[j1++] = x1;
|
|
2041
|
-
output[j1++] = y1;
|
|
2042
|
-
output[--j4] = y2;
|
|
2043
|
-
output[--j4] = x1;
|
|
2044
|
-
if (dx) {
|
|
2045
|
-
output[j1++] = x2;
|
|
2046
|
-
output[j1++] = y1;
|
|
2047
|
-
output[--j4] = y2;
|
|
2048
|
-
output[--j4] = x2;
|
|
1963
|
+
const arcLength = Math.abs(deltaAngle);
|
|
1964
|
+
const n = Math.max(1, Math.ceil(arcLength / (Math.PI / 16)));
|
|
1965
|
+
for (let i = 0; i <= n; i++) {
|
|
1966
|
+
const t = i / n;
|
|
1967
|
+
const angle = startAngle + deltaAngle * t;
|
|
1968
|
+
const x = cx + Math.cos(angle) * rx;
|
|
1969
|
+
const y = cy + Math.sin(angle) * ry;
|
|
1970
|
+
output.push(x, y);
|
|
2049
1971
|
}
|
|
2050
1972
|
return output;
|
|
2051
1973
|
}
|
|
@@ -2311,121 +2233,6 @@ class ArcCurve extends RoundCurve {
|
|
|
2311
2233
|
}
|
|
2312
2234
|
}
|
|
2313
2235
|
|
|
2314
|
-
class LineCurve extends Curve {
|
|
2315
|
-
constructor(p1 = new Vector2(), p2 = new Vector2()) {
|
|
2316
|
-
super();
|
|
2317
|
-
this.p1 = p1;
|
|
2318
|
-
this.p2 = p2;
|
|
2319
|
-
}
|
|
2320
|
-
static from(p1x, p1y, p2x, p2y) {
|
|
2321
|
-
return new LineCurve(
|
|
2322
|
-
new Vector2(p1x, p1y),
|
|
2323
|
-
new Vector2(p2x, p2y)
|
|
2324
|
-
);
|
|
2325
|
-
}
|
|
2326
|
-
getPoint(t, output = new Vector2()) {
|
|
2327
|
-
if (t === 1) {
|
|
2328
|
-
output.copy(this.p2);
|
|
2329
|
-
} else {
|
|
2330
|
-
output.copy(this.p2).sub(this.p1).scale(t).add(this.p1);
|
|
2331
|
-
}
|
|
2332
|
-
return output;
|
|
2333
|
-
}
|
|
2334
|
-
getPointAt(u, output = new Vector2()) {
|
|
2335
|
-
return this.getPoint(u, output);
|
|
2336
|
-
}
|
|
2337
|
-
getTangent(_t, output = new Vector2()) {
|
|
2338
|
-
return output.subVectors(this.p2, this.p1).normalize();
|
|
2339
|
-
}
|
|
2340
|
-
getTangentAt(u, output = new Vector2()) {
|
|
2341
|
-
return this.getTangent(u, output);
|
|
2342
|
-
}
|
|
2343
|
-
getControlPointRefs() {
|
|
2344
|
-
return [this.p1, this.p2];
|
|
2345
|
-
}
|
|
2346
|
-
getAdaptivePointArray(output = []) {
|
|
2347
|
-
output.push(
|
|
2348
|
-
this.p1.x,
|
|
2349
|
-
this.p1.y,
|
|
2350
|
-
this.p2.x,
|
|
2351
|
-
this.p2.y
|
|
2352
|
-
);
|
|
2353
|
-
return output;
|
|
2354
|
-
}
|
|
2355
|
-
getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
|
|
2356
|
-
const { p1, p2 } = this;
|
|
2357
|
-
min.x = Math.min(min.x, p1.x, p2.x);
|
|
2358
|
-
min.y = Math.min(min.y, p1.y, p2.y);
|
|
2359
|
-
max.x = Math.max(max.x, p1.x, p2.x);
|
|
2360
|
-
max.y = Math.max(max.y, p1.y, p2.y);
|
|
2361
|
-
return { min: min.finite(), max: max.finite() };
|
|
2362
|
-
}
|
|
2363
|
-
toCommands() {
|
|
2364
|
-
const { p1, p2 } = this;
|
|
2365
|
-
return [
|
|
2366
|
-
{ type: "M", x: p1.x, y: p1.y },
|
|
2367
|
-
{ type: "L", x: p2.x, y: p2.y }
|
|
2368
|
-
];
|
|
2369
|
-
}
|
|
2370
|
-
fillTriangulate(options = {}) {
|
|
2371
|
-
let {
|
|
2372
|
-
vertices = [],
|
|
2373
|
-
indices = [],
|
|
2374
|
-
verticesStride = 2,
|
|
2375
|
-
verticesOffset = vertices.length / verticesStride,
|
|
2376
|
-
indicesOffset = indices.length
|
|
2377
|
-
} = options;
|
|
2378
|
-
const x = this.p1.x;
|
|
2379
|
-
const y = this.p1.y;
|
|
2380
|
-
const width = this.p2.x - this.p1.x || 1;
|
|
2381
|
-
const height = this.p2.y - this.p2.y || 1;
|
|
2382
|
-
const points = [
|
|
2383
|
-
x,
|
|
2384
|
-
y,
|
|
2385
|
-
x + width,
|
|
2386
|
-
y,
|
|
2387
|
-
x + width,
|
|
2388
|
-
y + height,
|
|
2389
|
-
x,
|
|
2390
|
-
y + height
|
|
2391
|
-
];
|
|
2392
|
-
let count = 0;
|
|
2393
|
-
verticesOffset *= verticesStride;
|
|
2394
|
-
vertices[verticesOffset + count] = points[0];
|
|
2395
|
-
vertices[verticesOffset + count + 1] = points[1];
|
|
2396
|
-
count += verticesStride;
|
|
2397
|
-
vertices[verticesOffset + count] = points[2];
|
|
2398
|
-
vertices[verticesOffset + count + 1] = points[3];
|
|
2399
|
-
count += verticesStride;
|
|
2400
|
-
vertices[verticesOffset + count] = points[6];
|
|
2401
|
-
vertices[verticesOffset + count + 1] = points[7];
|
|
2402
|
-
count += verticesStride;
|
|
2403
|
-
vertices[verticesOffset + count] = points[4];
|
|
2404
|
-
vertices[verticesOffset + count + 1] = points[5];
|
|
2405
|
-
count += verticesStride;
|
|
2406
|
-
const verticesIndex = verticesOffset / verticesStride;
|
|
2407
|
-
indices[indicesOffset++] = verticesIndex;
|
|
2408
|
-
indices[indicesOffset++] = verticesIndex + 1;
|
|
2409
|
-
indices[indicesOffset++] = verticesIndex + 2;
|
|
2410
|
-
indices[indicesOffset++] = verticesIndex + 1;
|
|
2411
|
-
indices[indicesOffset++] = verticesIndex + 3;
|
|
2412
|
-
indices[indicesOffset++] = verticesIndex + 2;
|
|
2413
|
-
return { vertices, indices };
|
|
2414
|
-
}
|
|
2415
|
-
drawTo(ctx) {
|
|
2416
|
-
const { p1, p2 } = this;
|
|
2417
|
-
ctx.lineTo(p1.x, p1.y);
|
|
2418
|
-
ctx.lineTo(p2.x, p2.y);
|
|
2419
|
-
return this;
|
|
2420
|
-
}
|
|
2421
|
-
copy(source) {
|
|
2422
|
-
super.copy(source);
|
|
2423
|
-
this.p1.copy(source.p1);
|
|
2424
|
-
this.p2.copy(source.p2);
|
|
2425
|
-
return this;
|
|
2426
|
-
}
|
|
2427
|
-
}
|
|
2428
|
-
|
|
2429
2236
|
class CompositeCurve extends Curve {
|
|
2430
2237
|
constructor(curves = []) {
|
|
2431
2238
|
super();
|
|
@@ -2473,7 +2280,9 @@ class CompositeCurve extends Curve {
|
|
|
2473
2280
|
return this.curves.flatMap((curve) => curve.getControlPointRefs());
|
|
2474
2281
|
}
|
|
2475
2282
|
_removeNextPointIfEqualPrevPoint(output, offset) {
|
|
2476
|
-
|
|
2283
|
+
const p1 = [output[offset - 1], output[offset]];
|
|
2284
|
+
const p2 = [output[offset + 1], output[offset + 2]];
|
|
2285
|
+
if (p1[0] === p2[0] && p1[1] === p2[1]) {
|
|
2477
2286
|
output.splice(offset + 1, 2);
|
|
2478
2287
|
}
|
|
2479
2288
|
return output;
|
|
@@ -2500,43 +2309,19 @@ class CompositeCurve extends Curve {
|
|
|
2500
2309
|
});
|
|
2501
2310
|
return output;
|
|
2502
2311
|
}
|
|
2312
|
+
strokeTriangulate(options) {
|
|
2313
|
+
if (this.curves.length === 1) {
|
|
2314
|
+
return this.curves[0].strokeTriangulate(options);
|
|
2315
|
+
} else {
|
|
2316
|
+
return super.strokeTriangulate(options);
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2503
2319
|
fillTriangulate(options) {
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
const pointArray = [];
|
|
2510
|
-
lines.forEach((line) => {
|
|
2511
|
-
const x = line.p1.x;
|
|
2512
|
-
const y = line.p1.y;
|
|
2513
|
-
if (pointArray[pointArray.length - 2] !== x || pointArray[pointArray.length - 1] !== y) {
|
|
2514
|
-
pointArray.push(x, y);
|
|
2515
|
-
}
|
|
2516
|
-
pointArray.push(line.p2.x, line.p2.y);
|
|
2517
|
-
});
|
|
2518
|
-
fillTriangulate(pointArray, {
|
|
2519
|
-
...options,
|
|
2520
|
-
indices,
|
|
2521
|
-
vertices
|
|
2522
|
-
});
|
|
2523
|
-
lines.length = 0;
|
|
2524
|
-
}
|
|
2525
|
-
};
|
|
2526
|
-
this.curves.forEach((curve) => {
|
|
2527
|
-
if (curve instanceof LineCurve) {
|
|
2528
|
-
lines.push(curve);
|
|
2529
|
-
} else {
|
|
2530
|
-
fillLines();
|
|
2531
|
-
curve.fillTriangulate({
|
|
2532
|
-
...options,
|
|
2533
|
-
indices,
|
|
2534
|
-
vertices
|
|
2535
|
-
});
|
|
2536
|
-
}
|
|
2537
|
-
});
|
|
2538
|
-
fillLines();
|
|
2539
|
-
return { indices, vertices };
|
|
2320
|
+
if (this.curves.length === 1) {
|
|
2321
|
+
return this.curves[0].fillTriangulate(options);
|
|
2322
|
+
} else {
|
|
2323
|
+
return super.fillTriangulate(options);
|
|
2324
|
+
}
|
|
2540
2325
|
}
|
|
2541
2326
|
applyTransform(transform) {
|
|
2542
2327
|
this.curves.forEach((curve) => curve.applyTransform(transform));
|
|
@@ -2696,6 +2481,125 @@ class EllipseCurve extends RoundCurve {
|
|
|
2696
2481
|
}
|
|
2697
2482
|
}
|
|
2698
2483
|
|
|
2484
|
+
class LineCurve extends Curve {
|
|
2485
|
+
constructor(p1 = new Vector2(), p2 = new Vector2()) {
|
|
2486
|
+
super();
|
|
2487
|
+
this.p1 = p1;
|
|
2488
|
+
this.p2 = p2;
|
|
2489
|
+
}
|
|
2490
|
+
static from(p1x, p1y, p2x, p2y) {
|
|
2491
|
+
return new LineCurve(
|
|
2492
|
+
new Vector2(p1x, p1y),
|
|
2493
|
+
new Vector2(p2x, p2y)
|
|
2494
|
+
);
|
|
2495
|
+
}
|
|
2496
|
+
getPoint(t, output = new Vector2()) {
|
|
2497
|
+
if (t === 1) {
|
|
2498
|
+
output.copy(this.p2);
|
|
2499
|
+
} else {
|
|
2500
|
+
output.copy(this.p2).sub(this.p1).scale(t).add(this.p1);
|
|
2501
|
+
}
|
|
2502
|
+
return output;
|
|
2503
|
+
}
|
|
2504
|
+
getPointAt(u, output = new Vector2()) {
|
|
2505
|
+
return this.getPoint(u, output);
|
|
2506
|
+
}
|
|
2507
|
+
getTangent(_t, output = new Vector2()) {
|
|
2508
|
+
return output.subVectors(this.p2, this.p1).normalize();
|
|
2509
|
+
}
|
|
2510
|
+
getTangentAt(u, output = new Vector2()) {
|
|
2511
|
+
return this.getTangent(u, output);
|
|
2512
|
+
}
|
|
2513
|
+
getControlPointRefs() {
|
|
2514
|
+
return [this.p1, this.p2];
|
|
2515
|
+
}
|
|
2516
|
+
getAdaptivePointArray(output = []) {
|
|
2517
|
+
output.push(
|
|
2518
|
+
this.p1.x,
|
|
2519
|
+
this.p1.y,
|
|
2520
|
+
this.p2.x,
|
|
2521
|
+
this.p2.y
|
|
2522
|
+
);
|
|
2523
|
+
return output;
|
|
2524
|
+
}
|
|
2525
|
+
getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
|
|
2526
|
+
const { p1, p2 } = this;
|
|
2527
|
+
min.x = Math.min(min.x, p1.x, p2.x);
|
|
2528
|
+
min.y = Math.min(min.y, p1.y, p2.y);
|
|
2529
|
+
max.x = Math.max(max.x, p1.x, p2.x);
|
|
2530
|
+
max.y = Math.max(max.y, p1.y, p2.y);
|
|
2531
|
+
return { min: min.finite(), max: max.finite() };
|
|
2532
|
+
}
|
|
2533
|
+
toCommands() {
|
|
2534
|
+
const { p1, p2 } = this;
|
|
2535
|
+
return [
|
|
2536
|
+
{ type: "M", x: p1.x, y: p1.y },
|
|
2537
|
+
{ type: "L", x: p2.x, y: p2.y }
|
|
2538
|
+
];
|
|
2539
|
+
}
|
|
2540
|
+
fillTriangulate(options = {}) {
|
|
2541
|
+
let {
|
|
2542
|
+
vertices = [],
|
|
2543
|
+
indices = [],
|
|
2544
|
+
verticesStride = 2,
|
|
2545
|
+
verticesOffset = vertices.length / verticesStride,
|
|
2546
|
+
indicesOffset = indices.length
|
|
2547
|
+
} = options;
|
|
2548
|
+
const minX = Math.min(this.p1.x, this.p2.x);
|
|
2549
|
+
const maxX = Math.max(this.p1.x, this.p2.x);
|
|
2550
|
+
const minY = Math.min(this.p1.y, this.p2.y);
|
|
2551
|
+
const maxY = Math.max(this.p1.y, this.p2.y);
|
|
2552
|
+
const x = minX;
|
|
2553
|
+
const y = minY;
|
|
2554
|
+
const width = maxX - minX || options.style?.strokeWidth || 1;
|
|
2555
|
+
const height = maxY - minY || options.style?.strokeWidth || 1;
|
|
2556
|
+
const points = [
|
|
2557
|
+
x,
|
|
2558
|
+
y,
|
|
2559
|
+
x + width,
|
|
2560
|
+
y,
|
|
2561
|
+
x + width,
|
|
2562
|
+
y + height,
|
|
2563
|
+
x,
|
|
2564
|
+
y + height
|
|
2565
|
+
];
|
|
2566
|
+
let count = 0;
|
|
2567
|
+
verticesOffset *= verticesStride;
|
|
2568
|
+
vertices[verticesOffset + count] = points[0];
|
|
2569
|
+
vertices[verticesOffset + count + 1] = points[1];
|
|
2570
|
+
count += verticesStride;
|
|
2571
|
+
vertices[verticesOffset + count] = points[2];
|
|
2572
|
+
vertices[verticesOffset + count + 1] = points[3];
|
|
2573
|
+
count += verticesStride;
|
|
2574
|
+
vertices[verticesOffset + count] = points[6];
|
|
2575
|
+
vertices[verticesOffset + count + 1] = points[7];
|
|
2576
|
+
count += verticesStride;
|
|
2577
|
+
vertices[verticesOffset + count] = points[4];
|
|
2578
|
+
vertices[verticesOffset + count + 1] = points[5];
|
|
2579
|
+
count += verticesStride;
|
|
2580
|
+
const verticesIndex = verticesOffset / verticesStride;
|
|
2581
|
+
indices[indicesOffset++] = verticesIndex;
|
|
2582
|
+
indices[indicesOffset++] = verticesIndex + 1;
|
|
2583
|
+
indices[indicesOffset++] = verticesIndex + 2;
|
|
2584
|
+
indices[indicesOffset++] = verticesIndex + 1;
|
|
2585
|
+
indices[indicesOffset++] = verticesIndex + 3;
|
|
2586
|
+
indices[indicesOffset++] = verticesIndex + 2;
|
|
2587
|
+
return { vertices, indices };
|
|
2588
|
+
}
|
|
2589
|
+
drawTo(ctx) {
|
|
2590
|
+
const { p1, p2 } = this;
|
|
2591
|
+
ctx.lineTo(p1.x, p1.y);
|
|
2592
|
+
ctx.lineTo(p2.x, p2.y);
|
|
2593
|
+
return this;
|
|
2594
|
+
}
|
|
2595
|
+
copy(source) {
|
|
2596
|
+
super.copy(source);
|
|
2597
|
+
this.p1.copy(source.p1);
|
|
2598
|
+
this.p2.copy(source.p2);
|
|
2599
|
+
return this;
|
|
2600
|
+
}
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2699
2603
|
class PloygonCurve extends CompositeCurve {
|
|
2700
2604
|
//
|
|
2701
2605
|
}
|
|
@@ -3442,7 +3346,21 @@ class Path2D extends CompositeCurve {
|
|
|
3442
3346
|
curve.strokeTriangulate({
|
|
3443
3347
|
...options,
|
|
3444
3348
|
indices,
|
|
3445
|
-
vertices
|
|
3349
|
+
vertices,
|
|
3350
|
+
style: { ...this.style }
|
|
3351
|
+
});
|
|
3352
|
+
});
|
|
3353
|
+
return { indices, vertices };
|
|
3354
|
+
}
|
|
3355
|
+
fillTriangulate(options) {
|
|
3356
|
+
const indices = options?.indices ?? [];
|
|
3357
|
+
const vertices = options?.vertices ?? [];
|
|
3358
|
+
this.curves.forEach((curve) => {
|
|
3359
|
+
curve.fillTriangulate({
|
|
3360
|
+
...options,
|
|
3361
|
+
indices,
|
|
3362
|
+
vertices,
|
|
3363
|
+
style: { ...this.style }
|
|
3446
3364
|
});
|
|
3447
3365
|
});
|
|
3448
3366
|
return { indices, vertices };
|
|
@@ -3538,6 +3456,34 @@ class Path2DSet {
|
|
|
3538
3456
|
this.paths.forEach((path) => path.getMinMax(min, max, withStyle));
|
|
3539
3457
|
return new BoundingBox(min.x, min.y, max.x - min.x, max.y - min.y);
|
|
3540
3458
|
}
|
|
3459
|
+
toTriangulatedSVGString(result = this.paths.map((p) => p.fillTriangulate()), padding = 0) {
|
|
3460
|
+
let polygonStr = "";
|
|
3461
|
+
const min = { x: -padding, y: -padding };
|
|
3462
|
+
const max = { x: padding, y: padding };
|
|
3463
|
+
const results = Array.isArray(result) ? result : [result];
|
|
3464
|
+
results.forEach(({ vertices, indices }) => {
|
|
3465
|
+
const getPoint = (indice) => {
|
|
3466
|
+
const x = vertices[indice * 2];
|
|
3467
|
+
const y = vertices[indice * 2 + 1];
|
|
3468
|
+
min.x = Math.min(min.x, x + padding);
|
|
3469
|
+
max.x = Math.max(max.x, x + padding);
|
|
3470
|
+
min.y = Math.min(min.y, y + padding);
|
|
3471
|
+
max.y = Math.max(max.y, y + padding);
|
|
3472
|
+
return [x, y];
|
|
3473
|
+
};
|
|
3474
|
+
for (let i = 0, len = indices.length; i < len; i += 3) {
|
|
3475
|
+
const p1 = getPoint(indices[i]);
|
|
3476
|
+
const p2 = getPoint(indices[i + 1]);
|
|
3477
|
+
const p3 = getPoint(indices[i + 2]);
|
|
3478
|
+
polygonStr += `<polygon points="${p1.join(",")} ${p2.join(",")} ${p3.join(",")}" fill="none" stroke="black" stroke-width="0.5" stroke-linecap="round" stroke-linejoin="round" />`;
|
|
3479
|
+
}
|
|
3480
|
+
});
|
|
3481
|
+
const viewBox = [min.x, min.y, max.x - min.x, max.y - min.y];
|
|
3482
|
+
return `<svg width="${viewBox[2]}" height="${viewBox[3]}" viewBox="${viewBox.join(" ")}" xmlns="http://www.w3.org/2000/svg">${polygonStr}</svg>`;
|
|
3483
|
+
}
|
|
3484
|
+
toTriangulatedSVG(result, padding) {
|
|
3485
|
+
return new DOMParser().parseFromString(this.toTriangulatedSVGString(result, padding), "image/svg+xml").documentElement;
|
|
3486
|
+
}
|
|
3541
3487
|
toSVGString() {
|
|
3542
3488
|
const { x, y, width, height } = this.getBoundingBox();
|
|
3543
3489
|
const content = this.paths.map((path) => path.toSVGPathString()).join("");
|
package/dist/index.d.cts
CHANGED
|
@@ -14,6 +14,7 @@ interface FillTriangulateOptions {
|
|
|
14
14
|
verticesStride?: number;
|
|
15
15
|
verticesOffset?: number;
|
|
16
16
|
indicesOffset?: number;
|
|
17
|
+
style?: Partial<Path2DStyle>;
|
|
17
18
|
}
|
|
18
19
|
interface FillTriangulatedResult {
|
|
19
20
|
vertices: number[];
|
|
@@ -35,6 +36,7 @@ interface StrokeTriangulateOptions {
|
|
|
35
36
|
lineStyle?: LineStyle;
|
|
36
37
|
flipAlignment?: boolean;
|
|
37
38
|
closed?: boolean;
|
|
39
|
+
style?: Partial<Path2DStyle>;
|
|
38
40
|
}
|
|
39
41
|
interface StrokeTriangulatedResult {
|
|
40
42
|
vertices: number[];
|
|
@@ -162,8 +164,6 @@ declare abstract class Curve {
|
|
|
162
164
|
getBoundingBox(): BoundingBox;
|
|
163
165
|
fillTriangulate(options?: FillTriangulateOptions): FillTriangulatedResult;
|
|
164
166
|
strokeTriangulate(options?: StrokeTriangulateOptions): StrokeTriangulatedResult;
|
|
165
|
-
toTriangulatedSVGString(result?: FillTriangulatedResult | StrokeTriangulatedResult, padding?: number): string;
|
|
166
|
-
toTriangulatedSVG(result?: FillTriangulatedResult | StrokeTriangulatedResult, padding?: number): SVGElement;
|
|
167
167
|
toCommands(): Path2DCommand[];
|
|
168
168
|
toData(): Path2DData;
|
|
169
169
|
drawTo(ctx: CanvasRenderingContext2D): this;
|
|
@@ -225,6 +225,7 @@ declare class CompositeCurve<T extends Curve = Curve> extends Curve {
|
|
|
225
225
|
protected _removeNextPointIfEqualPrevPoint(output: number[], offset: number): number[];
|
|
226
226
|
getSpacedPointArray(count?: number, output?: number[]): number[];
|
|
227
227
|
getAdaptivePointArray(output?: number[]): number[];
|
|
228
|
+
strokeTriangulate(options?: StrokeTriangulateOptions): StrokeTriangulatedResult;
|
|
228
229
|
fillTriangulate(options?: FillTriangulateOptions): FillTriangulatedResult;
|
|
229
230
|
applyTransform(transform: Matrix3 | ((point: Vector2) => void)): this;
|
|
230
231
|
getMinMax(min?: Vector2, max?: Vector2): {
|
|
@@ -498,6 +499,7 @@ declare class Path2D extends CompositeCurve<CurvePath> {
|
|
|
498
499
|
max: Vector2;
|
|
499
500
|
};
|
|
500
501
|
strokeTriangulate(options?: StrokeTriangulateOptions): StrokeTriangulatedResult;
|
|
502
|
+
fillTriangulate(options?: FillTriangulateOptions): FillTriangulatedResult;
|
|
501
503
|
getBoundingBox(withStyle?: boolean): BoundingBox;
|
|
502
504
|
drawTo(ctx: CanvasRenderingContext2D, style?: Partial<Path2DStyle>): this;
|
|
503
505
|
drawControlPointsTo(ctx: CanvasRenderingContext2D, style?: Partial<Path2DStyle>): this;
|
|
@@ -512,6 +514,8 @@ declare class Path2DSet {
|
|
|
512
514
|
viewBox?: number[] | undefined;
|
|
513
515
|
constructor(paths?: Path2D[], viewBox?: number[] | undefined);
|
|
514
516
|
getBoundingBox(withStyle?: boolean): BoundingBox | undefined;
|
|
517
|
+
toTriangulatedSVGString(result?: FillTriangulatedResult | StrokeTriangulatedResult | (FillTriangulatedResult | StrokeTriangulatedResult)[], padding?: number): string;
|
|
518
|
+
toTriangulatedSVG(result?: FillTriangulatedResult | StrokeTriangulatedResult | (FillTriangulatedResult | StrokeTriangulatedResult)[], padding?: number): SVGElement;
|
|
515
519
|
toSVGString(): string;
|
|
516
520
|
toSVGUrl(): string;
|
|
517
521
|
toSVG(): SVGElement;
|
package/dist/index.d.mts
CHANGED
|
@@ -14,6 +14,7 @@ interface FillTriangulateOptions {
|
|
|
14
14
|
verticesStride?: number;
|
|
15
15
|
verticesOffset?: number;
|
|
16
16
|
indicesOffset?: number;
|
|
17
|
+
style?: Partial<Path2DStyle>;
|
|
17
18
|
}
|
|
18
19
|
interface FillTriangulatedResult {
|
|
19
20
|
vertices: number[];
|
|
@@ -35,6 +36,7 @@ interface StrokeTriangulateOptions {
|
|
|
35
36
|
lineStyle?: LineStyle;
|
|
36
37
|
flipAlignment?: boolean;
|
|
37
38
|
closed?: boolean;
|
|
39
|
+
style?: Partial<Path2DStyle>;
|
|
38
40
|
}
|
|
39
41
|
interface StrokeTriangulatedResult {
|
|
40
42
|
vertices: number[];
|
|
@@ -162,8 +164,6 @@ declare abstract class Curve {
|
|
|
162
164
|
getBoundingBox(): BoundingBox;
|
|
163
165
|
fillTriangulate(options?: FillTriangulateOptions): FillTriangulatedResult;
|
|
164
166
|
strokeTriangulate(options?: StrokeTriangulateOptions): StrokeTriangulatedResult;
|
|
165
|
-
toTriangulatedSVGString(result?: FillTriangulatedResult | StrokeTriangulatedResult, padding?: number): string;
|
|
166
|
-
toTriangulatedSVG(result?: FillTriangulatedResult | StrokeTriangulatedResult, padding?: number): SVGElement;
|
|
167
167
|
toCommands(): Path2DCommand[];
|
|
168
168
|
toData(): Path2DData;
|
|
169
169
|
drawTo(ctx: CanvasRenderingContext2D): this;
|
|
@@ -225,6 +225,7 @@ declare class CompositeCurve<T extends Curve = Curve> extends Curve {
|
|
|
225
225
|
protected _removeNextPointIfEqualPrevPoint(output: number[], offset: number): number[];
|
|
226
226
|
getSpacedPointArray(count?: number, output?: number[]): number[];
|
|
227
227
|
getAdaptivePointArray(output?: number[]): number[];
|
|
228
|
+
strokeTriangulate(options?: StrokeTriangulateOptions): StrokeTriangulatedResult;
|
|
228
229
|
fillTriangulate(options?: FillTriangulateOptions): FillTriangulatedResult;
|
|
229
230
|
applyTransform(transform: Matrix3 | ((point: Vector2) => void)): this;
|
|
230
231
|
getMinMax(min?: Vector2, max?: Vector2): {
|
|
@@ -498,6 +499,7 @@ declare class Path2D extends CompositeCurve<CurvePath> {
|
|
|
498
499
|
max: Vector2;
|
|
499
500
|
};
|
|
500
501
|
strokeTriangulate(options?: StrokeTriangulateOptions): StrokeTriangulatedResult;
|
|
502
|
+
fillTriangulate(options?: FillTriangulateOptions): FillTriangulatedResult;
|
|
501
503
|
getBoundingBox(withStyle?: boolean): BoundingBox;
|
|
502
504
|
drawTo(ctx: CanvasRenderingContext2D, style?: Partial<Path2DStyle>): this;
|
|
503
505
|
drawControlPointsTo(ctx: CanvasRenderingContext2D, style?: Partial<Path2DStyle>): this;
|
|
@@ -512,6 +514,8 @@ declare class Path2DSet {
|
|
|
512
514
|
viewBox?: number[] | undefined;
|
|
513
515
|
constructor(paths?: Path2D[], viewBox?: number[] | undefined);
|
|
514
516
|
getBoundingBox(withStyle?: boolean): BoundingBox | undefined;
|
|
517
|
+
toTriangulatedSVGString(result?: FillTriangulatedResult | StrokeTriangulatedResult | (FillTriangulatedResult | StrokeTriangulatedResult)[], padding?: number): string;
|
|
518
|
+
toTriangulatedSVG(result?: FillTriangulatedResult | StrokeTriangulatedResult | (FillTriangulatedResult | StrokeTriangulatedResult)[], padding?: number): SVGElement;
|
|
515
519
|
toSVGString(): string;
|
|
516
520
|
toSVGUrl(): string;
|
|
517
521
|
toSVG(): SVGElement;
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ interface FillTriangulateOptions {
|
|
|
14
14
|
verticesStride?: number;
|
|
15
15
|
verticesOffset?: number;
|
|
16
16
|
indicesOffset?: number;
|
|
17
|
+
style?: Partial<Path2DStyle>;
|
|
17
18
|
}
|
|
18
19
|
interface FillTriangulatedResult {
|
|
19
20
|
vertices: number[];
|
|
@@ -35,6 +36,7 @@ interface StrokeTriangulateOptions {
|
|
|
35
36
|
lineStyle?: LineStyle;
|
|
36
37
|
flipAlignment?: boolean;
|
|
37
38
|
closed?: boolean;
|
|
39
|
+
style?: Partial<Path2DStyle>;
|
|
38
40
|
}
|
|
39
41
|
interface StrokeTriangulatedResult {
|
|
40
42
|
vertices: number[];
|
|
@@ -162,8 +164,6 @@ declare abstract class Curve {
|
|
|
162
164
|
getBoundingBox(): BoundingBox;
|
|
163
165
|
fillTriangulate(options?: FillTriangulateOptions): FillTriangulatedResult;
|
|
164
166
|
strokeTriangulate(options?: StrokeTriangulateOptions): StrokeTriangulatedResult;
|
|
165
|
-
toTriangulatedSVGString(result?: FillTriangulatedResult | StrokeTriangulatedResult, padding?: number): string;
|
|
166
|
-
toTriangulatedSVG(result?: FillTriangulatedResult | StrokeTriangulatedResult, padding?: number): SVGElement;
|
|
167
167
|
toCommands(): Path2DCommand[];
|
|
168
168
|
toData(): Path2DData;
|
|
169
169
|
drawTo(ctx: CanvasRenderingContext2D): this;
|
|
@@ -225,6 +225,7 @@ declare class CompositeCurve<T extends Curve = Curve> extends Curve {
|
|
|
225
225
|
protected _removeNextPointIfEqualPrevPoint(output: number[], offset: number): number[];
|
|
226
226
|
getSpacedPointArray(count?: number, output?: number[]): number[];
|
|
227
227
|
getAdaptivePointArray(output?: number[]): number[];
|
|
228
|
+
strokeTriangulate(options?: StrokeTriangulateOptions): StrokeTriangulatedResult;
|
|
228
229
|
fillTriangulate(options?: FillTriangulateOptions): FillTriangulatedResult;
|
|
229
230
|
applyTransform(transform: Matrix3 | ((point: Vector2) => void)): this;
|
|
230
231
|
getMinMax(min?: Vector2, max?: Vector2): {
|
|
@@ -498,6 +499,7 @@ declare class Path2D extends CompositeCurve<CurvePath> {
|
|
|
498
499
|
max: Vector2;
|
|
499
500
|
};
|
|
500
501
|
strokeTriangulate(options?: StrokeTriangulateOptions): StrokeTriangulatedResult;
|
|
502
|
+
fillTriangulate(options?: FillTriangulateOptions): FillTriangulatedResult;
|
|
501
503
|
getBoundingBox(withStyle?: boolean): BoundingBox;
|
|
502
504
|
drawTo(ctx: CanvasRenderingContext2D, style?: Partial<Path2DStyle>): this;
|
|
503
505
|
drawControlPointsTo(ctx: CanvasRenderingContext2D, style?: Partial<Path2DStyle>): this;
|
|
@@ -512,6 +514,8 @@ declare class Path2DSet {
|
|
|
512
514
|
viewBox?: number[] | undefined;
|
|
513
515
|
constructor(paths?: Path2D[], viewBox?: number[] | undefined);
|
|
514
516
|
getBoundingBox(withStyle?: boolean): BoundingBox | undefined;
|
|
517
|
+
toTriangulatedSVGString(result?: FillTriangulatedResult | StrokeTriangulatedResult | (FillTriangulatedResult | StrokeTriangulatedResult)[], padding?: number): string;
|
|
518
|
+
toTriangulatedSVG(result?: FillTriangulatedResult | StrokeTriangulatedResult | (FillTriangulatedResult | StrokeTriangulatedResult)[], padding?: number): SVGElement;
|
|
515
519
|
toSVGString(): string;
|
|
516
520
|
toSVGUrl(): string;
|
|
517
521
|
toSVG(): SVGElement;
|