modern-path2d 1.2.19 → 1.3.1
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 +208 -220
- package/dist/index.d.cts +16 -1
- package/dist/index.d.mts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +208 -222
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -56,6 +56,11 @@ class Vector2 {
|
|
|
56
56
|
get array() {
|
|
57
57
|
return [this.x, this.y];
|
|
58
58
|
}
|
|
59
|
+
finite() {
|
|
60
|
+
this.x = Number.isFinite(this.x) ? this.x : 0;
|
|
61
|
+
this.y = Number.isFinite(this.y) ? this.y : 0;
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
59
64
|
set(x, y) {
|
|
60
65
|
this.x = x;
|
|
61
66
|
this.y = y;
|
|
@@ -1746,7 +1751,7 @@ class Curve {
|
|
|
1746
1751
|
min.min(p);
|
|
1747
1752
|
max.max(p);
|
|
1748
1753
|
}
|
|
1749
|
-
return { min, max };
|
|
1754
|
+
return { min: min.finite(), max: max.finite() };
|
|
1750
1755
|
}
|
|
1751
1756
|
getBoundingBox() {
|
|
1752
1757
|
const { min, max } = this.getMinMax();
|
|
@@ -1782,7 +1787,7 @@ class Curve {
|
|
|
1782
1787
|
const p1 = getPoint(indices[i]);
|
|
1783
1788
|
const p2 = getPoint(indices[i + 1]);
|
|
1784
1789
|
const p3 = getPoint(indices[i + 2]);
|
|
1785
|
-
polygonStr += `<polygon points="${p1.join(",")} ${p2.join(",")} ${p3.join(",")}" fill="none" stroke="black" />`;
|
|
1790
|
+
polygonStr += `<polygon points="${p1.join(",")} ${p2.join(",")} ${p3.join(",")}" fill="none" stroke="black" stroke-width="0.5" stroke-linecap="round" stroke-linejoin="round" />`;
|
|
1786
1791
|
}
|
|
1787
1792
|
const viewBox = [min.x, min.y, max.x - min.x, max.y - min.y];
|
|
1788
1793
|
return `<svg width="${viewBox[2]}" height="${viewBox[3]}" viewBox="${viewBox.join(" ")}" xmlns="http://www.w3.org/2000/svg">${polygonStr}</svg>`;
|
|
@@ -1965,76 +1970,24 @@ class RoundCurve extends Curve {
|
|
|
1965
1970
|
return [this._center];
|
|
1966
1971
|
}
|
|
1967
1972
|
getAdaptivePointArray(output = []) {
|
|
1968
|
-
const { cx, cy, rx, ry,
|
|
1969
|
-
if (!(rx >= 0 && ry >= 0
|
|
1970
|
-
return output;
|
|
1971
|
-
}
|
|
1972
|
-
const n = Math.ceil(2.3 * Math.sqrt(rx + ry));
|
|
1973
|
-
const x = cx;
|
|
1974
|
-
const y = cy;
|
|
1975
|
-
const m = n * 8 + (dx ? 4 : 0) + (dy ? 4 : 0);
|
|
1976
|
-
if (m === 0) {
|
|
1973
|
+
const { cx, cy, rx, ry, startAngle, endAngle, clockwise } = this;
|
|
1974
|
+
if (!(rx >= 0 && ry >= 0)) {
|
|
1977
1975
|
return output;
|
|
1978
1976
|
}
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
let
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
let x2 = x - x0;
|
|
1994
|
-
let y1 = y + y0;
|
|
1995
|
-
output[j1++] = x1;
|
|
1996
|
-
output[j1++] = y1;
|
|
1997
|
-
output[--j2] = y1;
|
|
1998
|
-
output[--j2] = x2;
|
|
1999
|
-
if (dy) {
|
|
2000
|
-
const y22 = y - y0;
|
|
2001
|
-
output[j3++] = x2;
|
|
2002
|
-
output[j3++] = y22;
|
|
2003
|
-
output[--j4] = y22;
|
|
2004
|
-
output[--j4] = x1;
|
|
2005
|
-
}
|
|
2006
|
-
for (let i = 1; i < n; i++) {
|
|
2007
|
-
const a = Math.PI / 2 * (i / n);
|
|
2008
|
-
const x02 = dx + Math.cos(a) * rx;
|
|
2009
|
-
const y02 = dy + Math.sin(a) * ry;
|
|
2010
|
-
const x12 = x + x02;
|
|
2011
|
-
const x22 = x - x02;
|
|
2012
|
-
const y12 = y + y02;
|
|
2013
|
-
const y22 = y - y02;
|
|
2014
|
-
output[j1++] = x12;
|
|
2015
|
-
output[j1++] = y12;
|
|
2016
|
-
output[--j2] = y12;
|
|
2017
|
-
output[--j2] = x22;
|
|
2018
|
-
output[j3++] = x22;
|
|
2019
|
-
output[j3++] = y22;
|
|
2020
|
-
output[--j4] = y22;
|
|
2021
|
-
output[--j4] = x12;
|
|
2022
|
-
}
|
|
2023
|
-
x0 = dx;
|
|
2024
|
-
y0 = dy + ry;
|
|
2025
|
-
x1 = x + x0;
|
|
2026
|
-
x2 = x - x0;
|
|
2027
|
-
y1 = y + y0;
|
|
2028
|
-
const y2 = y - y0;
|
|
2029
|
-
output[j1++] = x1;
|
|
2030
|
-
output[j1++] = y1;
|
|
2031
|
-
output[--j4] = y2;
|
|
2032
|
-
output[--j4] = x1;
|
|
2033
|
-
if (dx) {
|
|
2034
|
-
output[j1++] = x2;
|
|
2035
|
-
output[j1++] = y1;
|
|
2036
|
-
output[--j4] = y2;
|
|
2037
|
-
output[--j4] = x2;
|
|
1977
|
+
let deltaAngle = endAngle - startAngle;
|
|
1978
|
+
if (!clockwise && deltaAngle > 0) {
|
|
1979
|
+
deltaAngle -= 2 * Math.PI;
|
|
1980
|
+
} else if (clockwise && deltaAngle < 0) {
|
|
1981
|
+
deltaAngle += 2 * Math.PI;
|
|
1982
|
+
}
|
|
1983
|
+
const arcLength = Math.abs(deltaAngle);
|
|
1984
|
+
const n = Math.max(1, Math.ceil(arcLength / (Math.PI / 16)));
|
|
1985
|
+
for (let i = 0; i <= n; i++) {
|
|
1986
|
+
const t = i / n;
|
|
1987
|
+
const angle = startAngle + deltaAngle * t;
|
|
1988
|
+
const x = cx + Math.cos(angle) * rx;
|
|
1989
|
+
const y = cy + Math.sin(angle) * ry;
|
|
1990
|
+
output.push(x, y);
|
|
2038
1991
|
}
|
|
2039
1992
|
return output;
|
|
2040
1993
|
}
|
|
@@ -2094,7 +2047,7 @@ class RoundCurve extends Curve {
|
|
|
2094
2047
|
min.y = Math.min(min.y, cy - halfHeight);
|
|
2095
2048
|
max.x = Math.max(max.x, cx + halfWidth);
|
|
2096
2049
|
max.y = Math.max(max.y, cy + halfHeight);
|
|
2097
|
-
return { min, max };
|
|
2050
|
+
return { min: min.finite(), max: max.finite() };
|
|
2098
2051
|
}
|
|
2099
2052
|
copy(source) {
|
|
2100
2053
|
super.copy(source);
|
|
@@ -2300,121 +2253,6 @@ class ArcCurve extends RoundCurve {
|
|
|
2300
2253
|
}
|
|
2301
2254
|
}
|
|
2302
2255
|
|
|
2303
|
-
class LineCurve extends Curve {
|
|
2304
|
-
constructor(p1 = new Vector2(), p2 = new Vector2()) {
|
|
2305
|
-
super();
|
|
2306
|
-
this.p1 = p1;
|
|
2307
|
-
this.p2 = p2;
|
|
2308
|
-
}
|
|
2309
|
-
static from(p1x, p1y, p2x, p2y) {
|
|
2310
|
-
return new LineCurve(
|
|
2311
|
-
new Vector2(p1x, p1y),
|
|
2312
|
-
new Vector2(p2x, p2y)
|
|
2313
|
-
);
|
|
2314
|
-
}
|
|
2315
|
-
getPoint(t, output = new Vector2()) {
|
|
2316
|
-
if (t === 1) {
|
|
2317
|
-
output.copy(this.p2);
|
|
2318
|
-
} else {
|
|
2319
|
-
output.copy(this.p2).sub(this.p1).scale(t).add(this.p1);
|
|
2320
|
-
}
|
|
2321
|
-
return output;
|
|
2322
|
-
}
|
|
2323
|
-
getPointAt(u, output = new Vector2()) {
|
|
2324
|
-
return this.getPoint(u, output);
|
|
2325
|
-
}
|
|
2326
|
-
getTangent(_t, output = new Vector2()) {
|
|
2327
|
-
return output.subVectors(this.p2, this.p1).normalize();
|
|
2328
|
-
}
|
|
2329
|
-
getTangentAt(u, output = new Vector2()) {
|
|
2330
|
-
return this.getTangent(u, output);
|
|
2331
|
-
}
|
|
2332
|
-
getControlPointRefs() {
|
|
2333
|
-
return [this.p1, this.p2];
|
|
2334
|
-
}
|
|
2335
|
-
getAdaptivePointArray(output = []) {
|
|
2336
|
-
output.push(
|
|
2337
|
-
this.p1.x,
|
|
2338
|
-
this.p1.y,
|
|
2339
|
-
this.p2.x,
|
|
2340
|
-
this.p2.y
|
|
2341
|
-
);
|
|
2342
|
-
return output;
|
|
2343
|
-
}
|
|
2344
|
-
getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
|
|
2345
|
-
const { p1, p2 } = this;
|
|
2346
|
-
min.x = Math.min(min.x, p1.x, p2.x);
|
|
2347
|
-
min.y = Math.min(min.y, p1.y, p2.y);
|
|
2348
|
-
max.x = Math.max(max.x, p1.x, p2.x);
|
|
2349
|
-
max.y = Math.max(max.y, p1.y, p2.y);
|
|
2350
|
-
return { min, max };
|
|
2351
|
-
}
|
|
2352
|
-
toCommands() {
|
|
2353
|
-
const { p1, p2 } = this;
|
|
2354
|
-
return [
|
|
2355
|
-
{ type: "M", x: p1.x, y: p1.y },
|
|
2356
|
-
{ type: "L", x: p2.x, y: p2.y }
|
|
2357
|
-
];
|
|
2358
|
-
}
|
|
2359
|
-
fillTriangulate(options = {}) {
|
|
2360
|
-
let {
|
|
2361
|
-
vertices = [],
|
|
2362
|
-
indices = [],
|
|
2363
|
-
verticesStride = 2,
|
|
2364
|
-
verticesOffset = vertices.length / verticesStride,
|
|
2365
|
-
indicesOffset = indices.length
|
|
2366
|
-
} = options;
|
|
2367
|
-
const x = this.p1.x;
|
|
2368
|
-
const y = this.p1.y;
|
|
2369
|
-
const width = this.p2.x - this.p1.x || 1;
|
|
2370
|
-
const height = this.p2.y - this.p2.y || 1;
|
|
2371
|
-
const points = [
|
|
2372
|
-
x,
|
|
2373
|
-
y,
|
|
2374
|
-
x + width,
|
|
2375
|
-
y,
|
|
2376
|
-
x + width,
|
|
2377
|
-
y + height,
|
|
2378
|
-
x,
|
|
2379
|
-
y + height
|
|
2380
|
-
];
|
|
2381
|
-
let count = 0;
|
|
2382
|
-
verticesOffset *= verticesStride;
|
|
2383
|
-
vertices[verticesOffset + count] = points[0];
|
|
2384
|
-
vertices[verticesOffset + count + 1] = points[1];
|
|
2385
|
-
count += verticesStride;
|
|
2386
|
-
vertices[verticesOffset + count] = points[2];
|
|
2387
|
-
vertices[verticesOffset + count + 1] = points[3];
|
|
2388
|
-
count += verticesStride;
|
|
2389
|
-
vertices[verticesOffset + count] = points[6];
|
|
2390
|
-
vertices[verticesOffset + count + 1] = points[7];
|
|
2391
|
-
count += verticesStride;
|
|
2392
|
-
vertices[verticesOffset + count] = points[4];
|
|
2393
|
-
vertices[verticesOffset + count + 1] = points[5];
|
|
2394
|
-
count += verticesStride;
|
|
2395
|
-
const verticesIndex = verticesOffset / verticesStride;
|
|
2396
|
-
indices[indicesOffset++] = verticesIndex;
|
|
2397
|
-
indices[indicesOffset++] = verticesIndex + 1;
|
|
2398
|
-
indices[indicesOffset++] = verticesIndex + 2;
|
|
2399
|
-
indices[indicesOffset++] = verticesIndex + 1;
|
|
2400
|
-
indices[indicesOffset++] = verticesIndex + 3;
|
|
2401
|
-
indices[indicesOffset++] = verticesIndex + 2;
|
|
2402
|
-
return { vertices, indices };
|
|
2403
|
-
}
|
|
2404
|
-
drawTo(ctx) {
|
|
2405
|
-
const { p1, p2 } = this;
|
|
2406
|
-
ctx.lineTo(p1.x, p1.y);
|
|
2407
|
-
ctx.lineTo(p2.x, p2.y);
|
|
2408
|
-
return this;
|
|
2409
|
-
}
|
|
2410
|
-
copy(source) {
|
|
2411
|
-
super.copy(source);
|
|
2412
|
-
this.p1.copy(source.p1);
|
|
2413
|
-
this.p2.copy(source.p2);
|
|
2414
|
-
return this;
|
|
2415
|
-
}
|
|
2416
|
-
}
|
|
2417
|
-
|
|
2418
2256
|
class CompositeCurve extends Curve {
|
|
2419
2257
|
constructor(curves = []) {
|
|
2420
2258
|
super();
|
|
@@ -2492,39 +2330,13 @@ class CompositeCurve extends Curve {
|
|
|
2492
2330
|
fillTriangulate(options) {
|
|
2493
2331
|
const indices = options?.indices ?? [];
|
|
2494
2332
|
const vertices = options?.vertices ?? [];
|
|
2495
|
-
const lines = [];
|
|
2496
|
-
const fillLines = () => {
|
|
2497
|
-
if (lines.length) {
|
|
2498
|
-
const pointArray = [];
|
|
2499
|
-
lines.forEach((line) => {
|
|
2500
|
-
const x = line.p1.x;
|
|
2501
|
-
const y = line.p1.y;
|
|
2502
|
-
if (pointArray[pointArray.length - 2] !== x || pointArray[pointArray.length - 1] !== y) {
|
|
2503
|
-
pointArray.push(x, y);
|
|
2504
|
-
}
|
|
2505
|
-
pointArray.push(line.p2.x, line.p2.y);
|
|
2506
|
-
});
|
|
2507
|
-
fillTriangulate(pointArray, {
|
|
2508
|
-
...options,
|
|
2509
|
-
indices,
|
|
2510
|
-
vertices
|
|
2511
|
-
});
|
|
2512
|
-
lines.length = 0;
|
|
2513
|
-
}
|
|
2514
|
-
};
|
|
2515
2333
|
this.curves.forEach((curve) => {
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
...options,
|
|
2522
|
-
indices,
|
|
2523
|
-
vertices
|
|
2524
|
-
});
|
|
2525
|
-
}
|
|
2334
|
+
curve.fillTriangulate({
|
|
2335
|
+
...options,
|
|
2336
|
+
indices,
|
|
2337
|
+
vertices
|
|
2338
|
+
});
|
|
2526
2339
|
});
|
|
2527
|
-
fillLines();
|
|
2528
2340
|
return { indices, vertices };
|
|
2529
2341
|
}
|
|
2530
2342
|
applyTransform(transform) {
|
|
@@ -2533,7 +2345,7 @@ class CompositeCurve extends Curve {
|
|
|
2533
2345
|
}
|
|
2534
2346
|
getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
|
|
2535
2347
|
this.curves.forEach((curve) => curve.getMinMax(min, max));
|
|
2536
|
-
return { min, max };
|
|
2348
|
+
return { min: min.finite(), max: max.finite() };
|
|
2537
2349
|
}
|
|
2538
2350
|
getBoundingBox() {
|
|
2539
2351
|
const { min, max } = this.getMinMax();
|
|
@@ -2633,7 +2445,7 @@ class CubicBezierCurve extends Curve {
|
|
|
2633
2445
|
}
|
|
2634
2446
|
};
|
|
2635
2447
|
samplePoints(tValues, 10);
|
|
2636
|
-
return { min, max };
|
|
2448
|
+
return { min: min.finite(), max: max.finite() };
|
|
2637
2449
|
}
|
|
2638
2450
|
toCommands() {
|
|
2639
2451
|
const { p1, cp1, cp2, p2 } = this;
|
|
@@ -2685,6 +2497,125 @@ class EllipseCurve extends RoundCurve {
|
|
|
2685
2497
|
}
|
|
2686
2498
|
}
|
|
2687
2499
|
|
|
2500
|
+
class LineCurve extends Curve {
|
|
2501
|
+
constructor(p1 = new Vector2(), p2 = new Vector2()) {
|
|
2502
|
+
super();
|
|
2503
|
+
this.p1 = p1;
|
|
2504
|
+
this.p2 = p2;
|
|
2505
|
+
}
|
|
2506
|
+
static from(p1x, p1y, p2x, p2y) {
|
|
2507
|
+
return new LineCurve(
|
|
2508
|
+
new Vector2(p1x, p1y),
|
|
2509
|
+
new Vector2(p2x, p2y)
|
|
2510
|
+
);
|
|
2511
|
+
}
|
|
2512
|
+
getPoint(t, output = new Vector2()) {
|
|
2513
|
+
if (t === 1) {
|
|
2514
|
+
output.copy(this.p2);
|
|
2515
|
+
} else {
|
|
2516
|
+
output.copy(this.p2).sub(this.p1).scale(t).add(this.p1);
|
|
2517
|
+
}
|
|
2518
|
+
return output;
|
|
2519
|
+
}
|
|
2520
|
+
getPointAt(u, output = new Vector2()) {
|
|
2521
|
+
return this.getPoint(u, output);
|
|
2522
|
+
}
|
|
2523
|
+
getTangent(_t, output = new Vector2()) {
|
|
2524
|
+
return output.subVectors(this.p2, this.p1).normalize();
|
|
2525
|
+
}
|
|
2526
|
+
getTangentAt(u, output = new Vector2()) {
|
|
2527
|
+
return this.getTangent(u, output);
|
|
2528
|
+
}
|
|
2529
|
+
getControlPointRefs() {
|
|
2530
|
+
return [this.p1, this.p2];
|
|
2531
|
+
}
|
|
2532
|
+
getAdaptivePointArray(output = []) {
|
|
2533
|
+
output.push(
|
|
2534
|
+
this.p1.x,
|
|
2535
|
+
this.p1.y,
|
|
2536
|
+
this.p2.x,
|
|
2537
|
+
this.p2.y
|
|
2538
|
+
);
|
|
2539
|
+
return output;
|
|
2540
|
+
}
|
|
2541
|
+
getMinMax(min = Vector2.MAX, max = Vector2.MIN) {
|
|
2542
|
+
const { p1, p2 } = this;
|
|
2543
|
+
min.x = Math.min(min.x, p1.x, p2.x);
|
|
2544
|
+
min.y = Math.min(min.y, p1.y, p2.y);
|
|
2545
|
+
max.x = Math.max(max.x, p1.x, p2.x);
|
|
2546
|
+
max.y = Math.max(max.y, p1.y, p2.y);
|
|
2547
|
+
return { min: min.finite(), max: max.finite() };
|
|
2548
|
+
}
|
|
2549
|
+
toCommands() {
|
|
2550
|
+
const { p1, p2 } = this;
|
|
2551
|
+
return [
|
|
2552
|
+
{ type: "M", x: p1.x, y: p1.y },
|
|
2553
|
+
{ type: "L", x: p2.x, y: p2.y }
|
|
2554
|
+
];
|
|
2555
|
+
}
|
|
2556
|
+
fillTriangulate(options = {}) {
|
|
2557
|
+
let {
|
|
2558
|
+
vertices = [],
|
|
2559
|
+
indices = [],
|
|
2560
|
+
verticesStride = 2,
|
|
2561
|
+
verticesOffset = vertices.length / verticesStride,
|
|
2562
|
+
indicesOffset = indices.length
|
|
2563
|
+
} = options;
|
|
2564
|
+
const minX = Math.min(this.p1.x, this.p2.x);
|
|
2565
|
+
const maxX = Math.max(this.p1.x, this.p2.x);
|
|
2566
|
+
const minY = Math.min(this.p1.y, this.p2.y);
|
|
2567
|
+
const maxY = Math.max(this.p1.y, this.p2.y);
|
|
2568
|
+
const x = minX;
|
|
2569
|
+
const y = minY;
|
|
2570
|
+
const width = maxX - minX;
|
|
2571
|
+
const height = maxY - minY;
|
|
2572
|
+
const points = [
|
|
2573
|
+
x,
|
|
2574
|
+
y,
|
|
2575
|
+
x + width,
|
|
2576
|
+
y,
|
|
2577
|
+
x + width,
|
|
2578
|
+
y + height,
|
|
2579
|
+
x,
|
|
2580
|
+
y + height
|
|
2581
|
+
];
|
|
2582
|
+
let count = 0;
|
|
2583
|
+
verticesOffset *= verticesStride;
|
|
2584
|
+
vertices[verticesOffset + count] = points[0];
|
|
2585
|
+
vertices[verticesOffset + count + 1] = points[1];
|
|
2586
|
+
count += verticesStride;
|
|
2587
|
+
vertices[verticesOffset + count] = points[2];
|
|
2588
|
+
vertices[verticesOffset + count + 1] = points[3];
|
|
2589
|
+
count += verticesStride;
|
|
2590
|
+
vertices[verticesOffset + count] = points[6];
|
|
2591
|
+
vertices[verticesOffset + count + 1] = points[7];
|
|
2592
|
+
count += verticesStride;
|
|
2593
|
+
vertices[verticesOffset + count] = points[4];
|
|
2594
|
+
vertices[verticesOffset + count + 1] = points[5];
|
|
2595
|
+
count += verticesStride;
|
|
2596
|
+
const verticesIndex = verticesOffset / verticesStride;
|
|
2597
|
+
indices[indicesOffset++] = verticesIndex;
|
|
2598
|
+
indices[indicesOffset++] = verticesIndex + 1;
|
|
2599
|
+
indices[indicesOffset++] = verticesIndex + 2;
|
|
2600
|
+
indices[indicesOffset++] = verticesIndex + 1;
|
|
2601
|
+
indices[indicesOffset++] = verticesIndex + 3;
|
|
2602
|
+
indices[indicesOffset++] = verticesIndex + 2;
|
|
2603
|
+
return { vertices, indices };
|
|
2604
|
+
}
|
|
2605
|
+
drawTo(ctx) {
|
|
2606
|
+
const { p1, p2 } = this;
|
|
2607
|
+
ctx.lineTo(p1.x, p1.y);
|
|
2608
|
+
ctx.lineTo(p2.x, p2.y);
|
|
2609
|
+
return this;
|
|
2610
|
+
}
|
|
2611
|
+
copy(source) {
|
|
2612
|
+
super.copy(source);
|
|
2613
|
+
this.p1.copy(source.p1);
|
|
2614
|
+
this.p2.copy(source.p2);
|
|
2615
|
+
return this;
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2618
|
+
|
|
2688
2619
|
class PloygonCurve extends CompositeCurve {
|
|
2689
2620
|
//
|
|
2690
2621
|
}
|
|
@@ -2780,7 +2711,7 @@ class QuadraticBezierCurve extends Curve {
|
|
|
2780
2711
|
min.y = Math.min(min.y, p1.y, p2.y, y1, y2);
|
|
2781
2712
|
max.x = Math.max(max.x, p1.x, p2.x, x1, x2);
|
|
2782
2713
|
max.y = Math.max(max.y, p1.y, p2.y, y1, y2);
|
|
2783
|
-
return { min, max };
|
|
2714
|
+
return { min: min.finite(), max: max.finite() };
|
|
2784
2715
|
}
|
|
2785
2716
|
toCommands() {
|
|
2786
2717
|
const { p1, cp, p2 } = this;
|
|
@@ -3422,7 +3353,7 @@ class Path2D extends CompositeCurve {
|
|
|
3422
3353
|
}
|
|
3423
3354
|
}
|
|
3424
3355
|
});
|
|
3425
|
-
return { min, max };
|
|
3356
|
+
return { min: min.finite(), max: max.finite() };
|
|
3426
3357
|
}
|
|
3427
3358
|
strokeTriangulate(options) {
|
|
3428
3359
|
const indices = options?.indices ?? [];
|
|
@@ -3558,6 +3489,61 @@ class Path2DSet {
|
|
|
3558
3489
|
}
|
|
3559
3490
|
}
|
|
3560
3491
|
|
|
3492
|
+
class FFDControlGrid {
|
|
3493
|
+
constructor(rows, cols, width = 1, height = 1) {
|
|
3494
|
+
this.rows = rows;
|
|
3495
|
+
this.cols = cols;
|
|
3496
|
+
this.width = width;
|
|
3497
|
+
this.height = height;
|
|
3498
|
+
for (let i = 0; i < rows; i++) {
|
|
3499
|
+
this.controlPoints[i] = [];
|
|
3500
|
+
for (let j = 0; j < cols; j++) {
|
|
3501
|
+
this.controlPoints[i][j] = {
|
|
3502
|
+
x: j / (cols - 1) * width,
|
|
3503
|
+
y: i / (rows - 1) * height
|
|
3504
|
+
};
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
}
|
|
3508
|
+
controlPoints = [];
|
|
3509
|
+
moveControlPoint(i, j, dx, dy) {
|
|
3510
|
+
this.controlPoints[i][j].x += dx;
|
|
3511
|
+
this.controlPoints[i][j].y += dy;
|
|
3512
|
+
return this;
|
|
3513
|
+
}
|
|
3514
|
+
}
|
|
3515
|
+
function bsplineBasis(t) {
|
|
3516
|
+
const B = [];
|
|
3517
|
+
B[0] = (1 - t) ** 3 / 6;
|
|
3518
|
+
B[1] = (3 * t ** 3 - 6 * t ** 2 + 4) / 6;
|
|
3519
|
+
B[2] = (-3 * t ** 3 + 3 * t ** 2 + 3 * t + 1) / 6;
|
|
3520
|
+
B[3] = t ** 3 / 6;
|
|
3521
|
+
return B;
|
|
3522
|
+
}
|
|
3523
|
+
function applyFFD(point, grid, width = grid.width, height = grid.height) {
|
|
3524
|
+
const s = point.x / width * (grid.cols - 1);
|
|
3525
|
+
const t = point.y / height * (grid.rows - 1);
|
|
3526
|
+
const i = Math.floor(s);
|
|
3527
|
+
const j = Math.floor(t);
|
|
3528
|
+
const u = s - i;
|
|
3529
|
+
const v = t - j;
|
|
3530
|
+
const bu = bsplineBasis(u);
|
|
3531
|
+
const bv = bsplineBasis(v);
|
|
3532
|
+
let x = 0;
|
|
3533
|
+
let y = 0;
|
|
3534
|
+
for (let m = 0; m < 4; m++) {
|
|
3535
|
+
for (let n = 0; n < 4; n++) {
|
|
3536
|
+
const row = Math.min(Math.max(j - 1 + m, 0), grid.rows - 1);
|
|
3537
|
+
const col = Math.min(Math.max(i - 1 + n, 0), grid.cols - 1);
|
|
3538
|
+
const cp = grid.controlPoints[row][col];
|
|
3539
|
+
const weight = bu[n] * bv[m];
|
|
3540
|
+
x += cp.x * weight;
|
|
3541
|
+
y += cp.y * weight;
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3544
|
+
point.set(x, y);
|
|
3545
|
+
}
|
|
3546
|
+
|
|
3561
3547
|
const dataUri = "data:image/svg+xml;";
|
|
3562
3548
|
const base64DataUri = `${dataUri}base64,`;
|
|
3563
3549
|
const utf8DataUri = `${dataUri}charset=utf8,`;
|
|
@@ -4087,4 +4073,4 @@ function svgToPath2DSet(svg) {
|
|
|
4087
4073
|
);
|
|
4088
4074
|
}
|
|
4089
4075
|
|
|
4090
|
-
export { ArcCurve, BoundingBox, CompositeCurve, CubicBezierCurve, Curve, CurvePath, EllipseCurve, EquilateralPloygonCurve, LineCurve, Matrix3, Path2D, Path2DSet, PloygonCurve, QuadraticBezierCurve, RectangleCurve, RoundRectangleCurve, SplineCurve, Vector2, catmullRom, cubicBezier, drawPoint, fillTriangulate, getAdaptiveCubicBezierCurvePoints, getAdaptiveQuadraticBezierCurvePoints, parseArcCommand, parsePathDataArgs, quadraticBezier, setCanvasContext, strokeTriangulate, svgPathCommandsAddToPath2D, svgPathCommandsToData, svgPathDataToCommands, svgToDOM, svgToPath2DSet };
|
|
4076
|
+
export { ArcCurve, BoundingBox, CompositeCurve, CubicBezierCurve, Curve, CurvePath, EllipseCurve, EquilateralPloygonCurve, FFDControlGrid, LineCurve, Matrix3, Path2D, Path2DSet, PloygonCurve, QuadraticBezierCurve, RectangleCurve, RoundRectangleCurve, SplineCurve, Vector2, applyFFD, catmullRom, cubicBezier, drawPoint, fillTriangulate, getAdaptiveCubicBezierCurvePoints, getAdaptiveQuadraticBezierCurvePoints, parseArcCommand, parsePathDataArgs, quadraticBezier, setCanvasContext, strokeTriangulate, svgPathCommandsAddToPath2D, svgPathCommandsToData, svgPathDataToCommands, svgToDOM, svgToPath2DSet };
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "modern-path2d",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.1",
|
|
5
5
|
"packageManager": "pnpm@9.15.1",
|
|
6
|
-
"description": "A
|
|
6
|
+
"description": "A Path2D library, fully compatible with Web Path2D, with additional support for triangulate、animation、deformation etc.",
|
|
7
7
|
"author": "wxm",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"homepage": "https://github.com/qq15725/modern-path2d",
|