@pixerate/editor 0.33.0 → 0.35.0
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/THIRD_PARTY_NOTICES.md +22 -0
- package/dist/{bezier-DJPYiVbA.d.ts → bezier-BvqVmWMg.d.ts} +1 -1
- package/dist/{bezier-6KPx3w7Z.d.cts → bezier-D8bsO-L0.d.cts} +1 -1
- package/dist/canvas/index.cjs +179 -622
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +60 -3
- package/dist/canvas/index.d.ts +60 -3
- package/dist/canvas/index.js +37 -480
- package/dist/canvas/index.js.map +1 -1
- package/dist/{chunk-M4XE4UMT.cjs → chunk-BGNPT5PE.cjs} +464 -5
- package/dist/chunk-BGNPT5PE.cjs.map +1 -0
- package/dist/{chunk-GQTXV2EQ.js → chunk-EGPIVUEF.js} +470 -11
- package/dist/chunk-EGPIVUEF.js.map +1 -0
- package/dist/vector/index.cjs +2776 -185
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +638 -10
- package/dist/vector/index.d.ts +638 -10
- package/dist/vector/index.js +2644 -53
- package/dist/vector/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-GQTXV2EQ.js.map +0 -1
- package/dist/chunk-M4XE4UMT.cjs.map +0 -1
package/dist/canvas/index.js
CHANGED
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
CANVAS_GRADIENT_PRESETS,
|
|
3
3
|
PathOpsError,
|
|
4
4
|
SHAPE_KINDS,
|
|
5
|
-
add,
|
|
6
5
|
angleToSvgLinearCoords,
|
|
7
6
|
arcToCubics,
|
|
8
7
|
bezierPathArea,
|
|
@@ -15,20 +14,18 @@ import {
|
|
|
15
14
|
contourSignedArea,
|
|
16
15
|
contoursToPath,
|
|
17
16
|
countPathSegments,
|
|
18
|
-
cross,
|
|
19
17
|
cubicPointAt,
|
|
20
18
|
cubicsToPathData,
|
|
21
|
-
|
|
19
|
+
dashContours,
|
|
22
20
|
distanceToBezierPath,
|
|
23
21
|
dividePaths,
|
|
24
22
|
dividePolygons,
|
|
25
|
-
dot,
|
|
26
23
|
excludePaths,
|
|
27
24
|
fitCubicRun,
|
|
25
|
+
fitCubicWithTangents,
|
|
28
26
|
fitCubics,
|
|
29
27
|
fitFreehandPath,
|
|
30
28
|
fitPathData,
|
|
31
|
-
flattenChain,
|
|
32
29
|
flattenSvgPath,
|
|
33
30
|
formatNumber,
|
|
34
31
|
getShapeRenderData,
|
|
@@ -41,12 +38,12 @@ import {
|
|
|
41
38
|
isStraightCubic,
|
|
42
39
|
multiPolygonArea,
|
|
43
40
|
multiPolygonBounds,
|
|
44
|
-
nestedRingsToPath,
|
|
45
41
|
normalizeBezierPath,
|
|
42
|
+
offsetPath,
|
|
43
|
+
outlineStroke,
|
|
46
44
|
parseCssGradient,
|
|
47
45
|
parseSvgPath,
|
|
48
46
|
pathBoolean,
|
|
49
|
-
pathBooleanRings,
|
|
50
47
|
pathToContours,
|
|
51
48
|
pointInBezierPath,
|
|
52
49
|
pointInMultiPolygon,
|
|
@@ -56,12 +53,11 @@ import {
|
|
|
56
53
|
polygonToSvgPath,
|
|
57
54
|
resolveCanvasGradient,
|
|
58
55
|
ringSignedArea,
|
|
59
|
-
samePoint,
|
|
60
|
-
scale,
|
|
61
56
|
segmentBounds,
|
|
62
57
|
segmentCurvature,
|
|
63
58
|
segmentDerivative,
|
|
64
59
|
segmentExtrema,
|
|
60
|
+
segmentIntersections,
|
|
65
61
|
segmentLength,
|
|
66
62
|
segmentNearest,
|
|
67
63
|
segmentParamAtLength,
|
|
@@ -70,7 +66,7 @@ import {
|
|
|
70
66
|
shapeToPolygon,
|
|
71
67
|
simplifyRing,
|
|
72
68
|
splitSegment,
|
|
73
|
-
|
|
69
|
+
strokeOutlineRings,
|
|
74
70
|
subSegment,
|
|
75
71
|
subtractPaths,
|
|
76
72
|
subtractPolygons,
|
|
@@ -81,7 +77,7 @@ import {
|
|
|
81
77
|
unitePaths,
|
|
82
78
|
windingNumber,
|
|
83
79
|
xorPolygons
|
|
84
|
-
} from "../chunk-
|
|
80
|
+
} from "../chunk-EGPIVUEF.js";
|
|
85
81
|
import {
|
|
86
82
|
DEFAULT_NODE_HEIGHT,
|
|
87
83
|
DEFAULT_NODE_WIDTH,
|
|
@@ -183,11 +179,11 @@ function createFanOutTrajectory(options = {}) {
|
|
|
183
179
|
const oneMinusT = 1 - t;
|
|
184
180
|
const x = oneMinusT * oneMinusT * origin.x + 2 * oneMinusT * t * midX + t * t * target.x;
|
|
185
181
|
const y = oneMinusT * oneMinusT * origin.y + 2 * oneMinusT * t * midY + t * t * target.y;
|
|
186
|
-
const
|
|
182
|
+
const scale = startScale + (endScale - startScale) * progress;
|
|
187
183
|
const opacity = startOpacity + (endOpacity - startOpacity) * progress;
|
|
188
184
|
return {
|
|
189
185
|
position: { x, y },
|
|
190
|
-
scale
|
|
186
|
+
scale,
|
|
191
187
|
opacity
|
|
192
188
|
};
|
|
193
189
|
};
|
|
@@ -1214,7 +1210,7 @@ function spacingCandidate(rects, moving, horizontal, tolerance) {
|
|
|
1214
1210
|
return best2;
|
|
1215
1211
|
};
|
|
1216
1212
|
const crossMid = (a, b) => (Math.max(crossStart(a), crossStart(b)) + Math.min(crossEnd(a), crossEnd(b))) / 2;
|
|
1217
|
-
const segment = (from, to,
|
|
1213
|
+
const segment = (from, to, cross) => horizontal ? { orientation: "horizontal", kind: "spacing", x1: from, y1: cross, x2: to, y2: cross } : { orientation: "vertical", kind: "spacing", x1: cross, y1: from, x2: cross, y2: to };
|
|
1218
1214
|
const candidates = [];
|
|
1219
1215
|
if (before && after) {
|
|
1220
1216
|
const b = before;
|
|
@@ -1726,447 +1722,6 @@ function fitViewportToNodes(nodes, size, ids, options = {}) {
|
|
|
1726
1722
|
return bounds ? fitViewportToRect(bounds, size, options) : null;
|
|
1727
1723
|
}
|
|
1728
1724
|
|
|
1729
|
-
// src/canvas/pathops/stroke.ts
|
|
1730
|
-
var DEFAULT_TOLERANCE = 0.01;
|
|
1731
|
-
var normal = (t) => [-t[1], t[0]];
|
|
1732
|
-
function raise(seg) {
|
|
1733
|
-
if (seg.length !== 3) return [...seg];
|
|
1734
|
-
const [p0, p1, p2] = seg;
|
|
1735
|
-
return [p0, [p0[0] + 2 / 3 * (p1[0] - p0[0]), p0[1] + 2 / 3 * (p1[1] - p0[1])], [p2[0] + 2 / 3 * (p1[0] - p2[0]), p2[1] + 2 / 3 * (p1[1] - p2[1])], p2];
|
|
1736
|
-
}
|
|
1737
|
-
function isDegenerate(seg, tol) {
|
|
1738
|
-
return seg.every((p) => dist(p, seg[0]) <= tol);
|
|
1739
|
-
}
|
|
1740
|
-
function offsetSegment(seg, d, tol, out, depth = 0) {
|
|
1741
|
-
if (seg.length === 2) {
|
|
1742
|
-
const n = normal(segmentTangent(seg, 0));
|
|
1743
|
-
out.push([add(seg[0], scale(n, d)), add(seg[1], scale(n, d))]);
|
|
1744
|
-
return;
|
|
1745
|
-
}
|
|
1746
|
-
const c = raise(seg);
|
|
1747
|
-
const t0 = segmentTangent(c, 0);
|
|
1748
|
-
const t1 = segmentTangent(c, 1);
|
|
1749
|
-
const q0 = add(c[0], scale(normal(t0), d));
|
|
1750
|
-
const q3 = add(c[3], scale(normal(t1), d));
|
|
1751
|
-
const k0 = segmentCurvature(c, 0);
|
|
1752
|
-
const k1 = segmentCurvature(c, 1);
|
|
1753
|
-
const f0 = Number.isFinite(k0) ? 1 - d * k0 : 1;
|
|
1754
|
-
const f1 = Number.isFinite(k1) ? 1 - d * k1 : 1;
|
|
1755
|
-
const q1 = add(q0, scale(sub(c[1], c[0]), f0));
|
|
1756
|
-
const q2 = add(q3, scale(sub(c[2], c[3]), f1));
|
|
1757
|
-
const approx = [q0, q1, q2, q3];
|
|
1758
|
-
if (depth < 10) {
|
|
1759
|
-
let err = 0;
|
|
1760
|
-
for (const t of [0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875]) {
|
|
1761
|
-
const target = add(segmentPoint(c, t), scale(normal(segmentTangent(c, t)), d));
|
|
1762
|
-
err = Math.max(err, segmentNearest(approx, target).distance);
|
|
1763
|
-
if (err > tol) break;
|
|
1764
|
-
}
|
|
1765
|
-
if (err <= tol) {
|
|
1766
|
-
const m = segmentPoint(approx, 0.5);
|
|
1767
|
-
const back = segmentNearest(c, m).distance;
|
|
1768
|
-
err = Math.max(err, Math.abs(back - Math.abs(d)));
|
|
1769
|
-
}
|
|
1770
|
-
if (err > tol) {
|
|
1771
|
-
const [a, b] = splitSegment(c, 0.5);
|
|
1772
|
-
offsetSegment(a, d, tol, out, depth + 1);
|
|
1773
|
-
offsetSegment(b, d, tol, out, depth + 1);
|
|
1774
|
-
return;
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
out.push(approx);
|
|
1778
|
-
}
|
|
1779
|
-
function pushArc(out, center, radius, start, sweep, from, to) {
|
|
1780
|
-
const n = Math.max(1, Math.ceil(Math.abs(sweep) / (Math.PI / 2) - 1e-9));
|
|
1781
|
-
const step = sweep / n;
|
|
1782
|
-
const k = 4 / 3 * Math.tan(step / 4);
|
|
1783
|
-
let prev = from;
|
|
1784
|
-
for (let i = 0; i < n; i++) {
|
|
1785
|
-
const a0 = start + step * i;
|
|
1786
|
-
const a1 = a0 + step;
|
|
1787
|
-
const c0 = Math.cos(a0);
|
|
1788
|
-
const s0 = Math.sin(a0);
|
|
1789
|
-
const c1 = Math.cos(a1);
|
|
1790
|
-
const s1 = Math.sin(a1);
|
|
1791
|
-
const end = i === n - 1 ? to : [center[0] + radius * c1, center[1] + radius * s1];
|
|
1792
|
-
out.push([
|
|
1793
|
-
prev,
|
|
1794
|
-
[center[0] + radius * (c0 - k * s0), center[1] + radius * (s0 + k * c0)],
|
|
1795
|
-
[center[0] + radius * (c1 + k * s1), center[1] + radius * (s1 - k * c1)],
|
|
1796
|
-
end
|
|
1797
|
-
]);
|
|
1798
|
-
prev = end;
|
|
1799
|
-
}
|
|
1800
|
-
}
|
|
1801
|
-
function lineTo(out, from, to) {
|
|
1802
|
-
if (!samePoint(from, to)) out.push([from, to]);
|
|
1803
|
-
}
|
|
1804
|
-
function addJoin(out, p, tin, tout, d, style) {
|
|
1805
|
-
const from = add(p, scale(normal(tin), d));
|
|
1806
|
-
const to = add(p, scale(normal(tout), d));
|
|
1807
|
-
const turn = cross(tin, tout);
|
|
1808
|
-
const cos = dot(tin, tout);
|
|
1809
|
-
if (Math.abs(turn) < 1e-9 && cos > 0) {
|
|
1810
|
-
lineTo(out, from, to);
|
|
1811
|
-
return;
|
|
1812
|
-
}
|
|
1813
|
-
const reversal = Math.abs(turn) < 1e-9 && cos < 0;
|
|
1814
|
-
const inner = !reversal && turn > 0 === d > 0;
|
|
1815
|
-
if (inner) {
|
|
1816
|
-
lineTo(out, from, p);
|
|
1817
|
-
lineTo(out, p, to);
|
|
1818
|
-
return;
|
|
1819
|
-
}
|
|
1820
|
-
const theta = reversal ? d > 0 ? -Math.PI : Math.PI : Math.atan2(turn, cos);
|
|
1821
|
-
if (style.join === "round") {
|
|
1822
|
-
const v = sub(from, p);
|
|
1823
|
-
pushArc(out, p, Math.abs(d), Math.atan2(v[1], v[0]), theta, from, to);
|
|
1824
|
-
return;
|
|
1825
|
-
}
|
|
1826
|
-
if (style.join === "miter" && !reversal) {
|
|
1827
|
-
const phi = Math.PI - Math.abs(theta);
|
|
1828
|
-
const ratio = 1 / Math.max(Math.sin(phi / 2), 1e-12);
|
|
1829
|
-
if (ratio <= style.miterLimit) {
|
|
1830
|
-
const nin = normal(tin);
|
|
1831
|
-
const nout = normal(tout);
|
|
1832
|
-
const s = d / (1 + dot(nin, nout));
|
|
1833
|
-
const miter = add(p, scale(add(nin, nout), s));
|
|
1834
|
-
lineTo(out, from, miter);
|
|
1835
|
-
lineTo(out, miter, to);
|
|
1836
|
-
return;
|
|
1837
|
-
}
|
|
1838
|
-
}
|
|
1839
|
-
lineTo(out, from, to);
|
|
1840
|
-
}
|
|
1841
|
-
function offsetChain(segs, d, closed, style, tol) {
|
|
1842
|
-
const out = [];
|
|
1843
|
-
const pen = () => out.length > 0 ? out[out.length - 1][out[out.length - 1].length - 1] : null;
|
|
1844
|
-
for (let i = 0; i < segs.length; i++) {
|
|
1845
|
-
if (i > 0) addJoin(out, segs[i][0], segmentTangent(segs[i - 1], 1), segmentTangent(segs[i], 0), d, style);
|
|
1846
|
-
const pieces = [];
|
|
1847
|
-
offsetSegment(segs[i], d, tol, pieces);
|
|
1848
|
-
for (const piece of pieces) {
|
|
1849
|
-
const at = pen();
|
|
1850
|
-
if (at && !samePoint(at, piece[0])) lineTo(out, at, piece[0]);
|
|
1851
|
-
out.push(piece);
|
|
1852
|
-
}
|
|
1853
|
-
}
|
|
1854
|
-
if (closed && segs.length > 0) {
|
|
1855
|
-
const last = segs[segs.length - 1];
|
|
1856
|
-
addJoin(out, segs[0][0], segmentTangent(last, 1), segmentTangent(segs[0], 0), d, style);
|
|
1857
|
-
const at = pen();
|
|
1858
|
-
if (at && out.length > 0 && !samePoint(at, out[0][0])) lineTo(out, at, out[0][0]);
|
|
1859
|
-
}
|
|
1860
|
-
return out;
|
|
1861
|
-
}
|
|
1862
|
-
function reverseChain(chain) {
|
|
1863
|
-
return chain.map((s) => [...s].reverse()).reverse();
|
|
1864
|
-
}
|
|
1865
|
-
function addCap(out, p, t, h, cap) {
|
|
1866
|
-
const n = normal(t);
|
|
1867
|
-
const from = add(p, scale(n, h));
|
|
1868
|
-
const to = add(p, scale(n, -h));
|
|
1869
|
-
if (cap === "round") {
|
|
1870
|
-
pushArc(out, p, h, Math.atan2(n[1], n[0]), -Math.PI, from, to);
|
|
1871
|
-
} else if (cap === "square") {
|
|
1872
|
-
const a = add(from, scale(t, h));
|
|
1873
|
-
const b = add(to, scale(t, h));
|
|
1874
|
-
lineTo(out, from, a);
|
|
1875
|
-
lineTo(out, a, b);
|
|
1876
|
-
lineTo(out, b, to);
|
|
1877
|
-
} else {
|
|
1878
|
-
lineTo(out, from, to);
|
|
1879
|
-
}
|
|
1880
|
-
}
|
|
1881
|
-
function dotRings(p, t, h, cap) {
|
|
1882
|
-
if (cap === "butt") return [];
|
|
1883
|
-
const ring = [];
|
|
1884
|
-
addCap(ring, p, t, h, cap);
|
|
1885
|
-
addCap(ring, p, [-t[0], -t[1]], h, cap);
|
|
1886
|
-
return [ring];
|
|
1887
|
-
}
|
|
1888
|
-
function strokeContour(contour, h, style, tol) {
|
|
1889
|
-
const tiny = Math.max(1e-12, tol * 1e-6);
|
|
1890
|
-
const all = contour.closed ? closeContour(contour) : contour.segments;
|
|
1891
|
-
const segs = all.filter((s) => !isDegenerate(s, tiny));
|
|
1892
|
-
if (segs.length === 0) {
|
|
1893
|
-
const p = contour.segments[0]?.[0];
|
|
1894
|
-
return p ? dotRings(p, [1, 0], h, style.cap) : [];
|
|
1895
|
-
}
|
|
1896
|
-
if (contour.closed) {
|
|
1897
|
-
const left2 = offsetChain(segs, h, true, style, tol);
|
|
1898
|
-
const right2 = offsetChain(segs, -h, true, style, tol);
|
|
1899
|
-
return [left2, reverseChain(right2)];
|
|
1900
|
-
}
|
|
1901
|
-
const left = offsetChain(segs, h, false, style, tol);
|
|
1902
|
-
const right = reverseChain(offsetChain(segs, -h, false, style, tol));
|
|
1903
|
-
const ring = [...left];
|
|
1904
|
-
const last = segs[segs.length - 1];
|
|
1905
|
-
addCap(ring, last[last.length - 1], segmentTangent(last, 1), h, style.cap);
|
|
1906
|
-
const joinTo = (p) => {
|
|
1907
|
-
const at = ring[ring.length - 1][ring[ring.length - 1].length - 1];
|
|
1908
|
-
lineTo(ring, at, p);
|
|
1909
|
-
};
|
|
1910
|
-
if (right.length > 0) joinTo(right[0][0]);
|
|
1911
|
-
ring.push(...right);
|
|
1912
|
-
const first = segs[0];
|
|
1913
|
-
const t0 = segmentTangent(first, 0);
|
|
1914
|
-
addCap(ring, first[0], [-t0[0], -t0[1]], h, style.cap);
|
|
1915
|
-
if (ring.length > 0) joinTo(ring[0][0]);
|
|
1916
|
-
return [ring];
|
|
1917
|
-
}
|
|
1918
|
-
function ringsToPath(rings) {
|
|
1919
|
-
return contoursToPath(rings.filter((r) => r.length > 0).map((segments) => ({ segments, closed: true })));
|
|
1920
|
-
}
|
|
1921
|
-
var MAX_DASHES = 2e5;
|
|
1922
|
-
var MIN_ENTRY = 1e-6;
|
|
1923
|
-
function dashContours(contours, pattern, offset = 0) {
|
|
1924
|
-
if (pattern.length === 0 || pattern.some((v) => !Number.isFinite(v) || v < 0) || !Number.isFinite(offset)) return null;
|
|
1925
|
-
if (!pattern.some((v) => v > MIN_ENTRY)) return null;
|
|
1926
|
-
const pat = pattern.length % 2 === 1 ? [...pattern, ...pattern] : [...pattern];
|
|
1927
|
-
const period = pat.reduce((s, v) => s + v, 0);
|
|
1928
|
-
const chains = contours.map((c) => {
|
|
1929
|
-
const segs = closeContour(c);
|
|
1930
|
-
const lengths = segs.map((s) => segmentLength(s));
|
|
1931
|
-
return { segs, lengths, total: lengths.reduce((s, v) => s + v, 0), closed: c.closed };
|
|
1932
|
-
});
|
|
1933
|
-
const totalLength = chains.reduce((s, c) => s + c.total, 0);
|
|
1934
|
-
if (totalLength / period * pat.length > MAX_DASHES) return null;
|
|
1935
|
-
let off = (offset % period + period) % period;
|
|
1936
|
-
let ix0 = 0;
|
|
1937
|
-
while (off > pat[ix0]) {
|
|
1938
|
-
off -= pat[ix0];
|
|
1939
|
-
ix0 = (ix0 + 1) % pat.length;
|
|
1940
|
-
}
|
|
1941
|
-
const out = { contours: [], dots: [] };
|
|
1942
|
-
for (const chain of chains) {
|
|
1943
|
-
if (chain.segs.length === 0 || !(chain.total > 0)) continue;
|
|
1944
|
-
let ix = ix0;
|
|
1945
|
-
let rem = pat[ix0] - off;
|
|
1946
|
-
let pos = 0;
|
|
1947
|
-
const dashes = [];
|
|
1948
|
-
let guard = 0;
|
|
1949
|
-
while (pos < chain.total && guard++ < MAX_DASHES * 2) {
|
|
1950
|
-
const step = Math.min(rem, chain.total - pos);
|
|
1951
|
-
const on = ix % 2 === 0;
|
|
1952
|
-
if (on) dashes.push({ from: pos, to: pos + step });
|
|
1953
|
-
pos += step;
|
|
1954
|
-
rem -= step;
|
|
1955
|
-
if (rem <= 1e-12) {
|
|
1956
|
-
ix = (ix + 1) % pat.length;
|
|
1957
|
-
rem = pat[ix];
|
|
1958
|
-
}
|
|
1959
|
-
}
|
|
1960
|
-
if (chain.closed && dashes.length > 1) {
|
|
1961
|
-
const first = dashes[0];
|
|
1962
|
-
const last = dashes[dashes.length - 1];
|
|
1963
|
-
if (first.from <= 1e-9 && last.to >= chain.total - 1e-9 && first.to > first.from && last.to > last.from) {
|
|
1964
|
-
dashes.pop();
|
|
1965
|
-
const tail = trimSegments(chain.segs, last.from, chain.total, chain.lengths);
|
|
1966
|
-
const head = trimSegments(chain.segs, 0, first.to, chain.lengths);
|
|
1967
|
-
dashes.shift();
|
|
1968
|
-
out.contours.push({ segments: [...tail, ...head], closed: false });
|
|
1969
|
-
}
|
|
1970
|
-
}
|
|
1971
|
-
for (const dash of dashes) {
|
|
1972
|
-
if (dash.to - dash.from <= 1e-12) {
|
|
1973
|
-
const at = locate(chain.segs, chain.lengths, dash.from);
|
|
1974
|
-
out.dots.push(at);
|
|
1975
|
-
continue;
|
|
1976
|
-
}
|
|
1977
|
-
const segments = trimSegments(chain.segs, dash.from, dash.to, chain.lengths);
|
|
1978
|
-
if (segments.length > 0) out.contours.push({ segments, closed: false });
|
|
1979
|
-
}
|
|
1980
|
-
}
|
|
1981
|
-
return out;
|
|
1982
|
-
}
|
|
1983
|
-
function locate(segs, lengths, at) {
|
|
1984
|
-
let acc = 0;
|
|
1985
|
-
for (let i = 0; i < segs.length; i++) {
|
|
1986
|
-
if (at <= acc + lengths[i] || i === segs.length - 1) {
|
|
1987
|
-
const piece = trimSegments([segs[i]], 0, Math.max(0, at - acc), [lengths[i]]);
|
|
1988
|
-
const t = piece.length > 0 ? 1 : 0;
|
|
1989
|
-
const point = piece.length > 0 ? piece[piece.length - 1][piece[piece.length - 1].length - 1] : segs[i][0];
|
|
1990
|
-
const tangent = segmentTangent(piece.length > 0 ? piece[piece.length - 1] : segs[i], t);
|
|
1991
|
-
return { point, tangent };
|
|
1992
|
-
}
|
|
1993
|
-
acc += lengths[i];
|
|
1994
|
-
}
|
|
1995
|
-
return { point: segs[0][0], tangent: segmentTangent(segs[0], 0) };
|
|
1996
|
-
}
|
|
1997
|
-
function deepPoint(rings) {
|
|
1998
|
-
let minX = Infinity;
|
|
1999
|
-
let minY = Infinity;
|
|
2000
|
-
let maxX = -Infinity;
|
|
2001
|
-
let maxY = -Infinity;
|
|
2002
|
-
for (const p of rings[0].flat()) {
|
|
2003
|
-
minX = Math.min(minX, p[0]);
|
|
2004
|
-
maxX = Math.max(maxX, p[0]);
|
|
2005
|
-
minY = Math.min(minY, p[1]);
|
|
2006
|
-
maxY = Math.max(maxY, p[1]);
|
|
2007
|
-
}
|
|
2008
|
-
const w = maxX - minX;
|
|
2009
|
-
const h = maxY - minY;
|
|
2010
|
-
if (!(w > 0 && h > 0)) return null;
|
|
2011
|
-
const tolerance = Math.max(1e-6, 2e-3 * Math.min(w, h));
|
|
2012
|
-
const polys = rings.map((r) => flattenChain(r, tolerance));
|
|
2013
|
-
let best = null;
|
|
2014
|
-
for (const f of [0.5, 0.3, 0.7, 0.15, 0.85]) {
|
|
2015
|
-
const y = minY + h * f;
|
|
2016
|
-
const xs = [];
|
|
2017
|
-
for (const poly of polys) {
|
|
2018
|
-
for (let i = 0; i < poly.length; i++) {
|
|
2019
|
-
const a = poly[i];
|
|
2020
|
-
const b = poly[(i + 1) % poly.length];
|
|
2021
|
-
if (a[1] <= y !== b[1] <= y) xs.push(a[0] + (y - a[1]) / (b[1] - a[1]) * (b[0] - a[0]));
|
|
2022
|
-
}
|
|
2023
|
-
}
|
|
2024
|
-
xs.sort((p, q) => p - q);
|
|
2025
|
-
for (let i = 0; i + 1 < xs.length; i += 2) {
|
|
2026
|
-
const span = xs[i + 1] - xs[i];
|
|
2027
|
-
if (!best || span > best.span) best = { span, p: [(xs[i] + xs[i + 1]) / 2, y] };
|
|
2028
|
-
}
|
|
2029
|
-
}
|
|
2030
|
-
return best?.p ?? null;
|
|
2031
|
-
}
|
|
2032
|
-
function dropSpurious(rings, spurious) {
|
|
2033
|
-
const children = rings.map(() => []);
|
|
2034
|
-
rings.forEach((r, i) => {
|
|
2035
|
-
if (r.parent >= 0) children[r.parent].push(i);
|
|
2036
|
-
});
|
|
2037
|
-
const marked = rings.map((r, i) => spurious([r.segments, ...children[i].map((c) => rings[c].segments)], r));
|
|
2038
|
-
const hasMarkedAncestor = (i) => {
|
|
2039
|
-
for (let k = i; k >= 0; k = rings[k].parent) if (marked[k]) return true;
|
|
2040
|
-
return false;
|
|
2041
|
-
};
|
|
2042
|
-
return nestedRingsToPath(rings, (i) => !hasMarkedAncestor(i));
|
|
2043
|
-
}
|
|
2044
|
-
function mergeSmoothRuns(path, tolerance) {
|
|
2045
|
-
const contours = pathToContours(path).map((contour) => {
|
|
2046
|
-
const segs = closeContour(contour, true).map((s) => s.length === 3 ? raise(s) : [...s]);
|
|
2047
|
-
const n = segs.length;
|
|
2048
|
-
if (n < 2) return { segments: segs, closed: true };
|
|
2049
|
-
const smooth = (a, b) => {
|
|
2050
|
-
if (a.length !== 4 || b.length !== 4) return false;
|
|
2051
|
-
const ta = segmentTangent(a, 1);
|
|
2052
|
-
const tb = segmentTangent(b, 0);
|
|
2053
|
-
return dot(ta, tb) > 0.9998 && Math.abs(cross(ta, tb)) < 0.02;
|
|
2054
|
-
};
|
|
2055
|
-
let start = 0;
|
|
2056
|
-
for (let k = 0; k < n; k++) {
|
|
2057
|
-
if (!smooth(segs[(k + n - 1) % n], segs[k])) {
|
|
2058
|
-
start = k;
|
|
2059
|
-
break;
|
|
2060
|
-
}
|
|
2061
|
-
}
|
|
2062
|
-
const ordered = [...segs.slice(start), ...segs.slice(0, start)];
|
|
2063
|
-
const out = [];
|
|
2064
|
-
let i = 0;
|
|
2065
|
-
while (i < ordered.length) {
|
|
2066
|
-
let current = ordered[i];
|
|
2067
|
-
let j = i + 1;
|
|
2068
|
-
while (j < ordered.length && smooth(ordered[j - 1], ordered[j])) {
|
|
2069
|
-
const run = ordered.slice(i, j + 1);
|
|
2070
|
-
const pts = [];
|
|
2071
|
-
run.forEach((s, k) => {
|
|
2072
|
-
for (let q = k === 0 ? 0 : 1; q <= 12; q++) pts.push(segmentPoint(s, q / 12));
|
|
2073
|
-
});
|
|
2074
|
-
const fit = fitCubicRun(pts, tolerance, segmentTangent(run[0], 0), segmentTangent(run[run.length - 1], 1));
|
|
2075
|
-
if (fit.length !== 1) break;
|
|
2076
|
-
const c = fit[0];
|
|
2077
|
-
current = [run[0][0], c.p1, c.p2, run[run.length - 1][3]];
|
|
2078
|
-
j++;
|
|
2079
|
-
}
|
|
2080
|
-
out.push(current);
|
|
2081
|
-
i = j;
|
|
2082
|
-
}
|
|
2083
|
-
return { segments: out, closed: true };
|
|
2084
|
-
});
|
|
2085
|
-
return contoursToPath(contours);
|
|
2086
|
-
}
|
|
2087
|
-
function joinStyle(join, miterLimit) {
|
|
2088
|
-
return {
|
|
2089
|
-
join: join ?? "miter",
|
|
2090
|
-
miterLimit: miterLimit !== void 0 && Number.isFinite(miterLimit) ? Math.max(1, miterLimit) : 4
|
|
2091
|
-
};
|
|
2092
|
-
}
|
|
2093
|
-
function strokeOutlineRings(input, options) {
|
|
2094
|
-
const h = options.width / 2;
|
|
2095
|
-
if (!(h > 0) || !Number.isFinite(h)) return [];
|
|
2096
|
-
const tol = options.tolerance && options.tolerance > 0 ? options.tolerance : DEFAULT_TOLERANCE;
|
|
2097
|
-
const style = { ...joinStyle(options.join, options.miterLimit), cap: options.cap ?? "butt" };
|
|
2098
|
-
let contours = pathToContours(input);
|
|
2099
|
-
const rings = [];
|
|
2100
|
-
if (options.dash && options.dash.length > 0) {
|
|
2101
|
-
const dashed = dashContours(contours, options.dash, options.dashOffset ?? 0);
|
|
2102
|
-
if (dashed) {
|
|
2103
|
-
contours = dashed.contours;
|
|
2104
|
-
for (const dot2 of dashed.dots) rings.push(...dotRings(dot2.point, dot2.tangent, h, style.cap));
|
|
2105
|
-
}
|
|
2106
|
-
}
|
|
2107
|
-
for (const contour of contours) rings.push(...strokeContour(contour, h, style, tol));
|
|
2108
|
-
return ringsToPath(rings);
|
|
2109
|
-
}
|
|
2110
|
-
function outlineStroke(input, options) {
|
|
2111
|
-
const h = options.width / 2;
|
|
2112
|
-
if (!(h > 0) || !Number.isFinite(h)) return [];
|
|
2113
|
-
let source;
|
|
2114
|
-
try {
|
|
2115
|
-
source = contoursToPath(pathToContours(input));
|
|
2116
|
-
} catch {
|
|
2117
|
-
return [];
|
|
2118
|
-
}
|
|
2119
|
-
if (source.some((c) => c.type !== "Z" && Object.values(c).some((v) => typeof v === "number" && !Number.isFinite(v)))) return [];
|
|
2120
|
-
const raw = strokeOutlineRings(source, options);
|
|
2121
|
-
if (raw.length === 0) return [];
|
|
2122
|
-
const tol = options.tolerance && options.tolerance > 0 ? options.tolerance : DEFAULT_TOLERANCE;
|
|
2123
|
-
const sourceContours = pathToContours(source);
|
|
2124
|
-
const operand = { path: raw, fillRule: "nonzero" };
|
|
2125
|
-
try {
|
|
2126
|
-
const rings = pathBooleanRings("union", [operand], options);
|
|
2127
|
-
const cleaned = dropSpurious(rings, (face, ring) => {
|
|
2128
|
-
if (ring.area >= 0) return false;
|
|
2129
|
-
const p = deepPoint(face);
|
|
2130
|
-
return !!p && distanceToBezierPath(sourceContours, p) < h * (1 - 1e-4) - 1e-6;
|
|
2131
|
-
});
|
|
2132
|
-
return mergeSmoothRuns(cleaned, tol);
|
|
2133
|
-
} catch {
|
|
2134
|
-
return pathBoolean("union", [operand], options).path;
|
|
2135
|
-
}
|
|
2136
|
-
}
|
|
2137
|
-
function offsetPath(input, distance, options = {}) {
|
|
2138
|
-
if (!Number.isFinite(distance)) return [];
|
|
2139
|
-
const contours = pathToContours(input);
|
|
2140
|
-
if (contours.some((c) => c.segments.some((s) => s.some((p) => !Number.isFinite(p[0]) || !Number.isFinite(p[1]))))) return [];
|
|
2141
|
-
const closed = contours.filter((c) => c.closed && c.segments.length > 0);
|
|
2142
|
-
const open = contours.filter((c) => !c.closed && c.segments.length > 0);
|
|
2143
|
-
const fillRule = options.fillRule ?? "nonzero";
|
|
2144
|
-
const fill = { path: contoursToPath(closed), fillRule };
|
|
2145
|
-
const d = Math.abs(distance);
|
|
2146
|
-
const tol = options.tolerance && options.tolerance > 0 ? options.tolerance : DEFAULT_TOLERANCE;
|
|
2147
|
-
if (d === 0) return pathBoolean("union", [fill], options).path;
|
|
2148
|
-
const strokeOptions = { width: 2 * d, join: options.join ?? "miter", miterLimit: options.miterLimit, cap: "butt", tolerance: tol };
|
|
2149
|
-
const ring = { path: strokeOutlineRings(contoursToPath(closed), strokeOptions), fillRule: "nonzero" };
|
|
2150
|
-
const openRing = {
|
|
2151
|
-
path: distance > 0 ? strokeOutlineRings(contoursToPath(open), strokeOptions) : [],
|
|
2152
|
-
fillRule: "nonzero"
|
|
2153
|
-
};
|
|
2154
|
-
const grow = distance > 0;
|
|
2155
|
-
const operands = [fill, ring, openRing];
|
|
2156
|
-
try {
|
|
2157
|
-
const rings = pathBooleanRings(grow ? (m) => m[0] || m[1] || m[2] : (m) => m[0] && !m[1], operands, options);
|
|
2158
|
-
const sourceContours = contours;
|
|
2159
|
-
const cleaned = dropSpurious(rings, (face, r) => {
|
|
2160
|
-
if (grow ? r.area >= 0 : r.area <= 0) return false;
|
|
2161
|
-
const p = deepPoint(face);
|
|
2162
|
-
return !!p && distanceToBezierPath(sourceContours, p) < d * (1 - 1e-4) - 1e-6;
|
|
2163
|
-
});
|
|
2164
|
-
return mergeSmoothRuns(cleaned, tol);
|
|
2165
|
-
} catch {
|
|
2166
|
-
return grow ? pathBoolean("union", operands, options).path : pathBoolean("difference", [fill, ring], options).path;
|
|
2167
|
-
}
|
|
2168
|
-
}
|
|
2169
|
-
|
|
2170
1725
|
// src/canvas/shapeNodes.ts
|
|
2171
1726
|
var SHAPE_DATA_KEY = "shape";
|
|
2172
1727
|
var SHAPE_NODE_TYPE = "shape";
|
|
@@ -2655,8 +2210,8 @@ function snapResize(rect, handle, targets, options = {}) {
|
|
|
2655
2210
|
const ratio = rect.height > 0 ? rect.width / rect.height : 0;
|
|
2656
2211
|
if (options.keepAspectRatio && ratio > 0 && (hitX || hitY)) {
|
|
2657
2212
|
if (axes.x !== 0 && axes.y !== 0) {
|
|
2658
|
-
const
|
|
2659
|
-
const useX =
|
|
2213
|
+
const dist = (h, horizontal) => h ? Math.abs(h.value - (horizontal ? axes.x < 0 ? x0 : x1 : axes.y < 0 ? y0 : y1)) : Infinity;
|
|
2214
|
+
const useX = dist(hitX, true) <= dist(hitY, false);
|
|
2660
2215
|
if (useX && hitX) {
|
|
2661
2216
|
setEdge(true, hitX.value);
|
|
2662
2217
|
const height = (nx1 - nx0) / ratio;
|
|
@@ -3021,7 +2576,7 @@ function layoutFrameInner(s, frame) {
|
|
|
3021
2576
|
const b = s.boxes.get(id);
|
|
3022
2577
|
return horizontal ? [b.w, b.h] : [b.h, b.w];
|
|
3023
2578
|
};
|
|
3024
|
-
const resize = (it, main,
|
|
2579
|
+
const resize = (it, main, cross) => resizeChild(s, it.id, horizontal ? main : cross, horizontal ? cross : main);
|
|
3025
2580
|
if (!wraps) {
|
|
3026
2581
|
for (const it of items) {
|
|
3027
2582
|
if (!it.fillCross || it.fillMain) continue;
|
|
@@ -3035,13 +2590,13 @@ function layoutFrameInner(s, frame) {
|
|
|
3035
2590
|
let used = 0;
|
|
3036
2591
|
items.forEach((it, i) => {
|
|
3037
2592
|
const sz = it.fillMain ? it.minMain ?? 0 : it.main;
|
|
3038
|
-
const
|
|
3039
|
-
if (cur.length > 0 && used +
|
|
2593
|
+
const add = cur.length === 0 ? sz : Math.max(gap, 0) + sz;
|
|
2594
|
+
if (cur.length > 0 && used + add > innerMainFixed + 1e-6) {
|
|
3040
2595
|
lines.push(cur);
|
|
3041
2596
|
cur = [];
|
|
3042
2597
|
used = sz;
|
|
3043
2598
|
} else {
|
|
3044
|
-
used +=
|
|
2599
|
+
used += add;
|
|
3045
2600
|
}
|
|
3046
2601
|
cur.push(i);
|
|
3047
2602
|
});
|
|
@@ -3057,8 +2612,8 @@ function layoutFrameInner(s, frame) {
|
|
|
3057
2612
|
}
|
|
3058
2613
|
for (const it of items) {
|
|
3059
2614
|
if (!it.fillMain) continue;
|
|
3060
|
-
const
|
|
3061
|
-
resize(it, it.main,
|
|
2615
|
+
const cross = it.fillCross && !wraps ? clampLayoutSize(innerCrossFixed, it.minCross, it.maxCross) : it.cross;
|
|
2616
|
+
resize(it, it.main, cross);
|
|
3062
2617
|
it.cross = sizeOf2(it.id)[1];
|
|
3063
2618
|
}
|
|
3064
2619
|
if (baseline) {
|
|
@@ -3072,8 +2627,8 @@ function layoutFrameInner(s, frame) {
|
|
|
3072
2627
|
const inLine = line2.map((i) => items[i]);
|
|
3073
2628
|
const mainUsed = inLine.reduce((sum, it) => sum + it.main, 0) + gaps;
|
|
3074
2629
|
const allFill = inLine.every((it) => it.fillCross);
|
|
3075
|
-
const
|
|
3076
|
-
extents.push([mainUsed,
|
|
2630
|
+
const cross = inLine.filter((it) => allFill || !it.fillCross).reduce((m, it) => Math.max(m, it.baseOff + it.cross), 0);
|
|
2631
|
+
extents.push([mainUsed, cross]);
|
|
3077
2632
|
}
|
|
3078
2633
|
const contentMain = extents.reduce((m, l) => Math.max(m, l[0]), 0);
|
|
3079
2634
|
let crossGap = al.rowGap !== void 0 ? finite(al.rowGap) : gap;
|
|
@@ -3555,13 +3110,13 @@ function getAutoLayoutInsertTarget(nodes, frameId, point, options = {}) {
|
|
|
3555
3110
|
const horizontal = al.mode !== "vertical";
|
|
3556
3111
|
const main = (b) => horizontal ? b.x : b.y;
|
|
3557
3112
|
const mainSize = (b) => horizontal ? b.w : b.h;
|
|
3558
|
-
const
|
|
3113
|
+
const cross = (b) => horizontal ? b.y : b.x;
|
|
3559
3114
|
const crossSize = (b) => horizontal ? b.h : b.w;
|
|
3560
3115
|
const p = { x: px2, y: py };
|
|
3561
3116
|
const multiLine = al.mode === "grid" || !!al.wrap;
|
|
3562
3117
|
let index = 0;
|
|
3563
3118
|
for (const b of siblings) {
|
|
3564
|
-
const before = multiLine ?
|
|
3119
|
+
const before = multiLine ? cross(b) + crossSize(b) <= cross(p) || cross(b) <= cross(p) && main(b) + mainSize(b) / 2 < main(p) : main(b) + mainSize(b) / 2 < main(p);
|
|
3565
3120
|
if (before) index += 1;
|
|
3566
3121
|
}
|
|
3567
3122
|
const [pt, pr, pb, pl] = resolvePadding(al.padding);
|
|
@@ -3570,13 +3125,13 @@ function getAutoLayoutInsertTarget(nodes, frameId, point, options = {}) {
|
|
|
3570
3125
|
const f = s.boxes.get(frameId);
|
|
3571
3126
|
let guide;
|
|
3572
3127
|
if (horizontal) {
|
|
3573
|
-
const x = prev && next && Math.abs(
|
|
3128
|
+
const x = prev && next && Math.abs(cross(prev) - cross(next)) < 1e-6 ? (prev.x + prev.w + next.x) / 2 : prev ? prev.x + prev.w : next ? next.x : pl;
|
|
3574
3129
|
const ref = next ?? prev;
|
|
3575
3130
|
const y1 = ref ? ref.y : pt;
|
|
3576
3131
|
const y2 = ref ? ref.y + ref.h : f.h - pb;
|
|
3577
3132
|
guide = { orientation: "vertical", kind: "edge", x1: origin.x + x, y1: origin.y + y1, x2: origin.x + x, y2: origin.y + y2 };
|
|
3578
3133
|
} else {
|
|
3579
|
-
const y = prev && next && Math.abs(
|
|
3134
|
+
const y = prev && next && Math.abs(cross(prev) - cross(next)) < 1e-6 ? (prev.y + prev.h + next.y) / 2 : prev ? prev.y + prev.h : next ? next.y : pt;
|
|
3580
3135
|
const ref = next ?? prev;
|
|
3581
3136
|
const x1 = ref ? ref.x : pl;
|
|
3582
3137
|
const x2 = ref ? ref.x + ref.w : f.w - pr;
|
|
@@ -6448,8 +6003,8 @@ function sizeOf(node) {
|
|
|
6448
6003
|
return { width: node.width, height: node.height, styleWidth: s.width, styleHeight: s.height };
|
|
6449
6004
|
}
|
|
6450
6005
|
var splitGroup = (group) => {
|
|
6451
|
-
const
|
|
6452
|
-
return
|
|
6006
|
+
const dot = group.indexOf(".");
|
|
6007
|
+
return dot < 0 ? [group, ""] : [group.slice(0, dot), group.slice(dot + 1)];
|
|
6453
6008
|
};
|
|
6454
6009
|
function readOverrideGroup(node, group) {
|
|
6455
6010
|
const data = dataOf(node);
|
|
@@ -6562,7 +6117,7 @@ function listGroups(node, out) {
|
|
|
6562
6117
|
if (LINK_KEYS.has(k)) continue;
|
|
6563
6118
|
const prefix = NESTED_KEYS[k];
|
|
6564
6119
|
if (prefix) {
|
|
6565
|
-
if (isRecord(v)) for (const
|
|
6120
|
+
if (isRecord(v)) for (const sub of Object.keys(v)) out.add(`${prefix}.${sub}`);
|
|
6566
6121
|
continue;
|
|
6567
6122
|
}
|
|
6568
6123
|
out.add(`data.${k}`);
|
|
@@ -7875,11 +7430,11 @@ function restoreCanvasMainComponent(nodes, id, options = {}) {
|
|
|
7875
7430
|
if (g.get(inst.componentId)) return fail(nodes, "invalid", "The main component still exists.");
|
|
7876
7431
|
if (enclosingInstanceIn(g, id) !== void 0) return fail(nodes, "nested-instance", "Select the outer instance.");
|
|
7877
7432
|
const compId = inst.componentId;
|
|
7878
|
-
const
|
|
7433
|
+
const sub = g.subtree(id);
|
|
7879
7434
|
const map = /* @__PURE__ */ new Map([[id, compId]]);
|
|
7880
7435
|
const taken = new Set(nodes.map((n) => n.id));
|
|
7881
7436
|
taken.add(compId);
|
|
7882
|
-
for (const d of
|
|
7437
|
+
for (const d of sub) {
|
|
7883
7438
|
if (d === id) continue;
|
|
7884
7439
|
const src = enclosingInstanceIn(g, d) === id ? getComponentSourceId(g.get(d)) : void 0;
|
|
7885
7440
|
if (src && !taken.has(src)) {
|
|
@@ -7889,7 +7444,7 @@ function restoreCanvasMainComponent(nodes, id, options = {}) {
|
|
|
7889
7444
|
}
|
|
7890
7445
|
const nested = [];
|
|
7891
7446
|
const replaced = /* @__PURE__ */ new Map();
|
|
7892
|
-
for (const d of
|
|
7447
|
+
for (const d of sub) {
|
|
7893
7448
|
let n = g.get(d);
|
|
7894
7449
|
const nid = map.get(d) ?? d;
|
|
7895
7450
|
const parentId = n.parentId !== void 0 ? map.get(n.parentId) ?? n.parentId : void 0;
|
|
@@ -8056,15 +7611,15 @@ function addCanvasVariant(nodes, setId, options = {}) {
|
|
|
8056
7611
|
const taken = new Set(g.byId.keys());
|
|
8057
7612
|
taken.add(id);
|
|
8058
7613
|
const map = /* @__PURE__ */ new Map([[fromId, id]]);
|
|
8059
|
-
const
|
|
8060
|
-
for (const d of
|
|
7614
|
+
const sub = g.subtree(fromId);
|
|
7615
|
+
for (const d of sub) {
|
|
8061
7616
|
if (d === fromId) continue;
|
|
8062
7617
|
const nid = uniqueId(`${id}-${d}`, taken);
|
|
8063
7618
|
taken.add(nid);
|
|
8064
7619
|
map.set(d, nid);
|
|
8065
7620
|
}
|
|
8066
7621
|
const order = variantOrder([...edit.variants.map((v) => v.id), id], edit.values);
|
|
8067
|
-
const subSet = new Set(
|
|
7622
|
+
const subSet = new Set(sub);
|
|
8068
7623
|
const copies = nodes.filter((n) => subSet.has(n.id)).map((n) => {
|
|
8069
7624
|
const next = { ...n, id: map.get(n.id) };
|
|
8070
7625
|
if (n.parentId !== void 0 && n.id !== fromId) next.parentId = map.get(n.parentId) ?? n.parentId;
|
|
@@ -8623,8 +8178,8 @@ function findStrokesAtPoint(point, nodes, radius = 12) {
|
|
|
8623
8178
|
}
|
|
8624
8179
|
const localPoint = [point[0] - rect.x, point[1] - rect.y];
|
|
8625
8180
|
try {
|
|
8626
|
-
const
|
|
8627
|
-
if (
|
|
8181
|
+
const dist = distanceToBezierPath(shape.d, localPoint);
|
|
8182
|
+
if (dist <= effectiveRadius) {
|
|
8628
8183
|
matches2.push(node);
|
|
8629
8184
|
}
|
|
8630
8185
|
} catch {
|
|
@@ -8929,6 +8484,7 @@ export {
|
|
|
8929
8484
|
findStrokesAtPoint,
|
|
8930
8485
|
findVariant,
|
|
8931
8486
|
fitCubicRun,
|
|
8487
|
+
fitCubicWithTangents,
|
|
8932
8488
|
fitCubics,
|
|
8933
8489
|
fitFreehandPath,
|
|
8934
8490
|
fitPathData,
|
|
@@ -9111,6 +8667,7 @@ export {
|
|
|
9111
8667
|
segmentCurvature,
|
|
9112
8668
|
segmentDerivative,
|
|
9113
8669
|
segmentExtrema,
|
|
8670
|
+
segmentIntersections,
|
|
9114
8671
|
segmentLength,
|
|
9115
8672
|
segmentNearest,
|
|
9116
8673
|
segmentParamAtLength,
|