@pixerate/editor 0.37.0 → 0.38.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 +7 -0
- package/dist/canvas/index.cjs +37 -25
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +2 -2
- package/dist/canvas/index.d.ts +2 -2
- package/dist/canvas/index.js +13 -1
- package/dist/canvas/index.js.map +1 -1
- package/dist/{chunk-GVB7ZPLZ.cjs → chunk-7EDLVBOO.cjs} +649 -18
- package/dist/chunk-7EDLVBOO.cjs.map +1 -0
- package/dist/{chunk-HPEKB352.js → chunk-ZCCU3VNI.js} +646 -15
- package/dist/chunk-ZCCU3VNI.js.map +1 -0
- package/dist/{stroke-CWjFKal4.d.cts → pathfinder-Bd87_lsQ.d.cts} +234 -1
- package/dist/{stroke-ysgaPpAo.d.ts → pathfinder-fLmmFOJw.d.ts} +234 -1
- package/dist/vector/index.cjs +860 -274
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +242 -3
- package/dist/vector/index.d.ts +242 -3
- package/dist/vector/index.js +611 -25
- package/dist/vector/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-GVB7ZPLZ.cjs.map +0 -1
- package/dist/chunk-HPEKB352.js.map +0 -1
package/dist/vector/index.cjs
CHANGED
|
@@ -34,13 +34,32 @@ var _chunkQKLRAA4Tcjs = require('../chunk-QKLRAA4T.cjs');
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
var _chunk7EDLVBOOcjs = require('../chunk-7EDLVBOO.cjs');
|
|
38
40
|
|
|
39
41
|
// src/vector/types.ts
|
|
40
42
|
var VECTOR_CORNER_KINDS = ["round", "inverted", "chamfer"];
|
|
41
43
|
var VECTOR_ARROWHEADS = ["triangle", "arrow", "open", "circle", "square", "bar"];
|
|
42
|
-
var VECTOR_TOOLS = [
|
|
44
|
+
var VECTOR_TOOLS = [
|
|
45
|
+
"select",
|
|
46
|
+
"direct",
|
|
47
|
+
"pen",
|
|
48
|
+
"pencil",
|
|
49
|
+
"rect",
|
|
50
|
+
"ellipse",
|
|
51
|
+
"polygon",
|
|
52
|
+
"star",
|
|
53
|
+
"line",
|
|
54
|
+
"scissors",
|
|
55
|
+
"knife",
|
|
56
|
+
"eraser",
|
|
57
|
+
"width",
|
|
58
|
+
"shapeBuilder",
|
|
59
|
+
"paintBucket"
|
|
60
|
+
];
|
|
43
61
|
var VECTOR_TRANSFORM_HANDLES = ["nw", "n", "ne", "e", "se", "s", "sw", "w", "rotate"];
|
|
62
|
+
var VECTOR_PATHFINDER_OPERATIONS = ["divide", "trim", "merge", "crop", "outline", "minusBack"];
|
|
44
63
|
|
|
45
64
|
// src/vector/corners.ts
|
|
46
65
|
var EPS = 1e-9;
|
|
@@ -61,7 +80,7 @@ var Side = class {
|
|
|
61
80
|
constructor(a, h1, h2, b) {
|
|
62
81
|
this.straight = onAnchor(a, h1) && onAnchor(b, h2);
|
|
63
82
|
this.curve = this.straight ? [pt(a), pt(b)] : [pt(a), pt(_nullishCoalesce(h1, () => ( a))), pt(_nullishCoalesce(h2, () => ( b))), pt(b)];
|
|
64
|
-
this.length = this.straight ? Math.hypot(b.x - a.x, b.y - a.y) :
|
|
83
|
+
this.length = this.straight ? Math.hypot(b.x - a.x, b.y - a.y) : _chunk7EDLVBOOcjs.segmentLength.call(void 0, this.curve);
|
|
65
84
|
}
|
|
66
85
|
/** Unit direction the side leaves the corner in (towards its first control point off the corner). */
|
|
67
86
|
direction() {
|
|
@@ -79,10 +98,10 @@ var Side = class {
|
|
|
79
98
|
const t2 = this.length > EPS ? Math.min(1, Math.max(0, s / this.length)) : 0;
|
|
80
99
|
return { t: t2, p: add(vec(this.curve[0]), mul(u, s)), dir: u };
|
|
81
100
|
}
|
|
82
|
-
const t =
|
|
83
|
-
const d = vec(
|
|
101
|
+
const t = _chunk7EDLVBOOcjs.segmentParamAtLength.call(void 0, this.curve, s, this.length);
|
|
102
|
+
const d = vec(_chunk7EDLVBOOcjs.segmentDerivative.call(void 0, this.curve, t));
|
|
84
103
|
const l = len(d);
|
|
85
|
-
return { t, p: vec(
|
|
104
|
+
return { t, p: vec(_chunk7EDLVBOOcjs.segmentPoint.call(void 0, this.curve, t)), dir: l > EPS ? mul(d, 1 / l) : u };
|
|
86
105
|
}
|
|
87
106
|
};
|
|
88
107
|
function cornerOf(sp, s, i) {
|
|
@@ -155,7 +174,7 @@ function cutCorner(c, radius, kind) {
|
|
|
155
174
|
return { tu: a.t, tv: b.t, start: a.p, out: add(a.p, mul(d1, k)), in: add(b.p, mul(d2, k)), end: b.p };
|
|
156
175
|
}
|
|
157
176
|
var radiusOf = (a) => {
|
|
158
|
-
const r = _optionalChain([a, 'access',
|
|
177
|
+
const r = _optionalChain([a, 'access', _3 => _3.corner, 'optionalAccess', _4 => _4.radius]);
|
|
159
178
|
return typeof r === "number" && r > 0 && Number.isFinite(r) ? r : 0;
|
|
160
179
|
};
|
|
161
180
|
function hasVectorCorners(subpaths) {
|
|
@@ -169,7 +188,7 @@ function expandVectorCornersOf(sp, subpath = 0) {
|
|
|
169
188
|
const c = cornerOf(sp, subpath, i);
|
|
170
189
|
if (!c) return null;
|
|
171
190
|
const fitted = fitCornerRadius(c, r);
|
|
172
|
-
return fitted > EPS ? cutCorner(c, fitted, _nullishCoalesce(_optionalChain([a, 'access',
|
|
191
|
+
return fitted > EPS ? cutCorner(c, fitted, _nullishCoalesce(_optionalChain([a, 'access', _5 => _5.corner, 'optionalAccess', _6 => _6.kind]), () => ( "round"))) : null;
|
|
173
192
|
});
|
|
174
193
|
if (!cuts.some(Boolean)) return { subpath: { closed: sp.closed, anchors: sp.anchors.map(plain) }, sources: sp.anchors.map((_, i) => i) };
|
|
175
194
|
const trimmed = sp.anchors.map((a, j) => {
|
|
@@ -183,7 +202,7 @@ function expandVectorCornersOf(sp, subpath = 0) {
|
|
|
183
202
|
const s0 = from ? from.tv : 0;
|
|
184
203
|
const s1 = to ? 1 - to.tu : 1;
|
|
185
204
|
const seg = [pt(a), pt(_nullishCoalesce(a.out, () => ( a))), pt(_nullishCoalesce(b.in, () => ( b))), pt(b)];
|
|
186
|
-
const part =
|
|
205
|
+
const part = _chunk7EDLVBOOcjs.subSegment.call(void 0, seg, s0, Math.max(s0, s1));
|
|
187
206
|
return { out: vec(part[1]), in: vec(part[2]) };
|
|
188
207
|
});
|
|
189
208
|
const anchors = [];
|
|
@@ -237,7 +256,7 @@ function expandVectorCorners(subpaths) {
|
|
|
237
256
|
function setAnchorCorner(a, radius, kind) {
|
|
238
257
|
const { corner, ...rest } = a;
|
|
239
258
|
const r = Number.isFinite(radius) ? Math.max(0, radius) : 0;
|
|
240
|
-
const k = _nullishCoalesce(kind, () => ( _optionalChain([corner, 'optionalAccess',
|
|
259
|
+
const k = _nullishCoalesce(kind, () => ( _optionalChain([corner, 'optionalAccess', _7 => _7.kind])));
|
|
241
260
|
if (r <= 0 && !kind) return rest;
|
|
242
261
|
return { ...rest, corner: { radius: r, ...k && k !== "round" ? { kind: k } : {} } };
|
|
243
262
|
}
|
|
@@ -286,7 +305,7 @@ function sanitizeWidthProfile(points) {
|
|
|
286
305
|
return out.map((p, i) => [p, i]).sort((a, b) => a[0].t - b[0].t || a[1] - b[1]).map(([p]) => p);
|
|
287
306
|
}
|
|
288
307
|
function isUniformWidthProfile(points) {
|
|
289
|
-
return !_optionalChain([points, 'optionalAccess',
|
|
308
|
+
return !_optionalChain([points, 'optionalAccess', _8 => _8.length]) || points.every((p) => p.left === 1 && p.right === 1);
|
|
290
309
|
}
|
|
291
310
|
function secant(pts, i, k) {
|
|
292
311
|
const a = pts[i];
|
|
@@ -319,11 +338,11 @@ function interp(pts, t, k) {
|
|
|
319
338
|
return Math.max(0, w);
|
|
320
339
|
}
|
|
321
340
|
function widthProfileAt(points, t) {
|
|
322
|
-
if (!_optionalChain([points, 'optionalAccess',
|
|
341
|
+
if (!_optionalChain([points, 'optionalAccess', _9 => _9.length])) return { left: 1, right: 1 };
|
|
323
342
|
return { left: interp(points, t, "left"), right: interp(points, t, "right") };
|
|
324
343
|
}
|
|
325
344
|
function widthProfileMaxScale(points) {
|
|
326
|
-
if (!_optionalChain([points, 'optionalAccess',
|
|
345
|
+
if (!_optionalChain([points, 'optionalAccess', _10 => _10.length])) return 1;
|
|
327
346
|
return points.reduce((m, p) => Math.max(m, p.left, p.right), 0);
|
|
328
347
|
}
|
|
329
348
|
function widthProfilePreset(id) {
|
|
@@ -333,7 +352,7 @@ function widthProfilePreset(id) {
|
|
|
333
352
|
function widthProfilePresetId(points) {
|
|
334
353
|
if (isUniformWidthProfile(points)) return "uniform";
|
|
335
354
|
const same = (a, b) => a.length === b.length && a.every((p, i) => Math.abs(p.t - b[i].t) < 1e-9 && Math.abs(p.left - b[i].left) < 1e-9 && Math.abs(p.right - b[i].right) < 1e-9);
|
|
336
|
-
return _nullishCoalesce(_optionalChain([VECTOR_WIDTH_PRESETS, 'access',
|
|
355
|
+
return _nullishCoalesce(_optionalChain([VECTOR_WIDTH_PRESETS, 'access', _11 => _11.find, 'call', _12 => _12((p) => p.points.length && same(points, p.points)), 'optionalAccess', _13 => _13.id]), () => ( "custom"));
|
|
337
356
|
}
|
|
338
357
|
function reverseWidthProfile(points) {
|
|
339
358
|
return points.map((p) => ({ t: 1 - p.t, left: p.right, right: p.left })).reverse();
|
|
@@ -342,16 +361,16 @@ function mirrorWidthProfile(points) {
|
|
|
342
361
|
return points.map((p) => ({ t: p.t, left: p.right, right: p.left }));
|
|
343
362
|
}
|
|
344
363
|
function editable(points) {
|
|
345
|
-
return _optionalChain([points, 'optionalAccess',
|
|
364
|
+
return _optionalChain([points, 'optionalAccess', _14 => _14.length]) ? points.map((p) => ({ ...p })) : [sym(0, 1), sym(1, 1)];
|
|
346
365
|
}
|
|
347
|
-
function insertWidthPoint(points, t,
|
|
366
|
+
function insertWidthPoint(points, t, sides2 = {}, options = {}) {
|
|
348
367
|
const pts = editable(points);
|
|
349
368
|
const tt = Math.min(Math.max(Number.isFinite(t) ? t : 0, 0), 1);
|
|
350
|
-
const here = widthProfileAt(_optionalChain([points, 'optionalAccess',
|
|
369
|
+
const here = widthProfileAt(_optionalChain([points, 'optionalAccess', _15 => _15.length]) ? points : null, tt);
|
|
351
370
|
const p = {
|
|
352
371
|
t: tt,
|
|
353
|
-
left: _nullishCoalesce(clean(
|
|
354
|
-
right: _nullishCoalesce(clean(
|
|
372
|
+
left: _nullishCoalesce(clean(sides2.left, VECTOR_WIDTH_PROFILE_MAX_SCALE), () => ( here.left)),
|
|
373
|
+
right: _nullishCoalesce(clean(sides2.right, VECTOR_WIDTH_PROFILE_MAX_SCALE), () => ( here.right))
|
|
355
374
|
};
|
|
356
375
|
const same = pts.findIndex((q) => Math.abs(q.t - tt) <= VECTOR_WIDTH_SAME_T);
|
|
357
376
|
if (same >= 0 && !options.step) {
|
|
@@ -418,7 +437,7 @@ function generateWidthProfile(options) {
|
|
|
418
437
|
const n = Math.max(8, Math.min(VECTOR_WIDTH_PROFILE_MAX_POINTS * 4, _nullishCoalesce(options.samples, () => ( Math.ceil(32 + cycles * 16)))));
|
|
419
438
|
const raw = [];
|
|
420
439
|
for (let i = 0; i <= n; i++) raw.push([i / n, taperWaveFactor(i / n, options.taper, options.wave)]);
|
|
421
|
-
const ts = [_optionalChain([options, 'access',
|
|
440
|
+
const ts = [_optionalChain([options, 'access', _16 => _16.taper, 'optionalAccess', _17 => _17.startLength]), _optionalChain([options, 'access', _18 => _18.taper, 'optionalAccess', _19 => _19.endLength]) !== void 0 ? 1 - options.taper.endLength : void 0];
|
|
422
441
|
for (const t of ts) if (typeof t === "number" && t > 0 && t < 1) raw.push([t, taperWaveFactor(t, options.taper, options.wave)]);
|
|
423
442
|
raw.sort((a, b) => a[0] - b[0]);
|
|
424
443
|
const kept = simplifySamples(raw, _nullishCoalesce(options.tolerance, () => ( 0.01)), VECTOR_WIDTH_PROFILE_MAX_POINTS);
|
|
@@ -486,7 +505,7 @@ function flatten(segments, closed, tol) {
|
|
|
486
505
|
corner.push(isCorner);
|
|
487
506
|
};
|
|
488
507
|
for (const seg of segments) {
|
|
489
|
-
const flat =
|
|
508
|
+
const flat = _chunk7EDLVBOOcjs.flattenChain.call(void 0, [seg], tol);
|
|
490
509
|
if (dist(seg[0], seg[seg.length - 1]) <= 1e-12 && flat.length > 1) flat.push(seg[seg.length - 1]);
|
|
491
510
|
flat.forEach((p, i) => push(p, i === 0 || i === flat.length - 1));
|
|
492
511
|
}
|
|
@@ -576,16 +595,16 @@ function variableStrokeRings(path, options) {
|
|
|
576
595
|
const last = out[out.length - 1];
|
|
577
596
|
if (!last || dist(last, p) > 1e-12) out.push(p);
|
|
578
597
|
};
|
|
579
|
-
for (const contour of
|
|
598
|
+
for (const contour of _chunk7EDLVBOOcjs.pathToContours.call(void 0, path)) {
|
|
580
599
|
if (!contour.segments.length) continue;
|
|
581
600
|
const poly = flatten(contour.segments, contour.closed, Math.min(tol, half) / 4);
|
|
582
601
|
if (!poly) continue;
|
|
583
602
|
const len2 = poly.s[poly.s.length - 1];
|
|
584
|
-
const
|
|
603
|
+
const sides2 = (s) => {
|
|
585
604
|
const w = widthProfileAt(options.profile, s / len2);
|
|
586
605
|
return [w.left * half, w.right * half];
|
|
587
606
|
};
|
|
588
|
-
const intervals = _optionalChain([options, 'access',
|
|
607
|
+
const intervals = _optionalChain([options, 'access', _20 => _20.dash, 'optionalAccess', _21 => _21.some, 'call', _22 => _22((v2) => v2 > 0)]) ? dashIntervals(options.dash, _nullishCoalesce(options.dashOffset, () => ( 0)), len2) : [[0, len2]];
|
|
589
608
|
const whole = intervals.length === 1 && intervals[0][0] <= 0 && intervals[0][1] >= len2;
|
|
590
609
|
for (const [a, b] of intervals) {
|
|
591
610
|
const [pa, ia] = at(poly, a);
|
|
@@ -595,7 +614,7 @@ function variableStrokeRings(path, options) {
|
|
|
595
614
|
pts.push({ p: pb, s: b, corner: false });
|
|
596
615
|
const run = pts.filter((q, i) => i === 0 || dist(q.p, pts[i - 1].p) > 1e-9);
|
|
597
616
|
if (run.length < 2) {
|
|
598
|
-
const [l, r] =
|
|
617
|
+
const [l, r] = sides2(a);
|
|
599
618
|
const w2 = (l + r) / 2;
|
|
600
619
|
if (cap === "round" && w2 > 0) rings.push([[pa[0] + w2, pa[1]], ...arcPoints(pa, 0, 2 * Math.PI, w2, w2, tol)]);
|
|
601
620
|
continue;
|
|
@@ -605,7 +624,7 @@ function variableStrokeRings(path, options) {
|
|
|
605
624
|
const dirs = [];
|
|
606
625
|
for (let i = 0; i < m; i++) dirs.push(unitOf(sub2(run[i + 1].p, run[i].p)));
|
|
607
626
|
const normals = dirs.map(leftNormal);
|
|
608
|
-
const w = run.map((q) =>
|
|
627
|
+
const w = run.map((q) => sides2(q.s));
|
|
609
628
|
const side = (sigma) => {
|
|
610
629
|
const k = sigma > 0 ? 0 : 1;
|
|
611
630
|
const S = (i) => along(run[i].p, normals[i], sigma * w[i][k]);
|
|
@@ -702,7 +721,7 @@ function variableStrokeOutline(path, options) {
|
|
|
702
721
|
const tol = options.tolerance && options.tolerance > 0 ? options.tolerance : 0.05;
|
|
703
722
|
let polygons;
|
|
704
723
|
try {
|
|
705
|
-
polygons =
|
|
724
|
+
polygons = _chunk7EDLVBOOcjs.polygonBoolean.call(void 0, "union", [{ rings: pieces, fillRule: "nonzero" }]);
|
|
706
725
|
} catch (e2) {
|
|
707
726
|
return [];
|
|
708
727
|
}
|
|
@@ -710,11 +729,11 @@ function variableStrokeOutline(path, options) {
|
|
|
710
729
|
for (const polygon2 of polygons) {
|
|
711
730
|
for (const ring of polygon2) {
|
|
712
731
|
if (ring.length < 3) continue;
|
|
713
|
-
const cubics =
|
|
732
|
+
const cubics = _chunk7EDLVBOOcjs.fitCubics.call(void 0, ring, tol, { closed: true, cornerAngleDeg: 25 });
|
|
714
733
|
if (!cubics.length) continue;
|
|
715
734
|
out.push({ type: "M", x: cubics[0].p0[0], y: cubics[0].p0[1] });
|
|
716
735
|
cubics.forEach((c, i) => {
|
|
717
|
-
if (
|
|
736
|
+
if (_chunk7EDLVBOOcjs.isStraightCubic.call(void 0, c, tol * 0.02)) {
|
|
718
737
|
if (i < cubics.length - 1) out.push({ type: "L", x: c.p3[0], y: c.p3[1] });
|
|
719
738
|
} else out.push({ type: "C", x1: c.p1[0], y1: c.p1[1], x2: c.p2[0], y2: c.p2[1], x: c.p3[0], y: c.p3[1] });
|
|
720
739
|
});
|
|
@@ -725,17 +744,17 @@ function variableStrokeOutline(path, options) {
|
|
|
725
744
|
}
|
|
726
745
|
function nearestStrokePosition(path, p, only) {
|
|
727
746
|
let best = null;
|
|
728
|
-
|
|
747
|
+
_chunk7EDLVBOOcjs.pathToContours.call(void 0, path).forEach((c, ci) => {
|
|
729
748
|
if (!c.segments.length || only !== void 0 && ci !== only) return;
|
|
730
|
-
const lengths = c.segments.map((s) =>
|
|
749
|
+
const lengths = c.segments.map((s) => _chunk7EDLVBOOcjs.segmentLength.call(void 0, s));
|
|
731
750
|
const total = lengths.reduce((a, b) => a + b, 0);
|
|
732
751
|
if (!(total > 0)) return;
|
|
733
752
|
let acc = 0;
|
|
734
753
|
c.segments.forEach((seg, si) => {
|
|
735
|
-
const near2 =
|
|
754
|
+
const near2 = _chunk7EDLVBOOcjs.segmentNearest.call(void 0, seg, p);
|
|
736
755
|
if (!best || near2.distance < best.distance) {
|
|
737
|
-
const s = acc +
|
|
738
|
-
const tan =
|
|
756
|
+
const s = acc + _chunk7EDLVBOOcjs.segmentLength.call(void 0, seg, 0, near2.t);
|
|
757
|
+
const tan = _chunk7EDLVBOOcjs.segmentTangent.call(void 0, seg, near2.t);
|
|
739
758
|
const pt2 = seg.length === 2 ? lerp(seg[0], seg[1], near2.t) : evalSeg(seg, near2.t);
|
|
740
759
|
const n = leftNormal([tan[0], tan[1]]);
|
|
741
760
|
const side = (p[0] - pt2[0]) * n[0] + (p[1] - pt2[1]) * n[1] >= 0 ? "left" : "right";
|
|
@@ -752,9 +771,9 @@ function evalSeg(seg, t) {
|
|
|
752
771
|
return pts[0];
|
|
753
772
|
}
|
|
754
773
|
function strokePositionPoint(path, index, t) {
|
|
755
|
-
const c =
|
|
756
|
-
if (!_optionalChain([c, 'optionalAccess',
|
|
757
|
-
const lengths = c.segments.map((s) =>
|
|
774
|
+
const c = _chunk7EDLVBOOcjs.pathToContours.call(void 0, path)[index];
|
|
775
|
+
if (!_optionalChain([c, 'optionalAccess', _23 => _23.segments, 'access', _24 => _24.length])) return null;
|
|
776
|
+
const lengths = c.segments.map((s) => _chunk7EDLVBOOcjs.segmentLength.call(void 0, s));
|
|
758
777
|
const total = lengths.reduce((a, b) => a + b, 0);
|
|
759
778
|
let want = Math.min(Math.max(t, 0), 1) * total;
|
|
760
779
|
for (let i = 0; i < c.segments.length; i++) {
|
|
@@ -765,11 +784,11 @@ function strokePositionPoint(path, index, t) {
|
|
|
765
784
|
const target = Math.min(want, lengths[i]);
|
|
766
785
|
for (let k = 0; k < 40; k++) {
|
|
767
786
|
const mid = (lo + hi) / 2;
|
|
768
|
-
if (
|
|
787
|
+
if (_chunk7EDLVBOOcjs.segmentLength.call(void 0, seg, 0, mid) < target) lo = mid;
|
|
769
788
|
else hi = mid;
|
|
770
789
|
}
|
|
771
790
|
const u = (lo + hi) / 2;
|
|
772
|
-
const tan =
|
|
791
|
+
const tan = _chunk7EDLVBOOcjs.segmentTangent.call(void 0, seg, u);
|
|
773
792
|
return { point: evalSeg(seg, u), tangent: [tan[0], tan[1]] };
|
|
774
793
|
}
|
|
775
794
|
want -= lengths[i];
|
|
@@ -781,7 +800,7 @@ function strokePositionPoint(path, index, t) {
|
|
|
781
800
|
var KAPPA = 0.5522847498307936;
|
|
782
801
|
var NOTCH = 0.7;
|
|
783
802
|
function isClosedBezierShape(path) {
|
|
784
|
-
const contours =
|
|
803
|
+
const contours = _chunk7EDLVBOOcjs.pathToContours.call(void 0, path).filter((c) => c.segments.length > 0);
|
|
785
804
|
return contours.length > 0 && contours.every((c) => c.closed);
|
|
786
805
|
}
|
|
787
806
|
function effectiveStrokeAlign(style, closedShape) {
|
|
@@ -789,7 +808,7 @@ function effectiveStrokeAlign(style, closedShape) {
|
|
|
789
808
|
return closedShape ? a : "center";
|
|
790
809
|
}
|
|
791
810
|
function strokeWidthProfileOf(style) {
|
|
792
|
-
if (!_optionalChain([style, 'access',
|
|
811
|
+
if (!_optionalChain([style, 'access', _25 => _25.strokeWidthProfile, 'optionalAccess', _26 => _26.length])) return null;
|
|
793
812
|
const p = sanitizeWidthProfile(style.strokeWidthProfile);
|
|
794
813
|
return isUniformWidthProfile(p) ? null : p;
|
|
795
814
|
}
|
|
@@ -798,11 +817,11 @@ function hasStrokeExtras(style) {
|
|
|
798
817
|
}
|
|
799
818
|
function vectorStrokeLineArea(parts, style, tolerance) {
|
|
800
819
|
const profile = strokeWidthProfileOf(style);
|
|
801
|
-
const dash = _optionalChain([style, 'access',
|
|
820
|
+
const dash = _optionalChain([style, 'access', _27 => _27.strokeDasharray, 'optionalAccess', _28 => _28.length]) ? { dash: style.strokeDasharray } : {};
|
|
802
821
|
const join = _nullishCoalesce(style.strokeLinejoin, () => ( "miter"));
|
|
803
822
|
const cap = _nullishCoalesce(style.strokeLinecap, () => ( "butt"));
|
|
804
823
|
if (profile) return variableStrokeOutline(parts.line, { width: parts.drawWidth, profile, join, cap, ...dash, ...tolerance ? { tolerance } : {} });
|
|
805
|
-
return
|
|
824
|
+
return _chunk7EDLVBOOcjs.outlineStroke.call(void 0, parts.line, { width: parts.drawWidth, join, cap, ...dash, ...tolerance ? { tolerance } : {} });
|
|
806
825
|
}
|
|
807
826
|
var capExtent = (style, width) => style.strokeLinecap === "round" || style.strokeLinecap === "square" ? width / 2 : 0;
|
|
808
827
|
function arrowheadWeight(style, end) {
|
|
@@ -879,16 +898,16 @@ function arrowheadPath(kind, tip, dir, hw) {
|
|
|
879
898
|
}
|
|
880
899
|
}
|
|
881
900
|
var toVec = (p) => ({ x: p[0], y: p[1] });
|
|
882
|
-
var segLen = (s) =>
|
|
901
|
+
var segLen = (s) => _chunk7EDLVBOOcjs.segmentLength.call(void 0, s);
|
|
883
902
|
function endOf(segs, atStart) {
|
|
884
903
|
const long = (s2) => segLen(s2) > 1e-9;
|
|
885
904
|
if (atStart) {
|
|
886
905
|
const s2 = _nullishCoalesce(segs.find(long), () => ( segs[0]));
|
|
887
|
-
const t2 =
|
|
906
|
+
const t2 = _chunk7EDLVBOOcjs.segmentTangent.call(void 0, s2, 0);
|
|
888
907
|
return { p: toVec(segs[0][0]), out: v(-t2[0], -t2[1]) };
|
|
889
908
|
}
|
|
890
909
|
const s = _nullishCoalesce([...segs].reverse().find(long), () => ( segs[segs.length - 1]));
|
|
891
|
-
const t =
|
|
910
|
+
const t = _chunk7EDLVBOOcjs.segmentTangent.call(void 0, s, 1);
|
|
892
911
|
const last = segs[segs.length - 1];
|
|
893
912
|
return { p: toVec(last[last.length - 1]), out: v(t[0], t[1]) };
|
|
894
913
|
}
|
|
@@ -899,7 +918,7 @@ function pointAlong(segs, fromStart, dist4) {
|
|
|
899
918
|
const l = segLen(s);
|
|
900
919
|
if (acc + l >= dist4) {
|
|
901
920
|
const want = fromStart ? dist4 - acc : l - (dist4 - acc);
|
|
902
|
-
const pts =
|
|
921
|
+
const pts = _chunk7EDLVBOOcjs.trimSegments.call(void 0, [s], 0, want);
|
|
903
922
|
const p = pts.length ? pts[0][pts[0].length - 1] : s[0];
|
|
904
923
|
return toVec(p);
|
|
905
924
|
}
|
|
@@ -909,7 +928,7 @@ function pointAlong(segs, fromStart, dist4) {
|
|
|
909
928
|
}
|
|
910
929
|
function vectorStrokeParts(path, style) {
|
|
911
930
|
const width = _nullishCoalesce(style.strokeWidth, () => ( 1));
|
|
912
|
-
const contours =
|
|
931
|
+
const contours = _chunk7EDLVBOOcjs.pathToContours.call(void 0, path).filter((c) => c.segments.length > 0);
|
|
913
932
|
const closedShape = contours.length > 0 && contours.every((c) => c.closed);
|
|
914
933
|
const align = effectiveStrokeAlign(style, closedShape);
|
|
915
934
|
const drawWidth = align === "center" ? width : width * 2;
|
|
@@ -949,26 +968,26 @@ function vectorStrokeParts(path, style) {
|
|
|
949
968
|
if (!s0 && !s1) return c;
|
|
950
969
|
const lengths = c.segments.map(segLen);
|
|
951
970
|
const total = lengths.reduce((a, b) => a + b, 0);
|
|
952
|
-
return { closed: false, segments: total - s1 > s0 ?
|
|
971
|
+
return { closed: false, segments: total - s1 > s0 ? _chunk7EDLVBOOcjs.trimSegments.call(void 0, c.segments, s0, total - s1, lengths) : [] };
|
|
953
972
|
});
|
|
954
|
-
return { align, line:
|
|
973
|
+
return { align, line: _chunk7EDLVBOOcjs.contoursToPath.call(void 0, trimmed), drawWidth, heads };
|
|
955
974
|
}
|
|
956
975
|
function vectorStrokeOutlinePath(path, style) {
|
|
957
976
|
const parts = vectorStrokeParts(path, style);
|
|
958
977
|
const stroke = vectorStrokeLineArea(parts, style);
|
|
959
978
|
const fill = { path, fillRule: _nullishCoalesce(style.fillRule, () => ( "nonzero")) };
|
|
960
979
|
let area = stroke;
|
|
961
|
-
if (parts.align === "inside") area =
|
|
962
|
-
else if (parts.align === "outside") area =
|
|
980
|
+
if (parts.align === "inside") area = _chunk7EDLVBOOcjs.pathBoolean.call(void 0, "intersection", [stroke, fill]).path;
|
|
981
|
+
else if (parts.align === "outside") area = _chunk7EDLVBOOcjs.pathBoolean.call(void 0, "difference", [stroke, fill]).path;
|
|
963
982
|
if (!parts.heads.length) return area;
|
|
964
|
-
return
|
|
983
|
+
return _chunk7EDLVBOOcjs.pathBoolean.call(void 0, "union", [area, ...parts.heads.map((h) => h.path)]).path;
|
|
965
984
|
}
|
|
966
985
|
function hitTestVectorStroke(path, p, style, tolerance = 0) {
|
|
967
986
|
const parts = vectorStrokeParts(path, style);
|
|
968
987
|
const point = [p.x, p.y];
|
|
969
988
|
const width = _nullishCoalesce(style.strokeWidth, () => ( 1));
|
|
970
989
|
for (const h of parts.heads) {
|
|
971
|
-
if (
|
|
990
|
+
if (_chunk7EDLVBOOcjs.pointInBezierPath.call(void 0, h.path, point) || tolerance > 0 && _chunk7EDLVBOOcjs.distanceToBezierPath.call(void 0, h.path, point) <= tolerance) return true;
|
|
972
991
|
}
|
|
973
992
|
if (!parts.line.length) return false;
|
|
974
993
|
const profile = strokeWidthProfileOf(style);
|
|
@@ -986,13 +1005,13 @@ function hitTestVectorStroke(path, p, style, tolerance = 0) {
|
|
|
986
1005
|
reach = Math.max(reach, width / 2 * (w.left + w.right) / 2);
|
|
987
1006
|
}
|
|
988
1007
|
} else {
|
|
989
|
-
d =
|
|
1008
|
+
d = _chunk7EDLVBOOcjs.distanceToBezierPath.call(void 0, parts.line, point);
|
|
990
1009
|
if (parts.align !== "center") reach = width;
|
|
991
1010
|
}
|
|
992
1011
|
if (parts.align === "center") return d <= reach + tolerance;
|
|
993
1012
|
if (d > reach + tolerance) return false;
|
|
994
1013
|
if (d <= tolerance) return true;
|
|
995
|
-
const inside =
|
|
1014
|
+
const inside = _chunk7EDLVBOOcjs.pointInBezierPath.call(void 0, path, point, _nullishCoalesce(style.fillRule, () => ( "nonzero")));
|
|
996
1015
|
return parts.align === "inside" ? inside : !inside;
|
|
997
1016
|
}
|
|
998
1017
|
function vectorStrokeReach(style) {
|
|
@@ -1068,7 +1087,7 @@ function vectorNodeToBezier(node) {
|
|
|
1068
1087
|
}
|
|
1069
1088
|
function vectorPathData(input, precision = 3) {
|
|
1070
1089
|
const subpaths = Array.isArray(input) ? input : input.subpaths;
|
|
1071
|
-
return
|
|
1090
|
+
return _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, subpathsToBezier(subpaths), { precision });
|
|
1072
1091
|
}
|
|
1073
1092
|
function inferAnchorType(a) {
|
|
1074
1093
|
if (isOnAnchor(a, a.in) || isOnAnchor(a, a.out)) return "corner";
|
|
@@ -1084,7 +1103,7 @@ function inferAnchorType(a) {
|
|
|
1084
1103
|
return Math.abs(li - lo) <= 1e-3 * Math.max(li, lo) ? "symmetric" : "smooth";
|
|
1085
1104
|
}
|
|
1086
1105
|
function bezierToSubpaths(input) {
|
|
1087
|
-
const path =
|
|
1106
|
+
const path = _chunk7EDLVBOOcjs.toBezierPath.call(void 0, input);
|
|
1088
1107
|
const out = [];
|
|
1089
1108
|
let current = null;
|
|
1090
1109
|
const last = () => current.anchors[current.anchors.length - 1];
|
|
@@ -1181,14 +1200,14 @@ function nodeMatrix(node) {
|
|
|
1181
1200
|
function vectorPathWorldBezier(node, parent = IDENTITY_MATRIX) {
|
|
1182
1201
|
const m = multiplyMatrices(nodeMatrix(node), parent);
|
|
1183
1202
|
const path = subpathsToBezier(node.subpaths);
|
|
1184
|
-
return isIdentityMatrix(m) ? path :
|
|
1203
|
+
return isIdentityMatrix(m) ? path : _chunk7EDLVBOOcjs.transformBezierPath.call(void 0, path, m);
|
|
1185
1204
|
}
|
|
1186
1205
|
function vectorNodeBounds(node, parent = IDENTITY_MATRIX) {
|
|
1187
1206
|
if (node.type === "group") {
|
|
1188
1207
|
const m = multiplyMatrices(nodeMatrix(node), parent);
|
|
1189
1208
|
return unionBounds(node.children.map((c) => vectorNodeBounds(c, m)));
|
|
1190
1209
|
}
|
|
1191
|
-
const b =
|
|
1210
|
+
const b = _chunk7EDLVBOOcjs.bezierPathBounds.call(void 0, vectorPathWorldBezier(node, parent));
|
|
1192
1211
|
if (!b) return null;
|
|
1193
1212
|
return { x: b.minX, y: b.minY, width: b.maxX - b.minX, height: b.maxY - b.minY };
|
|
1194
1213
|
}
|
|
@@ -1222,9 +1241,9 @@ function hitTestVectorNode(node, p, tolerance = 0, parent = IDENTITY_MATRIX) {
|
|
|
1222
1241
|
const path = vectorPathWorldBezier(node, parent);
|
|
1223
1242
|
if (path.length === 0) return false;
|
|
1224
1243
|
const point = [p.x, p.y];
|
|
1225
|
-
if (hasPaint(node.fill) &&
|
|
1244
|
+
if (hasPaint(node.fill) && _chunk7EDLVBOOcjs.pointInBezierPath.call(void 0, path, point, _nullishCoalesce(node.fillRule, () => ( "nonzero")))) return true;
|
|
1226
1245
|
if (hasPaint(node.stroke)) return hitTestVectorStroke(path, p, node, tolerance);
|
|
1227
|
-
return
|
|
1246
|
+
return _chunk7EDLVBOOcjs.distanceToBezierPath.call(void 0, path, point) <= tolerance;
|
|
1228
1247
|
}
|
|
1229
1248
|
function vectorStrokeOutline(node, parent = IDENTITY_MATRIX) {
|
|
1230
1249
|
if (!hasPaint(node.stroke) || !((_nullishCoalesce(node.strokeWidth, () => ( 1))) > 0)) return [];
|
|
@@ -1244,9 +1263,9 @@ function nearestSegment(node, p) {
|
|
|
1244
1263
|
const count = subpathSegmentCount(sp);
|
|
1245
1264
|
for (let i = 0; i < count; i++) {
|
|
1246
1265
|
const seg = subpathSegment(sp, i);
|
|
1247
|
-
const hit =
|
|
1266
|
+
const hit = _chunk7EDLVBOOcjs.segmentNearest.call(void 0, seg, [p.x, p.y]);
|
|
1248
1267
|
if (!best || hit.distance < best.distance) {
|
|
1249
|
-
const pt2 =
|
|
1268
|
+
const pt2 = _chunk7EDLVBOOcjs.segmentPoint.call(void 0, seg, hit.t);
|
|
1250
1269
|
best = { subpath: s, segment: i, t: hit.t, point: { x: pt2[0], y: pt2[1] }, distance: hit.distance };
|
|
1251
1270
|
}
|
|
1252
1271
|
}
|
|
@@ -1306,7 +1325,7 @@ function bakeIntoGeometry(node, m) {
|
|
|
1306
1325
|
if (isIdentityMatrix(m)) return node;
|
|
1307
1326
|
if (node.type === "group") return { ...node, children: node.children.map((c) => transformVectorNode(c, m)) };
|
|
1308
1327
|
const path = node;
|
|
1309
|
-
const mirrored = m[0] * m[3] - m[1] * m[2] < 0 && _optionalChain([path, 'access',
|
|
1328
|
+
const mirrored = m[0] * m[3] - m[1] * m[2] < 0 && _optionalChain([path, 'access', _29 => _29.strokeWidthProfile, 'optionalAccess', _30 => _30.length]);
|
|
1310
1329
|
return {
|
|
1311
1330
|
...path,
|
|
1312
1331
|
...mirrored ? { strokeWidthProfile: mirrorWidthProfile(path.strokeWidthProfile) } : {},
|
|
@@ -1420,7 +1439,7 @@ function insertAnchor(sp, segment, t) {
|
|
|
1420
1439
|
const ia = segment;
|
|
1421
1440
|
const ib = (segment + 1) % n;
|
|
1422
1441
|
const seg = subpathSegment(sp, segment);
|
|
1423
|
-
const [left, right] =
|
|
1442
|
+
const [left, right] = _chunk7EDLVBOOcjs.splitSegment.call(void 0, seg, t);
|
|
1424
1443
|
const mid = left[left.length - 1];
|
|
1425
1444
|
const anchor = { x: mid[0], y: mid[1] };
|
|
1426
1445
|
if (seg.length === 4) {
|
|
@@ -1474,8 +1493,8 @@ function ellipseSubpath(b) {
|
|
|
1474
1493
|
]
|
|
1475
1494
|
};
|
|
1476
1495
|
}
|
|
1477
|
-
function polygonSubpath(b,
|
|
1478
|
-
const n = Math.max(3, Math.round(
|
|
1496
|
+
function polygonSubpath(b, sides2 = 6) {
|
|
1497
|
+
const n = Math.max(3, Math.round(sides2));
|
|
1479
1498
|
const cx = b.x + b.width / 2;
|
|
1480
1499
|
const cy = b.y + b.height / 2;
|
|
1481
1500
|
const anchors = [];
|
|
@@ -1516,7 +1535,7 @@ function vectorCornersAttribute(subpaths, precision = 3) {
|
|
|
1516
1535
|
subpaths.forEach(
|
|
1517
1536
|
(sp, s) => sp.anchors.forEach((a, i) => {
|
|
1518
1537
|
if (!a.corner || !(a.corner.radius > 0)) return;
|
|
1519
|
-
out.push(`${s}.${i}:${
|
|
1538
|
+
out.push(`${s}.${i}:${_chunk7EDLVBOOcjs.formatNumber.call(void 0, a.corner.radius, precision)}${a.corner.kind && a.corner.kind !== "round" ? `:${a.corner.kind}` : ""}`);
|
|
1520
1539
|
})
|
|
1521
1540
|
);
|
|
1522
1541
|
return out.join(" ");
|
|
@@ -1525,7 +1544,7 @@ function applyVectorCornersAttribute(subpaths, value) {
|
|
|
1525
1544
|
for (const item of value.trim().split(/\s+/)) {
|
|
1526
1545
|
const m = /^(\d+)\.(\d+):([\d.eE+-]+)(?::([a-z]+))?$/.exec(item);
|
|
1527
1546
|
if (!m) continue;
|
|
1528
|
-
const a = _optionalChain([subpaths, 'access',
|
|
1547
|
+
const a = _optionalChain([subpaths, 'access', _31 => _31[+m[1]], 'optionalAccess', _32 => _32.anchors, 'access', _33 => _33[+m[2]]]);
|
|
1529
1548
|
const radius = parseFloat(m[3]);
|
|
1530
1549
|
if (!a || !(radius > 0)) continue;
|
|
1531
1550
|
const kind = VECTOR_CORNER_KINDS.includes(m[4]) ? m[4] : void 0;
|
|
@@ -1537,7 +1556,7 @@ var escapeAttr = (value) => value.replace(/&/g, "&").replace(/"/g, """)
|
|
|
1537
1556
|
function vectorPaintToSvg(paint, gradientId) {
|
|
1538
1557
|
if (!hasPaint(paint)) return { value: "none", gradient: null };
|
|
1539
1558
|
if (typeof paint === "string") return { value: paint, gradient: null };
|
|
1540
|
-
return { value: `url(#${gradientId})`, gradient:
|
|
1559
|
+
return { value: `url(#${gradientId})`, gradient: _chunk7EDLVBOOcjs.gradientToSvgDef.call(void 0, paint, gradientId) };
|
|
1541
1560
|
}
|
|
1542
1561
|
var partsCache = /* @__PURE__ */ new WeakMap();
|
|
1543
1562
|
function vectorStrokeSvgParts(node, clipId, precision = 3) {
|
|
@@ -1555,22 +1574,22 @@ function computeStrokeSvgParts(node, clipId, precision) {
|
|
|
1555
1574
|
if (parts.align === "center" && !parts.heads.length && !profiled) return void 0;
|
|
1556
1575
|
let clip = null;
|
|
1557
1576
|
if (parts.align !== "center") {
|
|
1558
|
-
const b =
|
|
1577
|
+
const b = _chunk7EDLVBOOcjs.bezierPathBounds.call(void 0, path);
|
|
1559
1578
|
const pad = vectorStrokeReach(node) + 1;
|
|
1560
1579
|
const bounds = b ? { x: round2(b.minX - pad), y: round2(b.minY - pad), width: round2(b.maxX - b.minX + 2 * pad), height: round2(b.maxY - b.minY + 2 * pad) } : { x: 0, y: 0, width: 0, height: 0 };
|
|
1561
1580
|
clip = { kind: parts.align === "inside" ? "clip" : "mask", id: clipId, bounds };
|
|
1562
1581
|
}
|
|
1563
1582
|
return {
|
|
1564
1583
|
align: parts.align,
|
|
1565
|
-
d:
|
|
1584
|
+
d: _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, parts.line, { precision }),
|
|
1566
1585
|
width: parts.drawWidth,
|
|
1567
|
-
...profiled && (_nullishCoalesce(node.strokeWidth, () => ( 1))) > 0 ? { outline:
|
|
1586
|
+
...profiled && (_nullishCoalesce(node.strokeWidth, () => ( 1))) > 0 ? { outline: _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, vectorStrokeLineArea(parts, node), { precision }) } : {},
|
|
1568
1587
|
clip,
|
|
1569
|
-
heads: parts.heads.map((h) =>
|
|
1588
|
+
heads: parts.heads.map((h) => _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, h.path, { precision }))
|
|
1570
1589
|
};
|
|
1571
1590
|
}
|
|
1572
1591
|
function widthProfileToAttribute(points, precision = 4) {
|
|
1573
|
-
return points.map((p) => [p.t, p.left, p.right].map((n) =>
|
|
1592
|
+
return points.map((p) => [p.t, p.left, p.right].map((n) => _chunk7EDLVBOOcjs.formatNumber.call(void 0, n, precision)).join(",")).join(";");
|
|
1574
1593
|
}
|
|
1575
1594
|
function widthProfileFromAttribute(value) {
|
|
1576
1595
|
if (!value) return [];
|
|
@@ -1594,11 +1613,11 @@ function vectorDocumentToSvg(doc, options = {}) {
|
|
|
1594
1613
|
const pretty = options.pretty !== false;
|
|
1595
1614
|
const defs = [];
|
|
1596
1615
|
const lines = [];
|
|
1597
|
-
const num = (n) =>
|
|
1616
|
+
const num = (n) => _chunk7EDLVBOOcjs.formatNumber.call(void 0, n, precision);
|
|
1598
1617
|
const indent = (depth) => pretty ? " ".repeat(depth) : "";
|
|
1599
1618
|
const common = (node) => {
|
|
1600
1619
|
let out2 = ` id="${escapeAttr(node.id)}"`;
|
|
1601
|
-
if (node.transform) out2 += ` transform="matrix(${node.transform.map((n) =>
|
|
1620
|
+
if (node.transform) out2 += ` transform="matrix(${node.transform.map((n) => _chunk7EDLVBOOcjs.formatNumber.call(void 0, n, 6)).join(" ")})"`;
|
|
1602
1621
|
if (node.opacity !== void 0 && node.opacity < 1) out2 += ` opacity="${num(node.opacity)}"`;
|
|
1603
1622
|
if (node.visible === false) out2 += ` display="none"`;
|
|
1604
1623
|
return out2;
|
|
@@ -1617,13 +1636,13 @@ function vectorDocumentToSvg(doc, options = {}) {
|
|
|
1617
1636
|
if (stroke.gradient) defs.push(gradientMarkup(stroke.gradient));
|
|
1618
1637
|
const d = vectorPathData(node, precision);
|
|
1619
1638
|
const corners2 = vectorCornersAttribute(node.subpaths, precision);
|
|
1620
|
-
const live = corners2 ? ` data-vector-d="${
|
|
1639
|
+
const live = corners2 ? ` data-vector-d="${_chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, subpathsToBezier(node.subpaths, { corners: false }), { precision })}" data-vector-corners="${corners2}"` : "";
|
|
1621
1640
|
const fillAttrs = ` fill="${escapeAttr(fill.value)}"${node.fillRule === "evenodd" ? ` fill-rule="evenodd"` : ""}`;
|
|
1622
1641
|
const lineAttrs = (width) => {
|
|
1623
1642
|
let out2 = ` stroke="${escapeAttr(stroke.value)}" stroke-width="${num(width)}"`;
|
|
1624
1643
|
if (node.strokeLinecap && node.strokeLinecap !== "butt") out2 += ` stroke-linecap="${node.strokeLinecap}"`;
|
|
1625
1644
|
if (node.strokeLinejoin && node.strokeLinejoin !== "miter") out2 += ` stroke-linejoin="${node.strokeLinejoin}"`;
|
|
1626
|
-
if (_optionalChain([node, 'access',
|
|
1645
|
+
if (_optionalChain([node, 'access', _34 => _34.strokeDasharray, 'optionalAccess', _35 => _35.length])) out2 += ` stroke-dasharray="${node.strokeDasharray.map(num).join(" ")}"`;
|
|
1627
1646
|
return out2;
|
|
1628
1647
|
};
|
|
1629
1648
|
const parts = stroke.value !== "none" ? vectorStrokeSvgParts(node, `${prefix}clip-${node.id}`, precision) : void 0;
|
|
@@ -1643,12 +1662,12 @@ function vectorDocumentToSvg(doc, options = {}) {
|
|
|
1643
1662
|
data += ` data-vector-width-profile="${widthProfileToAttribute(profile)}"`;
|
|
1644
1663
|
if (node.strokeLinecap && node.strokeLinecap !== "butt") data += ` data-vector-stroke-linecap="${node.strokeLinecap}"`;
|
|
1645
1664
|
if (node.strokeLinejoin && node.strokeLinejoin !== "miter") data += ` data-vector-stroke-linejoin="${node.strokeLinejoin}"`;
|
|
1646
|
-
if (_optionalChain([node, 'access',
|
|
1665
|
+
if (_optionalChain([node, 'access', _36 => _36.strokeDasharray, 'optionalAccess', _37 => _37.length])) data += ` data-vector-stroke-dasharray="${node.strokeDasharray.map(num).join(" ")}"`;
|
|
1647
1666
|
}
|
|
1648
1667
|
lines.push(`${indent(depth)}<g${common(node)}${data}>`);
|
|
1649
1668
|
lines.push(`${indent(depth + 1)}<path data-vector-part="fill" d="${d}"${fillAttrs}${live}/>`);
|
|
1650
1669
|
if (options.strokes === "outline") {
|
|
1651
|
-
const area =
|
|
1670
|
+
const area = _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, vectorStrokeOutlinePath(subpathsToBezier(node.subpaths), node), { precision });
|
|
1652
1671
|
lines.push(`${indent(depth + 1)}<path data-vector-part="stroke-outline" d="${area}" fill="${escapeAttr(stroke.value)}"/>`);
|
|
1653
1672
|
} else {
|
|
1654
1673
|
let clip = "";
|
|
@@ -1812,7 +1831,7 @@ function resolveGradient(id, raw, seen = /* @__PURE__ */ new Set()) {
|
|
|
1812
1831
|
seen.add(id);
|
|
1813
1832
|
let stops = readStops(el);
|
|
1814
1833
|
const href = _nullishCoalesce(el.attrs.href, () => ( el.attrs["xlink:href"]));
|
|
1815
|
-
if (!stops.length && _optionalChain([href, 'optionalAccess',
|
|
1834
|
+
if (!stops.length && _optionalChain([href, 'optionalAccess', _38 => _38.startsWith, 'call', _39 => _39("#")])) stops = _nullishCoalesce(_optionalChain([resolveGradient, 'call', _40 => _40(href.slice(1), raw, seen), 'optionalAccess', _41 => _41.stops]), () => ( []));
|
|
1816
1835
|
if (!stops.length) return null;
|
|
1817
1836
|
if (el.name === "radialGradient") {
|
|
1818
1837
|
return { type: "radial", cx: fraction(el.attrs.cx, 0.5), cy: fraction(el.attrs.cy, 0.5), r: fraction(el.attrs.r, 0.5), stops };
|
|
@@ -1916,7 +1935,7 @@ function parseVectorSvg(svg, options = {}) {
|
|
|
1916
1935
|
const part = (name) => g.children.find((c) => c.name === "path" && c.attrs["data-vector-part"] === name);
|
|
1917
1936
|
const fillEl = part("fill");
|
|
1918
1937
|
const subpaths = fillEl ? shapeOf(fillEl) : null;
|
|
1919
|
-
if (!fillEl || !_optionalChain([subpaths, 'optionalAccess',
|
|
1938
|
+
if (!fillEl || !_optionalChain([subpaths, 'optionalAccess', _42 => _42.length])) return null;
|
|
1920
1939
|
const a = g.attrs;
|
|
1921
1940
|
const fs = readStyle(fillEl, style);
|
|
1922
1941
|
const strokeEl = part("stroke");
|
|
@@ -1953,7 +1972,7 @@ function parseVectorSvg(svg, options = {}) {
|
|
|
1953
1972
|
...profile.length ? { strokeWidthProfile: profile } : {},
|
|
1954
1973
|
...keptCap ? { strokeLinecap: keptCap } : {},
|
|
1955
1974
|
...keptJoin ? { strokeLinejoin: keptJoin } : {},
|
|
1956
|
-
..._optionalChain([keptDash, 'optionalAccess',
|
|
1975
|
+
..._optionalChain([keptDash, 'optionalAccess', _43 => _43.length]) ? { strokeDasharray: keptDash } : {}
|
|
1957
1976
|
};
|
|
1958
1977
|
return placed(node, m);
|
|
1959
1978
|
};
|
|
@@ -2007,7 +2026,7 @@ function parseVectorSvg(svg, options = {}) {
|
|
|
2007
2026
|
// src/vector/snap.ts
|
|
2008
2027
|
var VECTOR_CONSTRUCTION_ANGLES = [0, 45, 90, 135];
|
|
2009
2028
|
function constrainToLeave(leave, p) {
|
|
2010
|
-
if (!_optionalChain([leave, 'optionalAccess',
|
|
2029
|
+
if (!_optionalChain([leave, 'optionalAccess', _44 => _44.constrain])) return p;
|
|
2011
2030
|
const dx = p.x - leave.at.x;
|
|
2012
2031
|
const dy = p.y - leave.at.y;
|
|
2013
2032
|
switch (leave.constrain) {
|
|
@@ -2118,7 +2137,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2118
2137
|
moving.set(r.nodeId, set);
|
|
2119
2138
|
}
|
|
2120
2139
|
const t = _VectorSnapTargets.collect(doc, new Set(moving.keys()), "segments", false);
|
|
2121
|
-
t.pushPaths(doc, new Set(moving.keys()), (id, s, i) => !!_optionalChain([moving, 'access',
|
|
2140
|
+
t.pushPaths(doc, new Set(moving.keys()), (id, s, i) => !!_optionalChain([moving, 'access', _45 => _45.get, 'call', _46 => _46(id), 'optionalAccess', _47 => _47.has, 'call', _48 => _48(`${s}:${i}`)]), true);
|
|
2122
2141
|
return t.index();
|
|
2123
2142
|
}
|
|
2124
2143
|
/**
|
|
@@ -2236,7 +2255,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2236
2255
|
}
|
|
2237
2256
|
const b = vectorNodeBounds(n, parent);
|
|
2238
2257
|
const f = nodeFrame(n, parent, b);
|
|
2239
|
-
if (b) self.pushRect(b, "edge", _nullishCoalesce(_optionalChain([f, 'optionalAccess',
|
|
2258
|
+
if (b) self.pushRect(b, "edge", _nullishCoalesce(_optionalChain([f, 'optionalAccess', _49 => _49.centre]), () => ( null)));
|
|
2240
2259
|
}
|
|
2241
2260
|
};
|
|
2242
2261
|
visit(doc.nodes, IDENTITY_MATRIX);
|
|
@@ -2281,7 +2300,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2281
2300
|
lines: lines2,
|
|
2282
2301
|
labels: [this.label(q, kind)]
|
|
2283
2302
|
});
|
|
2284
|
-
if (_optionalChain([leave, 'optionalAccess',
|
|
2303
|
+
if (_optionalChain([leave, 'optionalAccess', _50 => _50.constrain])) {
|
|
2285
2304
|
const q = constrainToLeave(leave, p);
|
|
2286
2305
|
const hit = this.slide(leave.at, { x: q.x - leave.at.x, y: q.y - leave.at.y }, q, tol, true);
|
|
2287
2306
|
return hit ? { point: hit.point, x: true, y: true, ...this.linedUp(hit.point, hit.from) } : none(q);
|
|
@@ -2297,7 +2316,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2297
2316
|
}
|
|
2298
2317
|
const on = this.onSegment(near2);
|
|
2299
2318
|
if (on) return at2(on, "path");
|
|
2300
|
-
if (_optionalChain([leave, 'optionalAccess',
|
|
2319
|
+
if (_optionalChain([leave, 'optionalAccess', _51 => _51.angles, 'optionalAccess', _52 => _52.length])) {
|
|
2301
2320
|
const c = construction(leave, p, tol);
|
|
2302
2321
|
if (c) {
|
|
2303
2322
|
const hit = this.slide(leave.at, c.dir, c.point, tol, false);
|
|
@@ -2373,13 +2392,13 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2373
2392
|
const pt2 = toPoint(p);
|
|
2374
2393
|
for (const s of this.segments) {
|
|
2375
2394
|
if (p.x < s.minX - tol || p.x > s.maxX + tol || p.y < s.minY - tol || p.y > s.maxY + tol) continue;
|
|
2376
|
-
const hit =
|
|
2395
|
+
const hit = _chunk7EDLVBOOcjs.segmentNearest.call(void 0, s.seg, pt2);
|
|
2377
2396
|
if (hit.distance <= tol) out.push({ seg: s.seg, t: hit.t, distance: hit.distance });
|
|
2378
2397
|
}
|
|
2379
2398
|
return out.sort((a, b) => a.distance - b.distance);
|
|
2380
2399
|
}
|
|
2381
2400
|
onSegment(near2) {
|
|
2382
|
-
return near2.length ? toVec2(
|
|
2401
|
+
return near2.length ? toVec2(_chunk7EDLVBOOcjs.segmentPoint.call(void 0, near2[0].seg, near2[0].t)) : null;
|
|
2383
2402
|
}
|
|
2384
2403
|
/** Where two of the target segments near `p` cross, the crossing nearest `p` within `tol`. */
|
|
2385
2404
|
crossing(near2, p, tol) {
|
|
@@ -2388,7 +2407,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2388
2407
|
let bestD = Infinity;
|
|
2389
2408
|
for (let i = 0; i < list.length; i++) {
|
|
2390
2409
|
for (let j = i + 1; j < list.length; j++) {
|
|
2391
|
-
for (const hit of
|
|
2410
|
+
for (const hit of _chunk7EDLVBOOcjs.segmentIntersections.call(void 0, list[i].seg, list[j].seg)) {
|
|
2392
2411
|
const q = toVec2(hit.point);
|
|
2393
2412
|
const d = distance(q, p);
|
|
2394
2413
|
if (d <= tol && d < bestD) {
|
|
@@ -2427,7 +2446,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2427
2446
|
* with nothing spaces the box evenly in its row or column. Returns the correction and guides.
|
|
2428
2447
|
*/
|
|
2429
2448
|
snapRect(r, tol, options = {}) {
|
|
2430
|
-
const axes = { x: _optionalChain([options, 'access',
|
|
2449
|
+
const axes = { x: _optionalChain([options, 'access', _53 => _53.axes, 'optionalAccess', _54 => _54.x]) !== false, y: _optionalChain([options, 'access', _55 => _55.axes, 'optionalAccess', _56 => _56.y]) !== false };
|
|
2431
2450
|
const nearest = (lines, values) => {
|
|
2432
2451
|
let best = null;
|
|
2433
2452
|
for (const v2 of values) for (const l of linesNear(lines, v2, tol)) if (!best || Math.abs(l.v - v2) < Math.abs(best.d)) best = { d: l.v - v2, from: l.from };
|
|
@@ -2435,7 +2454,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2435
2454
|
};
|
|
2436
2455
|
const bx = axes.x ? nearest(this.xs, [r.x, r.x + r.width / 2, r.x + r.width]) : null;
|
|
2437
2456
|
const by = axes.y ? nearest(this.ys, [r.y, r.y + r.height / 2, r.y + r.height]) : null;
|
|
2438
|
-
const out = { dx: _nullishCoalesce(_optionalChain([bx, 'optionalAccess',
|
|
2457
|
+
const out = { dx: _nullishCoalesce(_optionalChain([bx, 'optionalAccess', _57 => _57.d]), () => ( 0)), dy: _nullishCoalesce(_optionalChain([by, 'optionalAccess', _58 => _58.d]), () => ( 0)), x: !!bx, y: !!by, lines: [], labels: [] };
|
|
2439
2458
|
const done = { ...r, x: r.x + out.dx, y: r.y + out.dy };
|
|
2440
2459
|
if (bx) {
|
|
2441
2460
|
const x = bx.from.x;
|
|
@@ -2558,9 +2577,9 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2558
2577
|
const on = this.nearestPoint(p, tol);
|
|
2559
2578
|
const tries = [];
|
|
2560
2579
|
if (on) tries.push({ tx: on.p.x, ty: on.p.y, s: { hx: null, hy: null, on } });
|
|
2561
|
-
tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess',
|
|
2562
|
-
tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess',
|
|
2563
|
-
tries.push({ tx: null, ty: _nullishCoalesce(_optionalChain([hy, 'optionalAccess',
|
|
2580
|
+
tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess', _59 => _59.v]), () => ( null)), ty: _nullishCoalesce(_optionalChain([hy, 'optionalAccess', _60 => _60.v]), () => ( null)), s: { hx, hy, on: null } });
|
|
2581
|
+
tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess', _61 => _61.v]), () => ( null)), ty: null, s: { hx, hy: null, on: null } });
|
|
2582
|
+
tries.push({ tx: null, ty: _nullishCoalesce(_optionalChain([hy, 'optionalAccess', _62 => _62.v]), () => ( null)), s: { hx: null, hy, on: null } });
|
|
2564
2583
|
for (const { tx, ty, s } of tries) {
|
|
2565
2584
|
if (tx === null && ty === null) continue;
|
|
2566
2585
|
const q = applyMatrix(toLocal, { x: _nullishCoalesce(tx, () => ( p.x)), y: _nullishCoalesce(ty, () => ( p.y)) });
|
|
@@ -2710,15 +2729,15 @@ var crossCondition = (r, d) => r[0] * d[1] - r[1] * d[0];
|
|
|
2710
2729
|
function solveOnSegment(seg, base, cond) {
|
|
2711
2730
|
const b = [base.x, base.y];
|
|
2712
2731
|
const g = (t) => {
|
|
2713
|
-
const p =
|
|
2714
|
-
return cond([p[0] - b[0], p[1] - b[1]],
|
|
2732
|
+
const p = _chunk7EDLVBOOcjs.segmentPoint.call(void 0, seg, t);
|
|
2733
|
+
return cond([p[0] - b[0], p[1] - b[1]], _chunk7EDLVBOOcjs.segmentDerivative.call(void 0, seg, t));
|
|
2715
2734
|
};
|
|
2716
2735
|
const vals = [];
|
|
2717
2736
|
let scale = 0;
|
|
2718
2737
|
for (let i = 0; i <= CURVE_SAMPLES; i++) {
|
|
2719
2738
|
const t = i / CURVE_SAMPLES;
|
|
2720
|
-
const p =
|
|
2721
|
-
const d =
|
|
2739
|
+
const p = _chunk7EDLVBOOcjs.segmentPoint.call(void 0, seg, t);
|
|
2740
|
+
const d = _chunk7EDLVBOOcjs.segmentDerivative.call(void 0, seg, t);
|
|
2722
2741
|
const r = [p[0] - b[0], p[1] - b[1]];
|
|
2723
2742
|
vals.push(cond(r, d));
|
|
2724
2743
|
scale = Math.max(scale, Math.hypot(r[0], r[1]) * Math.hypot(d[0], d[1]));
|
|
@@ -2745,8 +2764,8 @@ function solveOnSegment(seg, base, cond) {
|
|
|
2745
2764
|
} else hi = m;
|
|
2746
2765
|
}
|
|
2747
2766
|
const t = (lo + hi) / 2;
|
|
2748
|
-
const p =
|
|
2749
|
-
const dv =
|
|
2767
|
+
const p = _chunk7EDLVBOOcjs.segmentPoint.call(void 0, seg, t);
|
|
2768
|
+
const dv = _chunk7EDLVBOOcjs.segmentDerivative.call(void 0, seg, t);
|
|
2750
2769
|
const r = Math.hypot(p[0] - b[0], p[1] - b[1]);
|
|
2751
2770
|
const dl = Math.hypot(dv[0], dv[1]);
|
|
2752
2771
|
if (!(r > 1e-9 && dl > 0) || Math.abs(cond([p[0] - b[0], p[1] - b[1]], dv)) > 1e-6 * r * dl) continue;
|
|
@@ -2783,7 +2802,7 @@ function endTangent(c) {
|
|
|
2783
2802
|
return [1, 0];
|
|
2784
2803
|
}
|
|
2785
2804
|
function sample(c, n, out, withStart) {
|
|
2786
|
-
for (let i = withStart ? 0 : 1; i <= n; i++) out.push(
|
|
2805
|
+
for (let i = withStart ? 0 : 1; i <= n; i++) out.push(_chunk7EDLVBOOcjs.segmentPoint.call(void 0, c, i / n));
|
|
2787
2806
|
}
|
|
2788
2807
|
var onAnchor2 = (a, h) => !h || Math.abs(h.x - a.x) < EPS3 && Math.abs(h.y - a.y) < EPS3;
|
|
2789
2808
|
function tidy(a, keepType = true) {
|
|
@@ -2829,7 +2848,7 @@ function fitAcross(pts, N, t0, t1) {
|
|
|
2829
2848
|
const u = [];
|
|
2830
2849
|
for (let i = 0; i <= N; i++) u.push(k * i / N);
|
|
2831
2850
|
for (let i = 1; i <= N; i++) u.push(k + (1 - k) * i / N);
|
|
2832
|
-
return
|
|
2851
|
+
return _chunk7EDLVBOOcjs.fitCubicWithTangents.call(void 0, pts, u, t0, t1);
|
|
2833
2852
|
};
|
|
2834
2853
|
return goldenMin(fit, 0, 1);
|
|
2835
2854
|
}
|
|
@@ -2889,7 +2908,7 @@ function bendSegment(sp, segment, t, p) {
|
|
|
2889
2908
|
return { anchors, closed: sp.closed };
|
|
2890
2909
|
}
|
|
2891
2910
|
function subpathPointAt(sp, segment, t) {
|
|
2892
|
-
const [x, y] =
|
|
2911
|
+
const [x, y] = _chunk7EDLVBOOcjs.segmentPoint.call(void 0, subpathSegment(sp, segment), t);
|
|
2893
2912
|
return { x, y };
|
|
2894
2913
|
}
|
|
2895
2914
|
function curvatureMoveAnchor(sp, index, q) {
|
|
@@ -3150,20 +3169,20 @@ function removeRedundantPoints(sp, tolerance) {
|
|
|
3150
3169
|
}
|
|
3151
3170
|
|
|
3152
3171
|
// src/vector/pathCut.ts
|
|
3153
|
-
var loopArea = (l) =>
|
|
3172
|
+
var loopArea = (l) => _chunk7EDLVBOOcjs.contourSignedArea.call(void 0, l.segs);
|
|
3154
3173
|
function loopSample(l) {
|
|
3155
3174
|
const k = l.chord.findIndex((c) => !c);
|
|
3156
|
-
return
|
|
3175
|
+
return _chunk7EDLVBOOcjs.segmentPoint.call(void 0, l.segs[k >= 0 ? k : 0], 0.5);
|
|
3157
3176
|
}
|
|
3158
|
-
var contains2 = (l, p) =>
|
|
3177
|
+
var contains2 = (l, p) => _chunk7EDLVBOOcjs.windingNumber.call(void 0, [l.segs], p) !== 0;
|
|
3159
3178
|
function groupFaces(loops) {
|
|
3160
|
-
const
|
|
3161
|
-
if (!
|
|
3162
|
-
const largest =
|
|
3179
|
+
const usable2 = loops.filter((l) => l.segs.length && Math.abs(loopArea(l)) > 1e-12);
|
|
3180
|
+
if (!usable2.length) return [];
|
|
3181
|
+
const largest = usable2.reduce((a, b) => Math.abs(loopArea(b)) > Math.abs(loopArea(a)) ? b : a);
|
|
3163
3182
|
const sign = Math.sign(loopArea(largest));
|
|
3164
|
-
const outers =
|
|
3183
|
+
const outers = usable2.filter((l) => Math.sign(loopArea(l)) === sign).sort((a, b) => Math.abs(loopArea(a)) - Math.abs(loopArea(b)));
|
|
3165
3184
|
const faces = new Map(outers.map((o) => [o, { loops: [o] }]));
|
|
3166
|
-
for (const hole of
|
|
3185
|
+
for (const hole of usable2.filter((l) => Math.sign(loopArea(l)) !== sign)) {
|
|
3167
3186
|
const p = loopSample(hole);
|
|
3168
3187
|
const parent = outers.find((o) => Math.abs(loopArea(o)) > Math.abs(loopArea(hole)) && contains2(o, p));
|
|
3169
3188
|
if (parent) faces.get(parent).loops.push(hole);
|
|
@@ -3171,12 +3190,12 @@ function groupFaces(loops) {
|
|
|
3171
3190
|
return outers.reverse().map((o) => faces.get(o));
|
|
3172
3191
|
}
|
|
3173
3192
|
function faceToPath(face) {
|
|
3174
|
-
return
|
|
3193
|
+
return _chunk7EDLVBOOcjs.contoursToPath.call(void 0, face.loops.map((l) => ({ segments: l.segs, closed: true })));
|
|
3175
3194
|
}
|
|
3176
3195
|
function facesOf(path, fillRule) {
|
|
3177
|
-
const normalized =
|
|
3178
|
-
const loops =
|
|
3179
|
-
const segs =
|
|
3196
|
+
const normalized = _chunk7EDLVBOOcjs.normalizeBezierPath.call(void 0, path, fillRule);
|
|
3197
|
+
const loops = _chunk7EDLVBOOcjs.pathToContours.call(void 0, normalized).map((c) => {
|
|
3198
|
+
const segs = _chunk7EDLVBOOcjs.closeContour.call(void 0, c, true).map((s) => s.slice());
|
|
3180
3199
|
return { segs, chord: segs.map(() => false) };
|
|
3181
3200
|
});
|
|
3182
3201
|
return groupFaces(loops);
|
|
@@ -3246,7 +3265,7 @@ function lineHits(p, q, seg) {
|
|
|
3246
3265
|
const scale = Math.sqrt(len2) * Math.max(1, ...seg.map((pt2) => Math.abs(pt2[0]) + Math.abs(pt2[1])));
|
|
3247
3266
|
const out = [];
|
|
3248
3267
|
for (const t of rootsInUnit(...coeffs, scale)) {
|
|
3249
|
-
const point =
|
|
3268
|
+
const point = _chunk7EDLVBOOcjs.segmentPoint.call(void 0, seg, t);
|
|
3250
3269
|
const s = ((point[0] - p[0]) * dx + (point[1] - p[1]) * dy) / len2;
|
|
3251
3270
|
if (s >= -1e-9 && s <= 1 + 1e-9) out.push({ s: Math.min(1, Math.max(0, s)), t, point });
|
|
3252
3271
|
}
|
|
@@ -3259,7 +3278,7 @@ function arc(l, a, b, eps) {
|
|
|
3259
3278
|
const segs = [];
|
|
3260
3279
|
const chord = [];
|
|
3261
3280
|
const push = (k, t0, t1) => {
|
|
3262
|
-
const piece = t0 <= 0 && t1 >= 1 ? l.segs[k].slice() :
|
|
3281
|
+
const piece = t0 <= 0 && t1 >= 1 ? l.segs[k].slice() : _chunk7EDLVBOOcjs.subSegment.call(void 0, l.segs[k], t0, t1);
|
|
3263
3282
|
if (!degenerate(piece, eps)) {
|
|
3264
3283
|
segs.push(piece);
|
|
3265
3284
|
chord.push(l.chord[k]);
|
|
@@ -3284,7 +3303,7 @@ function knifePath(path, fillRule, knife) {
|
|
|
3284
3303
|
if (pts.length < 2) return null;
|
|
3285
3304
|
let faces = facesOf(path, fillRule);
|
|
3286
3305
|
if (!faces.length) return null;
|
|
3287
|
-
const b =
|
|
3306
|
+
const b = _chunk7EDLVBOOcjs.bezierPathBounds.call(void 0, path);
|
|
3288
3307
|
const size = b ? Math.max(b.maxX - b.minX, b.maxY - b.minY, 1) : 1;
|
|
3289
3308
|
const eps = size * 1e-9;
|
|
3290
3309
|
let cursor = -Infinity;
|
|
@@ -3298,7 +3317,7 @@ function knifePath(path, fillRule, knife) {
|
|
|
3298
3317
|
const kb = { minX: Math.min(pts[m][0], pts[m + 1][0]), maxX: Math.max(pts[m][0], pts[m + 1][0]), minY: Math.min(pts[m][1], pts[m + 1][1]), maxY: Math.max(pts[m][1], pts[m + 1][1]) };
|
|
3299
3318
|
face2.loops.forEach(
|
|
3300
3319
|
(l, li) => l.segs.forEach((seg, si) => {
|
|
3301
|
-
const sb =
|
|
3320
|
+
const sb = _chunk7EDLVBOOcjs.segmentBounds.call(void 0, seg);
|
|
3302
3321
|
if (sb.maxX < kb.minX - eps || sb.minX > kb.maxX + eps || sb.maxY < kb.minY - eps || sb.minY > kb.maxY + eps) return;
|
|
3303
3322
|
for (const h of lineHits(pts[m], pts[m + 1], seg)) {
|
|
3304
3323
|
const s = m + h.s;
|
|
@@ -3313,7 +3332,7 @@ function knifePath(path, fillRule, knife) {
|
|
|
3313
3332
|
const m = Math.min(pts.length - 2, Math.floor(s));
|
|
3314
3333
|
const u = s - m;
|
|
3315
3334
|
const q = [pts[m][0] + (pts[m + 1][0] - pts[m][0]) * u, pts[m][1] + (pts[m + 1][1] - pts[m][1]) * u];
|
|
3316
|
-
return
|
|
3335
|
+
return _chunk7EDLVBOOcjs.windingNumber.call(void 0, face2.loops.map((l) => l.segs), q) !== 0;
|
|
3317
3336
|
};
|
|
3318
3337
|
for (let i = 0; i < unique.length - 1; i++) {
|
|
3319
3338
|
const from2 = unique[i];
|
|
@@ -3373,33 +3392,33 @@ function eraserRegion(points, width) {
|
|
|
3373
3392
|
];
|
|
3374
3393
|
}
|
|
3375
3394
|
const line2 = [{ type: "M", x: pts[0][0], y: pts[0][1] }, ...pts.slice(1).map((p) => ({ type: "L", x: p[0], y: p[1] }))];
|
|
3376
|
-
return
|
|
3395
|
+
return _chunk7EDLVBOOcjs.outlineStroke.call(void 0, line2, { width, cap: "round", join: "round" });
|
|
3377
3396
|
}
|
|
3378
3397
|
function eraseFromFill(path, fillRule, region) {
|
|
3379
|
-
const overlap =
|
|
3380
|
-
if (!
|
|
3381
|
-
const rest =
|
|
3398
|
+
const overlap = _chunk7EDLVBOOcjs.pathBoolean.call(void 0, "intersection", [{ path, fillRule }, { path: region }]).path;
|
|
3399
|
+
if (!_chunk7EDLVBOOcjs.pathToContours.call(void 0, overlap).some((c) => Math.abs(_chunk7EDLVBOOcjs.contourSignedArea.call(void 0, _chunk7EDLVBOOcjs.closeContour.call(void 0, c, true))) > 1e-9)) return null;
|
|
3400
|
+
const rest = _chunk7EDLVBOOcjs.pathBoolean.call(void 0, "difference", [{ path, fillRule }, { path: region }]).path;
|
|
3382
3401
|
return splitIntoFaces(rest);
|
|
3383
3402
|
}
|
|
3384
3403
|
function eraseFromOutline(sp, region) {
|
|
3385
|
-
const regionSegs =
|
|
3404
|
+
const regionSegs = _chunk7EDLVBOOcjs.pathToContours.call(void 0, region).flatMap((c) => _chunk7EDLVBOOcjs.closeContour.call(void 0, c, true));
|
|
3386
3405
|
if (!regionSegs.length) return null;
|
|
3387
|
-
const rb =
|
|
3406
|
+
const rb = _chunk7EDLVBOOcjs.bezierPathBounds.call(void 0, region);
|
|
3388
3407
|
const count = subpathSegmentCount(sp);
|
|
3389
3408
|
if (!rb || count === 0) return null;
|
|
3390
|
-
const removed = (p) =>
|
|
3409
|
+
const removed = (p) => _chunk7EDLVBOOcjs.pointInBezierPath.call(void 0, region, p, "nonzero");
|
|
3391
3410
|
const runs = [];
|
|
3392
3411
|
let cur = [];
|
|
3393
3412
|
let any = false;
|
|
3394
3413
|
for (let i = 0; i < count; i++) {
|
|
3395
3414
|
const seg = subpathSegment(sp, i);
|
|
3396
|
-
const sb =
|
|
3415
|
+
const sb = _chunk7EDLVBOOcjs.segmentBounds.call(void 0, seg);
|
|
3397
3416
|
const ts = [0, 1];
|
|
3398
3417
|
if (!(sb.maxX < rb.minX || sb.minX > rb.maxX || sb.maxY < rb.minY || sb.minY > rb.maxY)) {
|
|
3399
3418
|
for (const r of regionSegs) {
|
|
3400
|
-
const b =
|
|
3419
|
+
const b = _chunk7EDLVBOOcjs.segmentBounds.call(void 0, r);
|
|
3401
3420
|
if (b.maxX < sb.minX || b.minX > sb.maxX || b.maxY < sb.minY || b.minY > sb.maxY) continue;
|
|
3402
|
-
for (const hit of
|
|
3421
|
+
for (const hit of _chunk7EDLVBOOcjs.segmentIntersections.call(void 0, seg, r)) if (hit.ta > 1e-9 && hit.ta < 1 - 1e-9) ts.push(hit.ta);
|
|
3403
3422
|
}
|
|
3404
3423
|
}
|
|
3405
3424
|
ts.sort((a, b) => a - b);
|
|
@@ -3407,7 +3426,7 @@ function eraseFromOutline(sp, region) {
|
|
|
3407
3426
|
const t0 = ts[k];
|
|
3408
3427
|
const t1 = ts[k + 1];
|
|
3409
3428
|
if (t1 - t0 < 1e-9) continue;
|
|
3410
|
-
if (removed(
|
|
3429
|
+
if (removed(_chunk7EDLVBOOcjs.segmentPoint.call(void 0, seg, (t0 + t1) / 2))) {
|
|
3411
3430
|
any = true;
|
|
3412
3431
|
if (cur.length) runs.push(cur);
|
|
3413
3432
|
cur = [];
|
|
@@ -3426,7 +3445,7 @@ function eraseFromOutline(sp, region) {
|
|
|
3426
3445
|
for (const run of runs) {
|
|
3427
3446
|
const anchors = [];
|
|
3428
3447
|
for (const { seg, t0, t1 } of run) {
|
|
3429
|
-
const c =
|
|
3448
|
+
const c = _chunk7EDLVBOOcjs.subSegment.call(void 0, subpathSegment(sp, seg), t0, t1);
|
|
3430
3449
|
const line2 = c.length === 2;
|
|
3431
3450
|
const start = c[0];
|
|
3432
3451
|
const end = c[c.length - 1];
|
|
@@ -3715,15 +3734,187 @@ function recognizeInkShape(points, options = {}) {
|
|
|
3715
3734
|
return roundish && rms < 0.1 ? ellipse() : null;
|
|
3716
3735
|
}
|
|
3717
3736
|
|
|
3737
|
+
// src/vector/builder.ts
|
|
3738
|
+
function vectorPathEntries(doc, roots, options = {}) {
|
|
3739
|
+
const out = [];
|
|
3740
|
+
const visit = (node, parent, inside) => {
|
|
3741
|
+
if (node.visible === false || node.locked && !options.locked) return;
|
|
3742
|
+
const picked = inside || roots === null || roots.includes(node.id);
|
|
3743
|
+
if (node.type === "group") {
|
|
3744
|
+
const m = multiplyMatrices(nodeMatrix(node), parent);
|
|
3745
|
+
for (const c of node.children) visit(c, m, picked);
|
|
3746
|
+
} else if (picked) out.push({ node, parent });
|
|
3747
|
+
};
|
|
3748
|
+
for (const n of doc.nodes) visit(n, IDENTITY_MATRIX, false);
|
|
3749
|
+
return out;
|
|
3750
|
+
}
|
|
3751
|
+
var usable = (sp) => sp.anchors.length > 1;
|
|
3752
|
+
function worldOf(entry, subpaths) {
|
|
3753
|
+
return vectorPathWorldBezier({ ...entry.node, subpaths }, entry.parent);
|
|
3754
|
+
}
|
|
3755
|
+
function subpathEnclosesArea(sp) {
|
|
3756
|
+
const contour = _chunk7EDLVBOOcjs.pathToContours.call(void 0, subpathsToBezier([{ ...sp, closed: true }]))[0];
|
|
3757
|
+
if (!contour) return false;
|
|
3758
|
+
const segs = _chunk7EDLVBOOcjs.closeContour.call(void 0, contour, true);
|
|
3759
|
+
const b = _chunk7EDLVBOOcjs.bezierPathBounds.call(void 0, _chunk7EDLVBOOcjs.contoursToPath.call(void 0, [{ segments: segs, closed: true }]));
|
|
3760
|
+
if (!b) return false;
|
|
3761
|
+
const w = b.maxX - b.minX;
|
|
3762
|
+
const h = b.maxY - b.minY;
|
|
3763
|
+
return Math.abs(_chunk7EDLVBOOcjs.contourSignedArea.call(void 0, segs)) > 1e-9 * (w * w + h * h);
|
|
3764
|
+
}
|
|
3765
|
+
var paintKey = (paint) => typeof paint === "string" ? paint.trim().toLowerCase() : JSON.stringify(_nullishCoalesce(paint, () => ( null)));
|
|
3766
|
+
function vectorPathfinderShape(entry, op) {
|
|
3767
|
+
const { node } = entry;
|
|
3768
|
+
const subpaths = node.subpaths.filter(usable);
|
|
3769
|
+
const closed = subpaths.map((s) => ({ ...s, closed: true }));
|
|
3770
|
+
const fillRule = _nullishCoalesce(node.fillRule, () => ( "nonzero"));
|
|
3771
|
+
if (hasPaint(node.fill)) return { path: worldOf(entry, closed), fillRule, key: `fill:${paintKey(node.fill)}`, paint: "fill" };
|
|
3772
|
+
const open = subpaths.length > 0 && subpaths.every((s) => !s.closed);
|
|
3773
|
+
if (op === "divide" && open) return { path: worldOf(entry, subpaths), line: true, paint: "line" };
|
|
3774
|
+
if (hasPaint(node.stroke) && (_nullishCoalesce(node.strokeWidth, () => ( 1))) > 0) {
|
|
3775
|
+
const path = vectorStrokeOutline({ ...node, subpaths }, entry.parent);
|
|
3776
|
+
return { path, fillRule: "nonzero", key: `fill:${paintKey(node.stroke)}`, paint: "stroke" };
|
|
3777
|
+
}
|
|
3778
|
+
return { path: worldOf(entry, closed), fillRule, key: "none", paint: "outline" };
|
|
3779
|
+
}
|
|
3780
|
+
var STROKE_KEYS = [
|
|
3781
|
+
"stroke",
|
|
3782
|
+
"strokeWidth",
|
|
3783
|
+
"strokeLinecap",
|
|
3784
|
+
"strokeLinejoin",
|
|
3785
|
+
"strokeDasharray",
|
|
3786
|
+
"strokeAlign",
|
|
3787
|
+
"startArrow",
|
|
3788
|
+
"endArrow",
|
|
3789
|
+
"arrowAlign",
|
|
3790
|
+
"startArrowScale",
|
|
3791
|
+
"endArrowScale",
|
|
3792
|
+
"strokeWidthProfile"
|
|
3793
|
+
];
|
|
3794
|
+
function vectorResultStyle(node, paint, edge = false) {
|
|
3795
|
+
const { id: _id, subpaths: _s, transform: _t, ...rest } = node;
|
|
3796
|
+
const base = { ...rest, fillRule: "nonzero" };
|
|
3797
|
+
if (edge) {
|
|
3798
|
+
for (const k of STROKE_KEYS) delete base[k];
|
|
3799
|
+
const stroke = paint === "stroke" || !hasPaint(node.fill) ? node.stroke : node.fill;
|
|
3800
|
+
return { ...base, fill: null, stroke: _nullishCoalesce(stroke, () => ( "#000000")), strokeWidth: _nullishCoalesce(node.strokeWidth, () => ( 1)) };
|
|
3801
|
+
}
|
|
3802
|
+
if (paint === "stroke") {
|
|
3803
|
+
for (const k of STROKE_KEYS) delete base[k];
|
|
3804
|
+
return { ...base, fill: _nullishCoalesce(node.stroke, () => ( null)), stroke: null };
|
|
3805
|
+
}
|
|
3806
|
+
return base;
|
|
3807
|
+
}
|
|
3808
|
+
function vectorShapeBuilderMap(entries) {
|
|
3809
|
+
const lines = [];
|
|
3810
|
+
const inputs = entries.map((entry) => {
|
|
3811
|
+
const filled = hasPaint(entry.node.fill);
|
|
3812
|
+
const subpaths = entry.node.subpaths.filter(usable).map((sp) => !sp.closed && filled && subpathEnclosesArea(sp) ? { ...sp, closed: true } : sp);
|
|
3813
|
+
lines.push(!subpaths.some((s) => s.closed));
|
|
3814
|
+
return { path: worldOf(entry, subpaths), fillRule: _nullishCoalesce(entry.node.fillRule, () => ( "nonzero")) };
|
|
3815
|
+
});
|
|
3816
|
+
const map = _chunk7EDLVBOOcjs.PlanarMap.build(inputs);
|
|
3817
|
+
if (!map) return null;
|
|
3818
|
+
const pieces = map.chains().filter((c) => lines[c.source] && !c.closed).map((c) => {
|
|
3819
|
+
const path = _chunk7EDLVBOOcjs.contoursToPath.call(void 0, [{ segments: c.segments, closed: false }]);
|
|
3820
|
+
return { path, segments: c.segments, source: c.source, bounds: _chunk7EDLVBOOcjs.bezierPathBounds.call(void 0, path) };
|
|
3821
|
+
});
|
|
3822
|
+
return { entries: [...entries], map, lines, pieces };
|
|
3823
|
+
}
|
|
3824
|
+
function vectorShapeBuilderHit(m, p, lineTolerance = null) {
|
|
3825
|
+
const point = [p.x, p.y];
|
|
3826
|
+
if (lineTolerance !== null && lineTolerance > 0) {
|
|
3827
|
+
let best = -1;
|
|
3828
|
+
let bestD = lineTolerance;
|
|
3829
|
+
m.pieces.forEach((piece, i) => {
|
|
3830
|
+
const b = piece.bounds;
|
|
3831
|
+
if (p.x < b.minX - bestD || p.x > b.maxX + bestD || p.y < b.minY - bestD || p.y > b.maxY + bestD) return;
|
|
3832
|
+
const d = _chunk7EDLVBOOcjs.distanceToBezierPath.call(void 0, piece.path, point);
|
|
3833
|
+
if (d <= bestD) {
|
|
3834
|
+
best = i;
|
|
3835
|
+
bestD = d;
|
|
3836
|
+
}
|
|
3837
|
+
});
|
|
3838
|
+
if (best >= 0) return { line: best };
|
|
3839
|
+
}
|
|
3840
|
+
const face = m.map.faceAt(point);
|
|
3841
|
+
return face >= 0 ? { face } : null;
|
|
3842
|
+
}
|
|
3843
|
+
function samplePolyline(points, step) {
|
|
3844
|
+
const out = [];
|
|
3845
|
+
const s = Math.max(step, 1e-3);
|
|
3846
|
+
points.forEach((p, i) => {
|
|
3847
|
+
if (i > 0) {
|
|
3848
|
+
const a = points[i - 1];
|
|
3849
|
+
const n = Math.min(4e3, Math.ceil(Math.hypot(p.x - a.x, p.y - a.y) / s));
|
|
3850
|
+
for (let k = 1; k < n; k++) out.push({ x: a.x + (p.x - a.x) * k / n, y: a.y + (p.y - a.y) * k / n });
|
|
3851
|
+
}
|
|
3852
|
+
out.push(p);
|
|
3853
|
+
});
|
|
3854
|
+
return out;
|
|
3855
|
+
}
|
|
3856
|
+
function addBuilderHit(touched, hit) {
|
|
3857
|
+
if (!hit) return false;
|
|
3858
|
+
const [list, i] = "face" in hit ? [touched.faces, hit.face] : [touched.lines, hit.line];
|
|
3859
|
+
if (list.includes(i)) return false;
|
|
3860
|
+
list.push(i);
|
|
3861
|
+
return true;
|
|
3862
|
+
}
|
|
3863
|
+
function sides(m, piece) {
|
|
3864
|
+
const seg = piece.segments[Math.floor(piece.segments.length / 2)];
|
|
3865
|
+
const mid = _chunk7EDLVBOOcjs.segmentPoint.call(void 0, seg, 0.5);
|
|
3866
|
+
const t = _chunk7EDLVBOOcjs.segmentTangent.call(void 0, seg, 0.5);
|
|
3867
|
+
const chord = Math.hypot(seg[seg.length - 1][0] - seg[0][0], seg[seg.length - 1][1] - seg[0][1]);
|
|
3868
|
+
const off = Math.max(1e-6, Math.min(0.05, 0.05 * chord));
|
|
3869
|
+
return [m.map.faceAt([mid[0] - t[1] * off, mid[1] + t[0] * off]), m.map.faceAt([mid[0] + t[1] * off, mid[1] - t[0] * off])];
|
|
3870
|
+
}
|
|
3871
|
+
function planShapeBuilder(m, touched, erase) {
|
|
3872
|
+
const replace = /* @__PURE__ */ new Map();
|
|
3873
|
+
const picked = new Set(touched.faces);
|
|
3874
|
+
const faces = m.map.faces;
|
|
3875
|
+
const sourcesOf = faces.map((_, i) => m.map.faceSources(i));
|
|
3876
|
+
m.entries.forEach((_, i) => {
|
|
3877
|
+
if (m.lines[i]) {
|
|
3878
|
+
const own = m.pieces.flatMap((piece, k) => piece.source === i ? [k] : []);
|
|
3879
|
+
const keep = own.filter((k) => !touched.lines.includes(k) && !sides(m, m.pieces[k]).every((f) => f >= 0 && picked.has(f)));
|
|
3880
|
+
if (keep.length === own.length) return;
|
|
3881
|
+
replace.set(i, keep.length ? { kind: "pieces", paths: keep.map((k) => m.pieces[k].path) } : null);
|
|
3882
|
+
return;
|
|
3883
|
+
}
|
|
3884
|
+
if (!touched.faces.some((f) => sourcesOf[f].includes(i))) return;
|
|
3885
|
+
const kept = faces.flatMap((_2, f) => sourcesOf[f].includes(i) && !picked.has(f) ? [f] : []);
|
|
3886
|
+
const rest = kept.length ? m.map.merge(kept) : [];
|
|
3887
|
+
replace.set(i, rest.length ? { kind: "fill", path: rest } : null);
|
|
3888
|
+
});
|
|
3889
|
+
let merged = null;
|
|
3890
|
+
if (!erase && touched.faces.length) {
|
|
3891
|
+
const path = m.map.merge(touched.faces);
|
|
3892
|
+
const covered = touched.faces.map((f) => sourcesOf[f]).find((s) => s.length);
|
|
3893
|
+
const lastShape = m.lines.lastIndexOf(false);
|
|
3894
|
+
const style = covered ? covered[covered.length - 1] : lastShape >= 0 ? lastShape : m.entries.length - 1;
|
|
3895
|
+
if (path.length) merged = { path, style, currentFill: !covered };
|
|
3896
|
+
}
|
|
3897
|
+
return { replace, merged };
|
|
3898
|
+
}
|
|
3899
|
+
function vectorFillMap(doc, gap = 0) {
|
|
3900
|
+
const entries = vectorPathEntries(doc, null, { locked: true });
|
|
3901
|
+
return _chunk7EDLVBOOcjs.PlanarMap.build(
|
|
3902
|
+
entries.map((e) => ({ path: worldOf(e, e.node.subpaths.filter(usable)), fills: false })),
|
|
3903
|
+
{ gap, maxSegments: 2e4 }
|
|
3904
|
+
);
|
|
3905
|
+
}
|
|
3906
|
+
|
|
3718
3907
|
// src/vector/controller.ts
|
|
3719
3908
|
var DEFAULT_VECTOR_SNAP = { grid: 0, objects: true, guides: true, threshold: 5, angles: VECTOR_CONSTRUCTION_ANGLES };
|
|
3909
|
+
var VECTOR_FILL_GAP = 6;
|
|
3720
3910
|
var DEFAULT_VECTOR_PATH_EDIT = {
|
|
3721
3911
|
keepShapeOnDelete: true,
|
|
3722
3912
|
curvatureMoves: false,
|
|
3723
3913
|
pencilSmoothing: 0,
|
|
3724
3914
|
recognizeShapes: false,
|
|
3725
3915
|
eraserSize: 10,
|
|
3726
|
-
pencilPressure: "pen"
|
|
3916
|
+
pencilPressure: "pen",
|
|
3917
|
+
fillGap: 0
|
|
3727
3918
|
};
|
|
3728
3919
|
var VECTOR_PENCIL_STRING_PX = 100;
|
|
3729
3920
|
var VECTOR_STYLE_KEYS = [
|
|
@@ -3769,7 +3960,7 @@ function getEditablePathIds(state) {
|
|
|
3769
3960
|
}
|
|
3770
3961
|
}
|
|
3771
3962
|
}
|
|
3772
|
-
return [...ids].filter((id) => _optionalChain([findVectorNode, 'call',
|
|
3963
|
+
return [...ids].filter((id) => _optionalChain([findVectorNode, 'call', _63 => _63(state.document.nodes, id), 'optionalAccess', _64 => _64.type]) === "path");
|
|
3773
3964
|
}
|
|
3774
3965
|
function getVisibleAnchors(state) {
|
|
3775
3966
|
const out = [];
|
|
@@ -3784,7 +3975,7 @@ function getVisibleHandles(state) {
|
|
|
3784
3975
|
const seen = /* @__PURE__ */ new Set();
|
|
3785
3976
|
const push = (node, s, i, handle) => {
|
|
3786
3977
|
const sp = node.subpaths[s];
|
|
3787
|
-
const a = _optionalChain([sp, 'optionalAccess',
|
|
3978
|
+
const a = _optionalChain([sp, 'optionalAccess', _65 => _65.anchors, 'access', _66 => _66[i]]);
|
|
3788
3979
|
if (!a || !a[handle]) return;
|
|
3789
3980
|
const key = `${node.id}:${s}:${i}:${handle}`;
|
|
3790
3981
|
if (seen.has(key)) return;
|
|
@@ -3793,8 +3984,8 @@ function getVisibleHandles(state) {
|
|
|
3793
3984
|
};
|
|
3794
3985
|
if (state.tool === "pen" && state.pen) {
|
|
3795
3986
|
const node = findVectorNode(state.document.nodes, state.pen.nodeId);
|
|
3796
|
-
const sp = _optionalChain([node, 'optionalAccess',
|
|
3797
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
3987
|
+
const sp = _optionalChain([node, 'optionalAccess', _67 => _67.type]) === "path" ? node.subpaths[state.pen.subpath] : void 0;
|
|
3988
|
+
if (_optionalChain([node, 'optionalAccess', _68 => _68.type]) === "path" && sp) {
|
|
3798
3989
|
const last = sp.anchors.length - 1;
|
|
3799
3990
|
push(node, state.pen.subpath, last, "in");
|
|
3800
3991
|
push(node, state.pen.subpath, last, "out");
|
|
@@ -3832,11 +4023,11 @@ function getVectorCornerWidgets(state) {
|
|
|
3832
4023
|
const side = Math.min(c.lu, c.lv);
|
|
3833
4024
|
if (side * zoom < 3 * VECTOR_CORNER_WIDGET_INSET) continue;
|
|
3834
4025
|
const a = node.subpaths[c.subpath].anchors[c.index];
|
|
3835
|
-
const radius = _nullishCoalesce(_optionalChain([a, 'access',
|
|
4026
|
+
const radius = _nullishCoalesce(_optionalChain([a, 'access', _69 => _69.corner, 'optionalAccess', _70 => _70.radius]), () => ( 0));
|
|
3836
4027
|
const drawn = fitCornerRadius(c, radius);
|
|
3837
4028
|
const k = Math.min(Math.max(drawn / c.sin, VECTOR_CORNER_WIDGET_INSET / (zoom * Math.sqrt(1 + c.cos))), side / 2);
|
|
3838
4029
|
const p = applyMatrix(m, cornerBisectorPoint(c, k));
|
|
3839
|
-
out.push({ ref: { nodeId: id, subpath: c.subpath, index: c.index }, x: p.x, y: p.y, radius, drawnRadius: drawn, kind: _nullishCoalesce(_optionalChain([a, 'access',
|
|
4030
|
+
out.push({ ref: { nodeId: id, subpath: c.subpath, index: c.index }, x: p.x, y: p.y, radius, drawnRadius: drawn, kind: _nullishCoalesce(_optionalChain([a, 'access', _71 => _71.corner, 'optionalAccess', _72 => _72.kind]), () => ( "round")), corner: c });
|
|
3840
4031
|
}
|
|
3841
4032
|
}
|
|
3842
4033
|
return out;
|
|
@@ -3853,13 +4044,13 @@ function getVectorWidthHandles(state) {
|
|
|
3853
4044
|
const n = findVectorNode(state.document.nodes, id);
|
|
3854
4045
|
if (n) for (const p of collectPathNodes(n)) ids.add(p.id);
|
|
3855
4046
|
}
|
|
3856
|
-
if (_optionalChain([state, 'access',
|
|
3857
|
-
if (_optionalChain([state, 'access',
|
|
4047
|
+
if (_optionalChain([state, 'access', _73 => _73.hover, 'optionalAccess', _74 => _74.nodeId])) ids.add(state.hover.nodeId);
|
|
4048
|
+
if (_optionalChain([state, 'access', _75 => _75.interaction, 'optionalAccess', _76 => _76.type]) === "width") ids.add(state.interaction.ref.nodeId);
|
|
3858
4049
|
if (state.selectedWidthPoint) ids.add(state.selectedWidthPoint.nodeId);
|
|
3859
4050
|
const out = [];
|
|
3860
4051
|
for (const id of ids) {
|
|
3861
4052
|
const node = findVectorNode(state.document.nodes, id);
|
|
3862
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
4053
|
+
if (_optionalChain([node, 'optionalAccess', _77 => _77.type]) !== "path" || node.visible === false || !_optionalChain([node, 'access', _78 => _78.strokeWidthProfile, 'optionalAccess', _79 => _79.length])) continue;
|
|
3863
4054
|
const g = vectorStrokeWidthGeometry(node);
|
|
3864
4055
|
if (!g) continue;
|
|
3865
4056
|
const profile = sanitizeWidthProfile(node.strokeWidthProfile);
|
|
@@ -3893,7 +4084,7 @@ function getVectorWidthHandles(state) {
|
|
|
3893
4084
|
}
|
|
3894
4085
|
function getAnchor(doc, ref) {
|
|
3895
4086
|
const node = findVectorNode(doc.nodes, ref.nodeId);
|
|
3896
|
-
return _optionalChain([node, 'optionalAccess',
|
|
4087
|
+
return _optionalChain([node, 'optionalAccess', _80 => _80.type]) === "path" ? _optionalChain([node, 'access', _81 => _81.subpaths, 'access', _82 => _82[ref.subpath], 'optionalAccess', _83 => _83.anchors, 'access', _84 => _84[ref.index]]) : void 0;
|
|
3897
4088
|
}
|
|
3898
4089
|
function getAnchorWorld(doc, ref) {
|
|
3899
4090
|
const a = getAnchor(doc, ref);
|
|
@@ -3962,9 +4153,27 @@ var TOOL_LABELS = {
|
|
|
3962
4153
|
scissors: "Scissors",
|
|
3963
4154
|
knife: "Knife",
|
|
3964
4155
|
eraser: "Eraser",
|
|
3965
|
-
width: "Width"
|
|
4156
|
+
width: "Width",
|
|
4157
|
+
shapeBuilder: "Shape Builder",
|
|
4158
|
+
paintBucket: "Paint Bucket"
|
|
4159
|
+
};
|
|
4160
|
+
var TOOL_KEYS = {
|
|
4161
|
+
v: "select",
|
|
4162
|
+
a: "direct",
|
|
4163
|
+
p: "pen",
|
|
4164
|
+
n: "pencil",
|
|
4165
|
+
r: "rect",
|
|
4166
|
+
o: "ellipse",
|
|
4167
|
+
y: "polygon",
|
|
4168
|
+
s: "star",
|
|
4169
|
+
l: "line",
|
|
4170
|
+
c: "scissors",
|
|
4171
|
+
k: "knife",
|
|
4172
|
+
e: "eraser",
|
|
4173
|
+
w: "width",
|
|
4174
|
+
m: "shapeBuilder",
|
|
4175
|
+
b: "paintBucket"
|
|
3966
4176
|
};
|
|
3967
|
-
var TOOL_KEYS = { v: "select", a: "direct", p: "pen", n: "pencil", r: "rect", o: "ellipse", y: "polygon", s: "star", l: "line", c: "scissors", k: "knife", e: "eraser", w: "width" };
|
|
3968
4177
|
function vectorToolLabel(tool) {
|
|
3969
4178
|
return TOOL_LABELS[tool];
|
|
3970
4179
|
}
|
|
@@ -3981,7 +4190,9 @@ var VECTOR_TOOL_SHORTCUTS = {
|
|
|
3981
4190
|
scissors: "C",
|
|
3982
4191
|
knife: "K",
|
|
3983
4192
|
eraser: "E",
|
|
3984
|
-
width: "W"
|
|
4193
|
+
width: "W",
|
|
4194
|
+
shapeBuilder: "M",
|
|
4195
|
+
paintBucket: "B"
|
|
3985
4196
|
};
|
|
3986
4197
|
var VECTOR_TOOL_GLYPHS = {
|
|
3987
4198
|
select: "\u2196",
|
|
@@ -3996,7 +4207,9 @@ var VECTOR_TOOL_GLYPHS = {
|
|
|
3996
4207
|
scissors: "\u2702",
|
|
3997
4208
|
knife: "\u27CB",
|
|
3998
4209
|
eraser: "\u232B",
|
|
3999
|
-
width: "\u21F9"
|
|
4210
|
+
width: "\u21F9",
|
|
4211
|
+
shapeBuilder: "\u2295",
|
|
4212
|
+
paintBucket: "\u25CD"
|
|
4000
4213
|
};
|
|
4001
4214
|
var SHAPE_TOOLS = /* @__PURE__ */ new Set(["rect", "ellipse", "polygon", "star", "line"]);
|
|
4002
4215
|
var BOOLEAN_OPS = {
|
|
@@ -4006,6 +4219,14 @@ var BOOLEAN_OPS = {
|
|
|
4006
4219
|
exclude: "xor"
|
|
4007
4220
|
};
|
|
4008
4221
|
var BOOLEAN_LABELS = { union: "Union", subtract: "Subtract", intersect: "Intersect", exclude: "Exclude" };
|
|
4222
|
+
var VECTOR_PATHFINDER_LABELS = {
|
|
4223
|
+
divide: "Divide",
|
|
4224
|
+
trim: "Trim",
|
|
4225
|
+
merge: "Merge",
|
|
4226
|
+
crop: "Crop",
|
|
4227
|
+
outline: "Outline",
|
|
4228
|
+
minusBack: "Minus Back"
|
|
4229
|
+
};
|
|
4009
4230
|
function mapTree(nodes, fn) {
|
|
4010
4231
|
let changed = false;
|
|
4011
4232
|
const out = [];
|
|
@@ -4070,16 +4291,23 @@ var VectorEditorController = (_class3 = class {
|
|
|
4070
4291
|
__init20() {this.hoverTargets = null}
|
|
4071
4292
|
__init21() {this.spaceHeld = false}
|
|
4072
4293
|
__init22() {this.clipboard = null}
|
|
4294
|
+
/** Shape Builder map of the selection, kept while the document and the selection stay the same. */
|
|
4295
|
+
__init23() {this.builderCache = null}
|
|
4296
|
+
/** Paint bucket map of the visible outlines. */
|
|
4297
|
+
__init24() {this.fillCache = null}
|
|
4298
|
+
__init25() {this.builderPreview = null}
|
|
4299
|
+
/** What the highlight shows, to skip notifying when the pointer stays over the same face. */
|
|
4300
|
+
__init26() {this.builderHoverKey = null}
|
|
4073
4301
|
|
|
4074
4302
|
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4303
|
+
__init27() {this.listeners = /* @__PURE__ */ new Set()}
|
|
4304
|
+
__init28() {this.cleanups = []}
|
|
4305
|
+
__init29() {this.applying = false}
|
|
4078
4306
|
/** Set while a commit records a change that was already applied, so `restore` still reports it. */
|
|
4079
|
-
|
|
4080
|
-
|
|
4307
|
+
__init30() {this.committing = false}
|
|
4308
|
+
__init31() {this.revision = 0}
|
|
4081
4309
|
|
|
4082
|
-
constructor(options = {}) {;_class3.prototype.__init9.call(this);_class3.prototype.__init10.call(this);_class3.prototype.__init11.call(this);_class3.prototype.__init12.call(this);_class3.prototype.__init13.call(this);_class3.prototype.__init14.call(this);_class3.prototype.__init15.call(this);_class3.prototype.__init16.call(this);_class3.prototype.__init17.call(this);_class3.prototype.__init18.call(this);_class3.prototype.__init19.call(this);_class3.prototype.__init20.call(this);_class3.prototype.__init21.call(this);_class3.prototype.__init22.call(this);_class3.prototype.__init23.call(this);_class3.prototype.__init24.call(this);_class3.prototype.__init25.call(this);_class3.prototype.__init26.call(this);_class3.prototype.__init27.call(this);_class3.prototype.__init28.call(this);_class3.prototype.__init29.call(this);
|
|
4310
|
+
constructor(options = {}) {;_class3.prototype.__init9.call(this);_class3.prototype.__init10.call(this);_class3.prototype.__init11.call(this);_class3.prototype.__init12.call(this);_class3.prototype.__init13.call(this);_class3.prototype.__init14.call(this);_class3.prototype.__init15.call(this);_class3.prototype.__init16.call(this);_class3.prototype.__init17.call(this);_class3.prototype.__init18.call(this);_class3.prototype.__init19.call(this);_class3.prototype.__init20.call(this);_class3.prototype.__init21.call(this);_class3.prototype.__init22.call(this);_class3.prototype.__init23.call(this);_class3.prototype.__init24.call(this);_class3.prototype.__init25.call(this);_class3.prototype.__init26.call(this);_class3.prototype.__init27.call(this);_class3.prototype.__init28.call(this);_class3.prototype.__init29.call(this);_class3.prototype.__init30.call(this);_class3.prototype.__init31.call(this);_class3.prototype.__init32.call(this);_class3.prototype.__init33.call(this);
|
|
4083
4311
|
this.history = _nullishCoalesce(options.history, () => ( new (0, _chunkQKLRAA4Tcjs.HistoryManager)()));
|
|
4084
4312
|
this.doc = options.document ? cloneVectorDocument(options.document) : { width: 800, height: 600, nodes: [] };
|
|
4085
4313
|
this.tool = _nullishCoalesce(options.tool, () => ( "select"));
|
|
@@ -4108,9 +4336,9 @@ var VectorEditorController = (_class3 = class {
|
|
|
4108
4336
|
// State
|
|
4109
4337
|
// -------------------------------------------------------------------------
|
|
4110
4338
|
/** The current snapshot (stable until the next change). */
|
|
4111
|
-
|
|
4339
|
+
__init32() {this.getState = () => this.state}
|
|
4112
4340
|
/** Calls `listener` after every change. Returns an unsubscribe function. */
|
|
4113
|
-
|
|
4341
|
+
__init33() {this.subscribe = (listener) => {
|
|
4114
4342
|
this.listeners.add(listener);
|
|
4115
4343
|
return () => {
|
|
4116
4344
|
this.listeners.delete(listener);
|
|
@@ -4144,6 +4372,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4144
4372
|
interaction: this.interaction,
|
|
4145
4373
|
pen: this.pen,
|
|
4146
4374
|
pointer: this.pointer,
|
|
4375
|
+
builder: this.builderPreview,
|
|
4147
4376
|
canUndo: h.canUndo,
|
|
4148
4377
|
canRedo: h.canRedo,
|
|
4149
4378
|
undoLabel: h.undoName,
|
|
@@ -4154,7 +4383,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4154
4383
|
notify(docChanged = false) {
|
|
4155
4384
|
this.revision++;
|
|
4156
4385
|
this.state = this.computeState();
|
|
4157
|
-
if (docChanged) _optionalChain([this, 'access',
|
|
4386
|
+
if (docChanged) _optionalChain([this, 'access', _85 => _85.onChange, 'optionalCall', _86 => _86(this.doc)]);
|
|
4158
4387
|
const state = this.state;
|
|
4159
4388
|
this.listeners.forEach((listener) => {
|
|
4160
4389
|
try {
|
|
@@ -4184,24 +4413,29 @@ var VectorEditorController = (_class3 = class {
|
|
|
4184
4413
|
return applyMatrix(invertMatrix(this.worldOf(id, doc)), p);
|
|
4185
4414
|
}
|
|
4186
4415
|
cursorFor() {
|
|
4187
|
-
if (_optionalChain([this, 'access',
|
|
4188
|
-
if (_optionalChain([this, 'access',
|
|
4189
|
-
if (_optionalChain([this, 'access',
|
|
4416
|
+
if (_optionalChain([this, 'access', _87 => _87.drag, 'optionalAccess', _88 => _88.kind]) === "pan" || this.spaceHeld) return this.drag ? "grabbing" : "grab";
|
|
4417
|
+
if (_optionalChain([this, 'access', _89 => _89.drag, 'optionalAccess', _90 => _90.kind]) === "rotate") return "grabbing";
|
|
4418
|
+
if (_optionalChain([this, 'access', _91 => _91.drag, 'optionalAccess', _92 => _92.kind]) === "move") return "move";
|
|
4190
4419
|
const h = this.hover;
|
|
4191
4420
|
switch (this.tool) {
|
|
4192
4421
|
case "select":
|
|
4193
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
4194
|
-
return _optionalChain([h, 'optionalAccess',
|
|
4422
|
+
if (_optionalChain([h, 'optionalAccess', _93 => _93.transformHandle])) return vectorResizeCursor(h.transformHandle, _nullishCoalesce(_optionalChain([this, 'access', _94 => _94.frameOf, 'call', _95 => _95(this.selectedRoots()), 'optionalAccess', _96 => _96.angle]), () => ( 0)));
|
|
4423
|
+
return _optionalChain([h, 'optionalAccess', _97 => _97.nodeId]) ? "move" : "default";
|
|
4195
4424
|
case "direct":
|
|
4196
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
4197
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
4198
|
-
return _optionalChain([h, 'optionalAccess',
|
|
4425
|
+
if (_optionalChain([h, 'optionalAccess', _98 => _98.anchor]) || _optionalChain([h, 'optionalAccess', _99 => _99.handle]) || _optionalChain([h, 'optionalAccess', _100 => _100.corner])) return "pointer";
|
|
4426
|
+
if (_optionalChain([h, 'optionalAccess', _101 => _101.segment])) return "copy";
|
|
4427
|
+
return _optionalChain([h, 'optionalAccess', _102 => _102.nodeId]) ? "move" : "default";
|
|
4199
4428
|
case "pen":
|
|
4200
|
-
return _optionalChain([h, 'optionalAccess',
|
|
4429
|
+
return _optionalChain([h, 'optionalAccess', _103 => _103.anchor]) ? "pointer" : "crosshair";
|
|
4201
4430
|
case "width":
|
|
4202
|
-
if (_optionalChain([this, 'access',
|
|
4203
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
4204
|
-
return _optionalChain([h, 'optionalAccess',
|
|
4431
|
+
if (_optionalChain([this, 'access', _104 => _104.drag, 'optionalAccess', _105 => _105.kind]) === "width") return this.drag.mode === "move" ? "grabbing" : "ew-resize";
|
|
4432
|
+
if (_optionalChain([h, 'optionalAccess', _106 => _106.widthPoint])) return h.widthPoint.part === "center" ? "grab" : "ew-resize";
|
|
4433
|
+
return _optionalChain([h, 'optionalAccess', _107 => _107.strokeSpot]) ? "copy" : "default";
|
|
4434
|
+
case "shapeBuilder":
|
|
4435
|
+
if (!_optionalChain([this, 'access', _108 => _108.builderPreview, 'optionalAccess', _109 => _109.faces, 'access', _110 => _110.length]) && !_optionalChain([this, 'access', _111 => _111.builderPreview, 'optionalAccess', _112 => _112.lines, 'access', _113 => _113.length])) return "crosshair";
|
|
4436
|
+
return this.builderPreview.mode === "erase" ? "not-allowed" : "cell";
|
|
4437
|
+
case "paintBucket":
|
|
4438
|
+
return this.builderPreview ? "cell" : "crosshair";
|
|
4205
4439
|
default:
|
|
4206
4440
|
return "crosshair";
|
|
4207
4441
|
}
|
|
@@ -4221,7 +4455,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4221
4455
|
this.selection = s.selection.filter((id) => this.getNode(id));
|
|
4222
4456
|
this.anchors = s.anchors.filter((r) => getAnchor(this.doc, r));
|
|
4223
4457
|
this.editingId = s.editingId && this.getNode(s.editingId) ? s.editingId : null;
|
|
4224
|
-
this.pen = s.pen && _optionalChain([this, 'access',
|
|
4458
|
+
this.pen = s.pen && _optionalChain([this, 'access', _114 => _114.getNode, 'call', _115 => _115(s.pen.nodeId), 'optionalAccess', _116 => _116.subpaths, 'optionalAccess', _117 => _117[s.pen.subpath]]) ? s.pen : null;
|
|
4225
4459
|
} finally {
|
|
4226
4460
|
this.applying = false;
|
|
4227
4461
|
}
|
|
@@ -4328,6 +4562,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
4328
4562
|
this.hover = null;
|
|
4329
4563
|
this.guides = null;
|
|
4330
4564
|
this.widthPoint = null;
|
|
4565
|
+
this.builderPreview = null;
|
|
4566
|
+
this.builderHoverKey = null;
|
|
4331
4567
|
if (tool !== "direct") {
|
|
4332
4568
|
this.anchors = [];
|
|
4333
4569
|
this.editingId = null;
|
|
@@ -4386,7 +4622,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4386
4622
|
if (res.kind) {
|
|
4387
4623
|
this.snappedToObject = true;
|
|
4388
4624
|
this.setGuides(res);
|
|
4389
|
-
return _optionalChain([leave, 'optionalAccess',
|
|
4625
|
+
return _optionalChain([leave, 'optionalAccess', _118 => _118.constrain]) ? res.point : { x: res.x ? res.point.x : this.gridValue(res.point.x), y: res.y ? res.point.y : this.gridValue(res.point.y) };
|
|
4390
4626
|
}
|
|
4391
4627
|
}
|
|
4392
4628
|
this.setGuides(null);
|
|
@@ -4404,14 +4640,14 @@ var VectorEditorController = (_class3 = class {
|
|
|
4404
4640
|
/** Where the pointer at `p` would place a point with the pen or a shape tool (and the guides showing why). */
|
|
4405
4641
|
hoverSnap(p, input) {
|
|
4406
4642
|
if (this.tool === "pen") {
|
|
4407
|
-
const sp = this.pen ? _optionalChain([this, 'access',
|
|
4408
|
-
if (this.pen && sp && _optionalChain([this, 'access',
|
|
4643
|
+
const sp = this.pen ? _optionalChain([this, 'access', _119 => _119.getNode, 'call', _120 => _120(this.pen.nodeId), 'optionalAccess', _121 => _121.subpaths, 'access', _122 => _122[this.pen.subpath]]) : void 0;
|
|
4644
|
+
if (this.pen && sp && _optionalChain([this, 'access', _123 => _123.hover, 'optionalAccess', _124 => _124.anchor])) {
|
|
4409
4645
|
this.setGuides(null);
|
|
4410
4646
|
return p;
|
|
4411
4647
|
}
|
|
4412
4648
|
const last = this.pen && sp ? getAnchorWorld(this.doc, { nodeId: this.pen.nodeId, subpath: this.pen.subpath, index: sp.anchors.length - 1 }) : void 0;
|
|
4413
4649
|
const leave = last ? { at: { x: last.x, y: last.y }, constrain: input.shift ? "angle" : null } : null;
|
|
4414
|
-
return this.snapDrawn(p, leave, input, () => this.drawingTargets(_nullishCoalesce(_optionalChain([this, 'access',
|
|
4650
|
+
return this.snapDrawn(p, leave, input, () => this.drawingTargets(_nullishCoalesce(_optionalChain([this, 'access', _125 => _125.pen, 'optionalAccess', _126 => _126.nodeId]), () => ( null))));
|
|
4415
4651
|
}
|
|
4416
4652
|
if (SHAPE_TOOLS.has(this.tool)) return this.snapDrawn(p, null, input, () => this.drawingTargets(null));
|
|
4417
4653
|
this.setGuides(null);
|
|
@@ -4559,7 +4795,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4559
4795
|
if (d.fillRule) out.fillRule = d.fillRule;
|
|
4560
4796
|
if (d.strokeAlign && d.strokeAlign !== "center") out.strokeAlign = d.strokeAlign;
|
|
4561
4797
|
for (const key of ["startArrow", "endArrow", "arrowAlign", "startArrowScale", "endArrowScale"]) if (d[key]) out[key] = d[key];
|
|
4562
|
-
if (_optionalChain([d, 'access',
|
|
4798
|
+
if (_optionalChain([d, 'access', _127 => _127.strokeWidthProfile, 'optionalAccess', _128 => _128.length])) out.strokeWidthProfile = d.strokeWidthProfile.map((p) => ({ ...p }));
|
|
4563
4799
|
return out;
|
|
4564
4800
|
}
|
|
4565
4801
|
/** Merges `patch` into a node (paths take style and geometry; groups name / visibility / opacity). */
|
|
@@ -4607,7 +4843,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4607
4843
|
/** Removes one width point of a path's profile (the width tool's Delete). */
|
|
4608
4844
|
removeWidthPoint(ref) {
|
|
4609
4845
|
const node = this.getNode(ref.nodeId);
|
|
4610
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
4846
|
+
if (_optionalChain([node, 'optionalAccess', _129 => _129.type]) !== "path" || !_optionalChain([node, 'access', _130 => _130.strokeWidthProfile, 'optionalAccess', _131 => _131[ref.index]])) return { ok: false, message: "There is no such width point." };
|
|
4611
4847
|
const rest = removeWidthPoints(sanitizeWidthProfile(node.strokeWidthProfile), [ref.index]);
|
|
4612
4848
|
this.widthPoint = null;
|
|
4613
4849
|
this.change("Delete Width Point", () => this.replaceNode(node.id, withStyle(node, { strokeWidthProfile: rest.length ? rest : null })));
|
|
@@ -4632,7 +4868,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4632
4868
|
const refs = this.cornerTargets(options);
|
|
4633
4869
|
if (!refs.length) return { ok: false, message: "Nothing is selected." };
|
|
4634
4870
|
this.change("Corner Kind", () => {
|
|
4635
|
-
this.doc = this.updateAnchors(this.doc, refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access',
|
|
4871
|
+
this.doc = this.updateAnchors(this.doc, refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access', _132 => _132.corner, 'optionalAccess', _133 => _133.radius]), () => ( 0)), kind));
|
|
4636
4872
|
});
|
|
4637
4873
|
return { ok: true };
|
|
4638
4874
|
}
|
|
@@ -4771,10 +5007,10 @@ var VectorEditorController = (_class3 = class {
|
|
|
4771
5007
|
return this.selection.filter((id) => {
|
|
4772
5008
|
let covered = false;
|
|
4773
5009
|
const loc = locateVectorNode(this.doc.nodes, id);
|
|
4774
|
-
let parent = _nullishCoalesce(_optionalChain([loc, 'optionalAccess',
|
|
5010
|
+
let parent = _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _134 => _134.parent]), () => ( null));
|
|
4775
5011
|
while (parent) {
|
|
4776
5012
|
if (this.selection.includes(parent.id)) covered = true;
|
|
4777
|
-
parent = _nullishCoalesce(_optionalChain([locateVectorNode, 'call',
|
|
5013
|
+
parent = _nullishCoalesce(_optionalChain([locateVectorNode, 'call', _135 => _135(this.doc.nodes, parent.id), 'optionalAccess', _136 => _136.parent]), () => ( null));
|
|
4778
5014
|
}
|
|
4779
5015
|
return !covered;
|
|
4780
5016
|
});
|
|
@@ -4957,8 +5193,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
4957
5193
|
if (!ids.length) return null;
|
|
4958
5194
|
const locs = ids.map((id2) => locateVectorNode(this.doc.nodes, id2));
|
|
4959
5195
|
if (locs.some((l) => !l)) return null;
|
|
4960
|
-
const parent = _nullishCoalesce(_optionalChain([locs, 'access',
|
|
4961
|
-
if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access',
|
|
5196
|
+
const parent = _nullishCoalesce(_optionalChain([locs, 'access', _137 => _137[0], 'access', _138 => _138.parent, 'optionalAccess', _139 => _139.id]), () => ( null));
|
|
5197
|
+
if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access', _140 => _140.parent, 'optionalAccess', _141 => _141.id]), () => ( null))) !== parent)) return null;
|
|
4962
5198
|
const id = this.newId();
|
|
4963
5199
|
this.change("Group", () => {
|
|
4964
5200
|
const set = new Set(ids);
|
|
@@ -4981,7 +5217,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4981
5217
|
}
|
|
4982
5218
|
/** Replaces selected groups with their children. */
|
|
4983
5219
|
ungroup(options = {}) {
|
|
4984
|
-
const groups = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess',
|
|
5220
|
+
const groups = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess', _142 => _142.type]) === "group");
|
|
4985
5221
|
if (!groups.length) return { ok: false, message: "Select a group to ungroup." };
|
|
4986
5222
|
const set = new Set(groups.map((g) => g.id));
|
|
4987
5223
|
this.change("Ungroup", () => {
|
|
@@ -5041,7 +5277,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5041
5277
|
});
|
|
5042
5278
|
const paths = [...new Set(order)].map((id2) => this.getNode(id2));
|
|
5043
5279
|
if (paths.length < 2) return null;
|
|
5044
|
-
const result =
|
|
5280
|
+
const result = _chunk7EDLVBOOcjs.pathBoolean.call(void 0,
|
|
5045
5281
|
BOOLEAN_OPS[op],
|
|
5046
5282
|
paths.map((p) => ({
|
|
5047
5283
|
path: vectorPathWorldBezier(
|
|
@@ -5091,11 +5327,11 @@ var VectorEditorController = (_class3 = class {
|
|
|
5091
5327
|
/** A document-space path mapped into the parent space of node `id`. */
|
|
5092
5328
|
intoParentSpace(id, path) {
|
|
5093
5329
|
const parent = _nullishCoalesce(vectorParentMatrix(this.doc.nodes, id), () => ( IDENTITY_MATRIX));
|
|
5094
|
-
return isRoot(parent) ? path :
|
|
5330
|
+
return isRoot(parent) ? path : _chunk7EDLVBOOcjs.transformBezierPath.call(void 0, path, invertMatrix(parent));
|
|
5095
5331
|
}
|
|
5096
5332
|
/** Splits selected compound paths into one path per subpath. */
|
|
5097
5333
|
breakApart(options = {}) {
|
|
5098
|
-
const paths = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess',
|
|
5334
|
+
const paths = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess', _143 => _143.type]) === "path" && n.subpaths.length > 1);
|
|
5099
5335
|
if (!paths.length) return { ok: false, message: "Select a compound path to break apart." };
|
|
5100
5336
|
const created = [];
|
|
5101
5337
|
const set = new Set(paths.map((p) => p.id));
|
|
@@ -5115,6 +5351,248 @@ var VectorEditorController = (_class3 = class {
|
|
|
5115
5351
|
return { ok: true };
|
|
5116
5352
|
}
|
|
5117
5353
|
// -------------------------------------------------------------------------
|
|
5354
|
+
// Pathfinder, Shape Builder and paint bucket
|
|
5355
|
+
// -------------------------------------------------------------------------
|
|
5356
|
+
/**
|
|
5357
|
+
* Pathfinder: Divide, Trim, Merge, Crop, Outline or Minus Back over the selected (or given)
|
|
5358
|
+
* paths, in document space (rotated nodes and groups included, live corners cut). Unfilled
|
|
5359
|
+
* stroked paths take part as the area their stroke paints (Divide: open ones cut instead).
|
|
5360
|
+
* The results replace the operands at the place of the top-most one, grouped when there are
|
|
5361
|
+
* several; each keeps the style of the operand whose area it is. Returns the new path ids,
|
|
5362
|
+
* or an empty list when nothing came out.
|
|
5363
|
+
*/
|
|
5364
|
+
pathfinder(op, options = {}) {
|
|
5365
|
+
const roots = _nullishCoalesce(options.ids, () => ( this.selectedRoots()));
|
|
5366
|
+
const entries = vectorPathEntries(this.doc, roots);
|
|
5367
|
+
if (entries.length < (op === "divide" || op === "outline" ? 1 : 2)) return [];
|
|
5368
|
+
const shapes = entries.map((e) => vectorPathfinderShape(e, op));
|
|
5369
|
+
const result = _chunk7EDLVBOOcjs.pathfinder.call(void 0, op, shapes);
|
|
5370
|
+
if (result.error || !result.pieces.length) return [];
|
|
5371
|
+
const last = entries[entries.length - 1].node.id;
|
|
5372
|
+
const topRoot = _nullishCoalesce([...roots].reverse().find((r) => {
|
|
5373
|
+
const n = this.getNode(r);
|
|
5374
|
+
return !!n && !!findVectorNode([n], last);
|
|
5375
|
+
}), () => ( last));
|
|
5376
|
+
const nodes = [];
|
|
5377
|
+
for (const piece of result.pieces) {
|
|
5378
|
+
const subpaths = bezierToSubpaths(this.intoParentSpace(topRoot, piece.path)).map((sp) => piece.open ? { ...sp, closed: false } : sp);
|
|
5379
|
+
if (!subpaths.length) continue;
|
|
5380
|
+
const source = entries[piece.source].node;
|
|
5381
|
+
const style = vectorResultStyle(source, shapes[piece.source].paint, op === "outline");
|
|
5382
|
+
nodes.push({ ...style, type: "path", id: this.newId(), name: _nullishCoalesce(source.name, () => ( "Path")), subpaths });
|
|
5383
|
+
}
|
|
5384
|
+
if (!nodes.length) return [];
|
|
5385
|
+
const label = VECTOR_PATHFINDER_LABELS[op];
|
|
5386
|
+
const container = nodes.length > 1 ? { id: this.newId(), type: "group", name: label, children: nodes } : nodes[0];
|
|
5387
|
+
const drop = /* @__PURE__ */ new Set([...entries.map((e) => e.node.id), ...roots]);
|
|
5388
|
+
this.change(label, () => {
|
|
5389
|
+
this.setDoc(mapTree(this.doc.nodes, (n) => n.id === topRoot ? container : drop.has(n.id) ? null : n));
|
|
5390
|
+
this.selection = [container.id];
|
|
5391
|
+
this.anchors = [];
|
|
5392
|
+
this.editingId = null;
|
|
5393
|
+
});
|
|
5394
|
+
return nodes.map((n) => n.id);
|
|
5395
|
+
}
|
|
5396
|
+
/** The Shape Builder map of the selected (or given) paths, cached per document and selection. */
|
|
5397
|
+
shapeBuilderMap(ids) {
|
|
5398
|
+
const roots = _nullishCoalesce(ids, () => ( this.selectedRoots()));
|
|
5399
|
+
const key = roots.join("\0");
|
|
5400
|
+
if (_optionalChain([this, 'access', _144 => _144.builderCache, 'optionalAccess', _145 => _145.doc]) === this.doc && this.builderCache.key === key) return this.builderCache.map;
|
|
5401
|
+
const entries = roots.length ? vectorPathEntries(this.doc, roots) : [];
|
|
5402
|
+
const map = entries.length ? vectorShapeBuilderMap(entries) : null;
|
|
5403
|
+
this.builderCache = { doc: this.doc, key, map };
|
|
5404
|
+
return map;
|
|
5405
|
+
}
|
|
5406
|
+
/** The faces the Shape Builder offers for the selected (or given) paths (document units). */
|
|
5407
|
+
getShapeBuilderFaces(options = {}) {
|
|
5408
|
+
const m = this.shapeBuilderMap(options.ids);
|
|
5409
|
+
if (!m) return [];
|
|
5410
|
+
return m.map.faces.map((f, index) => {
|
|
5411
|
+
const p = m.map.faceInterior(index);
|
|
5412
|
+
return {
|
|
5413
|
+
index,
|
|
5414
|
+
d: _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, f.path, { precision: 3 }),
|
|
5415
|
+
area: f.area,
|
|
5416
|
+
sources: m.map.faceSources(index).map((i) => m.entries[i].node.id),
|
|
5417
|
+
point: p ? { x: p[0], y: p[1] } : null
|
|
5418
|
+
};
|
|
5419
|
+
});
|
|
5420
|
+
}
|
|
5421
|
+
/** Pick distance of the Shape Builder's erase for line pieces (document units). */
|
|
5422
|
+
builderLineTolerance() {
|
|
5423
|
+
return Math.max(this.hitRadius, 4) / this.viewport.zoom;
|
|
5424
|
+
}
|
|
5425
|
+
/**
|
|
5426
|
+
* Shape Builder gesture along `points` (document units; one point is a click) over the faces
|
|
5427
|
+
* the selected (or given) paths make. Merges the faces touched into one shape styled like the
|
|
5428
|
+
* top-most shape over the first face (the current fill for a face only outlines enclose);
|
|
5429
|
+
* with `erase` deletes them, and the pieces of unfilled open paths within `tolerance`. Every
|
|
5430
|
+
* shape covering a touched face loses that area. One undo step.
|
|
5431
|
+
*/
|
|
5432
|
+
shapeBuilder(points, options = {}) {
|
|
5433
|
+
const none = (message) => ({ ok: false, message, merged: null, faces: 0, lines: 0 });
|
|
5434
|
+
if (!points.length || !points.every((p) => Number.isFinite(p.x) && Number.isFinite(p.y))) return none("Give the points of the gesture.");
|
|
5435
|
+
const m = this.shapeBuilderMap(options.ids);
|
|
5436
|
+
if (!m) return none("Select paths that make faces.");
|
|
5437
|
+
const erase = !!options.erase;
|
|
5438
|
+
const tol = erase ? _nullishCoalesce(options.tolerance, () => ( this.builderLineTolerance())) : null;
|
|
5439
|
+
const touched = { faces: [], lines: [] };
|
|
5440
|
+
const size = m.map.faces.reduce((s, f) => Math.max(s, f.bounds.maxX - f.bounds.minX, f.bounds.maxY - f.bounds.minY), 1);
|
|
5441
|
+
for (const p of samplePolyline(points, Math.max(size / 2e3, 0.25 / this.viewport.zoom))) addBuilderHit(touched, vectorShapeBuilderHit(m, p, tol));
|
|
5442
|
+
if (!touched.faces.length && !touched.lines.length) return none("There is no face under the pointer.");
|
|
5443
|
+
return this.applyShapeBuilder(m, touched, erase);
|
|
5444
|
+
}
|
|
5445
|
+
applyShapeBuilder(m, touched, erase) {
|
|
5446
|
+
const plan = planShapeBuilder(m, touched, erase);
|
|
5447
|
+
let mergedId = null;
|
|
5448
|
+
const created = /* @__PURE__ */ new Map();
|
|
5449
|
+
this.change(erase ? "Shape Builder Delete" : "Shape Builder", () => {
|
|
5450
|
+
let nodes = this.doc.nodes;
|
|
5451
|
+
m.entries.forEach((entry, i) => {
|
|
5452
|
+
const node = entry.node;
|
|
5453
|
+
const toLocal = (path) => _chunk7EDLVBOOcjs.transformBezierPath.call(void 0, path, invertMatrix(multiplyMatrices(nodeMatrix(node), entry.parent)));
|
|
5454
|
+
const list = [];
|
|
5455
|
+
const r = plan.replace.get(i);
|
|
5456
|
+
if (r === void 0) list.push(node);
|
|
5457
|
+
else if (_optionalChain([r, 'optionalAccess', _146 => _146.kind]) === "fill") list.push({ ...node, fillRule: "nonzero", subpaths: bezierToSubpaths(toLocal(r.path)) });
|
|
5458
|
+
else if (_optionalChain([r, 'optionalAccess', _147 => _147.kind]) === "pieces") {
|
|
5459
|
+
r.paths.forEach(
|
|
5460
|
+
(path, k) => list.push({ ...node, id: k === 0 ? node.id : this.newId(), subpaths: bezierToSubpaths(toLocal(path)).map((sp) => ({ ...sp, closed: false })) })
|
|
5461
|
+
);
|
|
5462
|
+
}
|
|
5463
|
+
if (plan.merged && plan.merged.style === i) {
|
|
5464
|
+
mergedId = this.newId();
|
|
5465
|
+
const merged = {
|
|
5466
|
+
...vectorResultStyle(node, "fill"),
|
|
5467
|
+
type: "path",
|
|
5468
|
+
id: mergedId,
|
|
5469
|
+
name: "Shape",
|
|
5470
|
+
...node.transform ? { transform: node.transform } : {},
|
|
5471
|
+
subpaths: bezierToSubpaths(toLocal(plan.merged.path))
|
|
5472
|
+
};
|
|
5473
|
+
if (plan.merged.currentFill || !hasPaint(merged.fill)) merged.fill = hasPaint(this.defaults.fill) ? this.defaults.fill : "#808080";
|
|
5474
|
+
list.push(merged);
|
|
5475
|
+
}
|
|
5476
|
+
if (r === void 0 && list.length === 1) return;
|
|
5477
|
+
created.set(node.id, list.map((n) => n.id));
|
|
5478
|
+
nodes = spliceTree(nodes, node.id, list);
|
|
5479
|
+
});
|
|
5480
|
+
this.setDoc(nodes);
|
|
5481
|
+
const selection = this.selection.flatMap((id) => _nullishCoalesce(created.get(id), () => ( [id])));
|
|
5482
|
+
if (mergedId && !selection.includes(mergedId)) selection.push(mergedId);
|
|
5483
|
+
this.selection = selection.filter((id, k) => !!this.getNode(id) && selection.indexOf(id) === k);
|
|
5484
|
+
this.anchors = [];
|
|
5485
|
+
this.editingId = null;
|
|
5486
|
+
});
|
|
5487
|
+
this.builderCache = null;
|
|
5488
|
+
return { ok: true, merged: mergedId, faces: touched.faces.length, lines: touched.lines.length };
|
|
5489
|
+
}
|
|
5490
|
+
/** The paint bucket's map of the visible outlines, cached per document and gap. */
|
|
5491
|
+
fillMap(gap) {
|
|
5492
|
+
if (_optionalChain([this, 'access', _148 => _148.fillCache, 'optionalAccess', _149 => _149.doc]) === this.doc && this.fillCache.gap === gap) return this.fillCache.map;
|
|
5493
|
+
const map = vectorFillMap(this.doc, gap);
|
|
5494
|
+
this.fillCache = { doc: this.doc, gap, map };
|
|
5495
|
+
return map;
|
|
5496
|
+
}
|
|
5497
|
+
/**
|
|
5498
|
+
* Paint bucket: the region the visible outlines enclose around `point` (document units),
|
|
5499
|
+
* crossings split and islands left as holes, becomes a new path filled with the current fill
|
|
5500
|
+
* default, placed just below the selection (or on top when nothing is selected). `gap`
|
|
5501
|
+
* (default `editing.fillGap`) closes gaps up to that size between loose ends. Returns the new
|
|
5502
|
+
* path's id, or null when nothing encloses the point.
|
|
5503
|
+
*/
|
|
5504
|
+
fillRegion(point, options = {}) {
|
|
5505
|
+
if (!Number.isFinite(point.x) || !Number.isFinite(point.y)) return null;
|
|
5506
|
+
const region = _optionalChain([this, 'access', _150 => _150.fillMap, 'call', _151 => _151(_nullishCoalesce(options.gap, () => ( this.editing.fillGap))), 'optionalAccess', _152 => _152.regionAt, 'call', _153 => _153([point.x, point.y])]);
|
|
5507
|
+
if (!_optionalChain([region, 'optionalAccess', _154 => _154.length])) return null;
|
|
5508
|
+
let below = null;
|
|
5509
|
+
const roots = new Set(this.selectedRoots());
|
|
5510
|
+
walkVectorNodes(this.doc.nodes, (n) => {
|
|
5511
|
+
if (!below && roots.has(n.id)) below = n.id;
|
|
5512
|
+
});
|
|
5513
|
+
const subpaths = bezierToSubpaths(below ? this.intoParentSpace(below, region) : region);
|
|
5514
|
+
if (!subpaths.length) return null;
|
|
5515
|
+
const id = this.newId();
|
|
5516
|
+
const node = { id, type: "path", name: "Fill", ...this.styleFor(false), stroke: null, fillRule: "nonzero", subpaths };
|
|
5517
|
+
if (!hasPaint(node.fill)) node.fill = "#808080";
|
|
5518
|
+
const target = below;
|
|
5519
|
+
this.change("Fill Region", () => {
|
|
5520
|
+
if (target) {
|
|
5521
|
+
const current = this.getNode(target);
|
|
5522
|
+
this.setDoc(spliceTree(this.doc.nodes, target, [node, current]));
|
|
5523
|
+
} else this.setDoc([...this.doc.nodes, node]);
|
|
5524
|
+
if (!target) this.selection = [id];
|
|
5525
|
+
this.anchors = [];
|
|
5526
|
+
this.editingId = null;
|
|
5527
|
+
});
|
|
5528
|
+
return id;
|
|
5529
|
+
}
|
|
5530
|
+
/** Updates the Shape Builder / paint bucket highlight for the pointer at `p`; true when it changed. */
|
|
5531
|
+
hoverBuilder(p, alt) {
|
|
5532
|
+
if (this.tool === "paintBucket") {
|
|
5533
|
+
const region = _nullishCoalesce(_optionalChain([this, 'access', _155 => _155.fillMap, 'call', _156 => _156(this.editing.fillGap), 'optionalAccess', _157 => _157.regionAt, 'call', _158 => _158([p.x, p.y])]), () => ( null));
|
|
5534
|
+
const key2 = region ? _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, region, { precision: 2 }) : null;
|
|
5535
|
+
if (key2 === this.builderHoverKey) return false;
|
|
5536
|
+
this.builderHoverKey = key2;
|
|
5537
|
+
this.builderPreview = region ? { mode: "fill", faces: [region], lines: [], trail: null } : null;
|
|
5538
|
+
return true;
|
|
5539
|
+
}
|
|
5540
|
+
const m = this.selectedRoots().length ? this.shapeBuilderMap() : null;
|
|
5541
|
+
const hit = m ? vectorShapeBuilderHit(m, p, alt ? this.builderLineTolerance() : null) : null;
|
|
5542
|
+
const key = hit ? `${alt ? "erase" : "merge"}:${JSON.stringify(hit)}` : null;
|
|
5543
|
+
if (key === this.builderHoverKey) return false;
|
|
5544
|
+
this.builderHoverKey = key;
|
|
5545
|
+
this.builderPreview = hit && m ? this.builderPreviewOf(m, "face" in hit ? { faces: [hit.face], lines: [] } : { faces: [], lines: [hit.line] }, alt, null) : null;
|
|
5546
|
+
return true;
|
|
5547
|
+
}
|
|
5548
|
+
builderPreviewOf(m, touched, erase, trail) {
|
|
5549
|
+
const faces = m.map.faces;
|
|
5550
|
+
return {
|
|
5551
|
+
mode: erase ? "erase" : "merge",
|
|
5552
|
+
faces: touched.faces.map((f) => faces[f].path),
|
|
5553
|
+
lines: touched.lines.map((k) => m.pieces[k].path),
|
|
5554
|
+
trail
|
|
5555
|
+
};
|
|
5556
|
+
}
|
|
5557
|
+
downBuilder(p, input) {
|
|
5558
|
+
this.builderHoverKey = null;
|
|
5559
|
+
if (this.tool === "paintBucket") {
|
|
5560
|
+
this.fillRegion(p);
|
|
5561
|
+
this.builderPreview = null;
|
|
5562
|
+
this.hoverBuilder(p, false);
|
|
5563
|
+
this.notify();
|
|
5564
|
+
return;
|
|
5565
|
+
}
|
|
5566
|
+
const m = this.selectedRoots().length ? this.shapeBuilderMap() : null;
|
|
5567
|
+
if (!m) return;
|
|
5568
|
+
const erase = !!input.alt;
|
|
5569
|
+
const touched = { faces: [], lines: [] };
|
|
5570
|
+
addBuilderHit(touched, vectorShapeBuilderHit(m, p, erase ? this.builderLineTolerance() : null));
|
|
5571
|
+
this.drag = { kind: "builder", erase, points: [p], touched, map: m };
|
|
5572
|
+
this.interaction = { type: "builder", mode: erase ? "erase" : "merge", points: [p] };
|
|
5573
|
+
this.builderPreview = this.builderPreviewOf(m, touched, erase, [p]);
|
|
5574
|
+
this.notify();
|
|
5575
|
+
}
|
|
5576
|
+
moveBuilder(drag, p) {
|
|
5577
|
+
const last = drag.points[drag.points.length - 1];
|
|
5578
|
+
if (Math.hypot(p.x - last.x, p.y - last.y) * this.viewport.zoom < 1) return;
|
|
5579
|
+
const tol = drag.erase ? this.builderLineTolerance() : null;
|
|
5580
|
+
for (const q of samplePolyline([last, p], 2 / this.viewport.zoom)) addBuilderHit(drag.touched, vectorShapeBuilderHit(drag.map, q, tol));
|
|
5581
|
+
drag.points.push(p);
|
|
5582
|
+
this.interaction = { type: "builder", mode: drag.erase ? "erase" : "merge", points: drag.points.slice() };
|
|
5583
|
+
this.builderPreview = this.builderPreviewOf(drag.map, drag.touched, drag.erase, drag.points.slice());
|
|
5584
|
+
this.notify();
|
|
5585
|
+
}
|
|
5586
|
+
upBuilder(drag) {
|
|
5587
|
+
this.builderPreview = null;
|
|
5588
|
+
this.builderHoverKey = null;
|
|
5589
|
+
if (!drag.touched.faces.length && !drag.touched.lines.length) {
|
|
5590
|
+
this.notify();
|
|
5591
|
+
return;
|
|
5592
|
+
}
|
|
5593
|
+
this.applyShapeBuilder(drag.map, drag.touched, drag.erase);
|
|
5594
|
+
}
|
|
5595
|
+
// -------------------------------------------------------------------------
|
|
5118
5596
|
// Anchor editing
|
|
5119
5597
|
// -------------------------------------------------------------------------
|
|
5120
5598
|
updateAnchors(doc, refs, fn) {
|
|
@@ -5157,7 +5635,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5157
5635
|
/** `doc` with anchor `ref` moved to document point `to` by a Curvature-tool move. */
|
|
5158
5636
|
curvatureMoved(doc, ref, to) {
|
|
5159
5637
|
const node = findVectorNode(doc.nodes, ref.nodeId);
|
|
5160
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
5638
|
+
if (_optionalChain([node, 'optionalAccess', _159 => _159.type]) !== "path" || node.locked || !node.subpaths[ref.subpath]) return doc;
|
|
5161
5639
|
const q = this.toLocal(ref.nodeId, to, doc);
|
|
5162
5640
|
const subpaths = node.subpaths.map((sp, i) => i === ref.subpath ? curvatureMoveAnchor(sp, ref.index, q) : sp);
|
|
5163
5641
|
const nodes = mapTree(doc.nodes, (n) => n.id === ref.nodeId ? { ...node, subpaths } : n);
|
|
@@ -5166,7 +5644,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5166
5644
|
/** `doc` with segment `ref` bent through document point `p` at parameter `t`. */
|
|
5167
5645
|
bent(doc, ref, t, p) {
|
|
5168
5646
|
const node = findVectorNode(doc.nodes, ref.nodeId);
|
|
5169
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
5647
|
+
if (_optionalChain([node, 'optionalAccess', _160 => _160.type]) !== "path" || node.locked || !node.subpaths[ref.subpath]) return doc;
|
|
5170
5648
|
const q = this.toLocal(ref.nodeId, p, doc);
|
|
5171
5649
|
const subpaths = node.subpaths.map((sp, i) => i === ref.subpath ? bendSegment(sp, ref.segment, t, q) : sp);
|
|
5172
5650
|
return { ...doc, nodes: mapTree(doc.nodes, (n) => n.id === ref.nodeId ? { ...node, subpaths } : n) };
|
|
@@ -5177,7 +5655,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5177
5655
|
*/
|
|
5178
5656
|
bendSegment(ref, to, t = 0.5) {
|
|
5179
5657
|
const node = this.getNode(ref.nodeId);
|
|
5180
|
-
const sp = _optionalChain([node, 'optionalAccess',
|
|
5658
|
+
const sp = _optionalChain([node, 'optionalAccess', _161 => _161.type]) === "path" ? node.subpaths[ref.subpath] : void 0;
|
|
5181
5659
|
if (!sp || ref.segment < 0 || ref.segment >= (sp.closed ? sp.anchors.length : sp.anchors.length - 1) || sp.anchors.length < 2) return { ok: false, message: "There is no such segment." };
|
|
5182
5660
|
if (node.locked) return { ok: false, message: "The path is locked." };
|
|
5183
5661
|
this.change("Bend Segment", () => {
|
|
@@ -5212,7 +5690,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5212
5690
|
/** Adds an anchor on the nearest segment of `nodeId` to document point `point` (shape unchanged). */
|
|
5213
5691
|
insertAnchorAt(nodeId, point) {
|
|
5214
5692
|
const node = this.getNode(nodeId);
|
|
5215
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
5693
|
+
if (_optionalChain([node, 'optionalAccess', _162 => _162.type]) !== "path") return null;
|
|
5216
5694
|
const hit = nearestSegment(node, this.toLocal(nodeId, point));
|
|
5217
5695
|
if (!hit) return null;
|
|
5218
5696
|
const { subpath, index } = insertAnchor(node.subpaths[hit.subpath], hit.segment, hit.t);
|
|
@@ -5256,7 +5734,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5256
5734
|
setClosed(closed, nodeId) {
|
|
5257
5735
|
const targets = nodeId ? (() => {
|
|
5258
5736
|
const n = this.getNode(nodeId);
|
|
5259
|
-
return _optionalChain([n, 'optionalAccess',
|
|
5737
|
+
return _optionalChain([n, 'optionalAccess', _163 => _163.type]) === "path" ? n.subpaths.map((_, s) => ({ nodeId, subpath: s })) : [];
|
|
5260
5738
|
})() : this.anchors.map((r) => ({ nodeId: r.nodeId, subpath: r.subpath }));
|
|
5261
5739
|
if (!targets.length) return { ok: false, message: "Select a path or points." };
|
|
5262
5740
|
this.change(closed ? "Close Path" : "Open Path", () => {
|
|
@@ -5277,7 +5755,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5277
5755
|
this.setDoc(
|
|
5278
5756
|
mapTree(
|
|
5279
5757
|
this.doc.nodes,
|
|
5280
|
-
(n) => n.type === "path" && set.has(n.id) ? { ...n, subpaths: n.subpaths.map(reverseSubpath), ..._optionalChain([n, 'access',
|
|
5758
|
+
(n) => n.type === "path" && set.has(n.id) ? { ...n, subpaths: n.subpaths.map(reverseSubpath), ..._optionalChain([n, 'access', _164 => _164.strokeWidthProfile, 'optionalAccess', _165 => _165.length]) ? { strokeWidthProfile: reverseWidthProfile(n.strokeWidthProfile) } : {} } : n
|
|
5281
5759
|
)
|
|
5282
5760
|
);
|
|
5283
5761
|
this.anchors = [];
|
|
@@ -5415,7 +5893,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5415
5893
|
*/
|
|
5416
5894
|
cutPathAt(nodeId, point) {
|
|
5417
5895
|
const node = this.getNode(nodeId);
|
|
5418
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
5896
|
+
if (_optionalChain([node, 'optionalAccess', _166 => _166.type]) !== "path" || node.locked) return null;
|
|
5419
5897
|
const local = this.toLocal(nodeId, point);
|
|
5420
5898
|
const hit = nearestSegment(node, local);
|
|
5421
5899
|
if (!hit) return null;
|
|
@@ -5465,7 +5943,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5465
5943
|
if (n.visible === false || n.locked || parent && blocked.has(parent.id)) blocked.add(n.id);
|
|
5466
5944
|
});
|
|
5467
5945
|
const visible = (p) => !blocked.has(p.id);
|
|
5468
|
-
if (_optionalChain([ids, 'optionalAccess',
|
|
5946
|
+
if (_optionalChain([ids, 'optionalAccess', _167 => _167.length]) || this.selection.length) return this.pathTargets(_nullishCoalesce(ids, () => ( this.selection))).filter(visible);
|
|
5469
5947
|
const box = polylineBounds(points.map(toPoint2), pad);
|
|
5470
5948
|
if (!box) return [];
|
|
5471
5949
|
const out = [];
|
|
@@ -5521,10 +5999,10 @@ var VectorEditorController = (_class3 = class {
|
|
|
5521
5999
|
const region = eraserRegion(pts, width);
|
|
5522
6000
|
if (!region.length) return [];
|
|
5523
6001
|
const plan = [];
|
|
5524
|
-
const rb =
|
|
6002
|
+
const rb = _chunk7EDLVBOOcjs.bezierPathBounds.call(void 0, region);
|
|
5525
6003
|
const reach = rb ? [{ x: rb.minX, y: rb.minY }, { x: rb.maxX, y: rb.maxY }] : points;
|
|
5526
6004
|
for (const node of this.strokeTargets(reach, options.ids, 0)) {
|
|
5527
|
-
const local =
|
|
6005
|
+
const local = _chunk7EDLVBOOcjs.transformBezierPath.call(void 0, region, invertMatrix(this.worldOf(node.id)));
|
|
5528
6006
|
const live = node.subpaths.filter((sp) => sp.anchors.length > 1);
|
|
5529
6007
|
if (!live.length) continue;
|
|
5530
6008
|
if (hasPaint(node.fill) && live.every((sp) => sp.closed)) {
|
|
@@ -5551,7 +6029,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5551
6029
|
finishPath() {
|
|
5552
6030
|
if (!this.pen) return;
|
|
5553
6031
|
const node = this.getNode(this.pen.nodeId);
|
|
5554
|
-
const sp = _optionalChain([node, 'optionalAccess',
|
|
6032
|
+
const sp = _optionalChain([node, 'optionalAccess', _168 => _168.subpaths, 'access', _169 => _169[this.pen.subpath]]);
|
|
5555
6033
|
const pen = this.pen;
|
|
5556
6034
|
this.pen = null;
|
|
5557
6035
|
this.pointer = null;
|
|
@@ -5595,7 +6073,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5595
6073
|
if (trimmed.startsWith("{")) {
|
|
5596
6074
|
try {
|
|
5597
6075
|
const data = JSON.parse(trimmed);
|
|
5598
|
-
if (_optionalChain([data, 'optionalAccess',
|
|
6076
|
+
if (_optionalChain([data, 'optionalAccess', _170 => _170.type]) === VECTOR_CLIPBOARD_TYPE && Array.isArray(data.nodes)) nodes = data.nodes;
|
|
5599
6077
|
} catch (e3) {
|
|
5600
6078
|
nodes = null;
|
|
5601
6079
|
}
|
|
@@ -5607,7 +6085,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5607
6085
|
}
|
|
5608
6086
|
}
|
|
5609
6087
|
} else nodes = this.clipboard;
|
|
5610
|
-
if (!_optionalChain([nodes, 'optionalAccess',
|
|
6088
|
+
if (!_optionalChain([nodes, 'optionalAccess', _171 => _171.length])) return [];
|
|
5611
6089
|
const offset = _nullishCoalesce(options.offset, () => ( (text && !text.trim().startsWith("{") ? { x: 0, y: 0 } : { x: 10, y: 10 })));
|
|
5612
6090
|
const copies = nodes.map((n) => transformVectorNode(this.freshIds(n), translateMatrix(offset.x, offset.y)));
|
|
5613
6091
|
this.change("Paste", () => {
|
|
@@ -5651,14 +6129,14 @@ var VectorEditorController = (_class3 = class {
|
|
|
5651
6129
|
if (!frame) return null;
|
|
5652
6130
|
const { box, handles } = getVectorSelectionBoxGeometry(frame, this.viewport);
|
|
5653
6131
|
const r = this.hitRadius + 2;
|
|
5654
|
-
const
|
|
5655
|
-
for (const h of
|
|
6132
|
+
const usable2 = box.width < 2 * r || box.height < 2 * r ? handles.filter((h) => h.handle.length === 2 || h.handle === "rotate") : handles;
|
|
6133
|
+
for (const h of usable2) if (Math.hypot(h.screen.x - screen.x, h.screen.y - screen.y) <= r * Math.SQRT2) return h.handle;
|
|
5656
6134
|
return null;
|
|
5657
6135
|
}
|
|
5658
6136
|
hitHandle(screen) {
|
|
5659
6137
|
for (const ref of getVisibleHandles(this.view()).reverse()) {
|
|
5660
6138
|
const a = getAnchorWorld(this.doc, ref);
|
|
5661
|
-
const h = _optionalChain([a, 'optionalAccess',
|
|
6139
|
+
const h = _optionalChain([a, 'optionalAccess', _172 => _172[ref.handle]]);
|
|
5662
6140
|
if (!h) continue;
|
|
5663
6141
|
const s = this.documentToScreen(h);
|
|
5664
6142
|
if (Math.hypot(s.x - screen.x, s.y - screen.y) <= this.hitRadius) return ref;
|
|
@@ -5828,9 +6306,9 @@ var VectorEditorController = (_class3 = class {
|
|
|
5828
6306
|
downWidth(screen, p, input) {
|
|
5829
6307
|
const hit = this.hitWidthHandle(screen);
|
|
5830
6308
|
const spot = hit ? null : this.strokeSpotAt(p);
|
|
5831
|
-
const nodeId = _nullishCoalesce(_optionalChain([hit, 'optionalAccess',
|
|
6309
|
+
const nodeId = _nullishCoalesce(_optionalChain([hit, 'optionalAccess', _173 => _173.ref, 'access', _174 => _174.nodeId]), () => ( _optionalChain([spot, 'optionalAccess', _175 => _175.nodeId])));
|
|
5832
6310
|
const node = nodeId ? this.getNode(nodeId) : void 0;
|
|
5833
|
-
const g = _optionalChain([node, 'optionalAccess',
|
|
6311
|
+
const g = _optionalChain([node, 'optionalAccess', _176 => _176.type]) === "path" ? vectorStrokeWidthGeometry(node) : null;
|
|
5834
6312
|
if (!node || node.type !== "path" || !g) {
|
|
5835
6313
|
if (this.widthPoint) {
|
|
5836
6314
|
this.widthPoint = null;
|
|
@@ -5849,7 +6327,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5849
6327
|
if (hit) {
|
|
5850
6328
|
profile = sanitizeWidthProfile(node.strokeWidthProfile);
|
|
5851
6329
|
ref = { nodeId: node.id, index: hit.ref.index, subpath: hit.ref.subpath };
|
|
5852
|
-
t = _nullishCoalesce(_optionalChain([profile, 'access',
|
|
6330
|
+
t = _nullishCoalesce(_optionalChain([profile, 'access', _177 => _177[ref.index], 'optionalAccess', _178 => _178.t]), () => ( 0));
|
|
5853
6331
|
subpath = hit.ref.subpath;
|
|
5854
6332
|
if (hit.ref.part === "center") mode = "move";
|
|
5855
6333
|
else if (input.alt) side = hit.ref.part;
|
|
@@ -5936,6 +6414,9 @@ var VectorEditorController = (_class3 = class {
|
|
|
5936
6414
|
return this.downPencil(p, input);
|
|
5937
6415
|
case "width":
|
|
5938
6416
|
return this.downWidth(screen, p, input);
|
|
6417
|
+
case "shapeBuilder":
|
|
6418
|
+
case "paintBucket":
|
|
6419
|
+
return this.downBuilder(p, input);
|
|
5939
6420
|
case "scissors": {
|
|
5940
6421
|
const seg = this.nearestOutline(p);
|
|
5941
6422
|
if (seg) this.cutPathAt(seg.nodeId, seg.point);
|
|
@@ -6071,7 +6552,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
6071
6552
|
}
|
|
6072
6553
|
downPen(screen, p, input) {
|
|
6073
6554
|
const before = this.snapshot();
|
|
6074
|
-
const sp = this.pen ? _optionalChain([this, 'access',
|
|
6555
|
+
const sp = this.pen ? _optionalChain([this, 'access', _179 => _179.getNode, 'call', _180 => _180(this.pen.nodeId), 'optionalAccess', _181 => _181.subpaths, 'access', _182 => _182[this.pen.subpath]]) : void 0;
|
|
6075
6556
|
if (this.pen && sp) {
|
|
6076
6557
|
const pen = this.pen;
|
|
6077
6558
|
const first = { nodeId: pen.nodeId, subpath: pen.subpath, index: 0 };
|
|
@@ -6165,6 +6646,11 @@ var VectorEditorController = (_class3 = class {
|
|
|
6165
6646
|
pointerMove(screen, input = {}) {
|
|
6166
6647
|
const p = this.screenToDocument(screen);
|
|
6167
6648
|
const drag = this.drag;
|
|
6649
|
+
if (!drag && (this.tool === "shapeBuilder" || this.tool === "paintBucket")) {
|
|
6650
|
+
this.pointer = p;
|
|
6651
|
+
if (this.hoverBuilder(p, !!input.alt)) this.notify();
|
|
6652
|
+
return;
|
|
6653
|
+
}
|
|
6168
6654
|
if (!drag) {
|
|
6169
6655
|
const hover = this.computeHover(screen);
|
|
6170
6656
|
const pointerMatters = this.tool === "pen" && !!this.pen;
|
|
@@ -6296,6 +6782,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
6296
6782
|
this.notify(true);
|
|
6297
6783
|
return;
|
|
6298
6784
|
}
|
|
6785
|
+
case "builder":
|
|
6786
|
+
return this.moveBuilder(drag, p);
|
|
6299
6787
|
case "stroke": {
|
|
6300
6788
|
const last = drag.points[drag.points.length - 1];
|
|
6301
6789
|
if (Math.hypot(p.x - last.x, p.y - last.y) * this.viewport.zoom < 1.5) return;
|
|
@@ -6326,7 +6814,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
6326
6814
|
}
|
|
6327
6815
|
case "shape": {
|
|
6328
6816
|
const node = this.getNode(drag.nodeId);
|
|
6329
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
6817
|
+
if (_optionalChain([node, 'optionalAccess', _183 => _183.type]) !== "path") return;
|
|
6330
6818
|
const leave = { at: drag.start, constrain: input.shift ? drag.tool === "line" ? "angle" : "square" : null, curves: false };
|
|
6331
6819
|
let end = this.snapDrawn(p, leave, input, () => drag.targets ??= this.drawingTargets(null));
|
|
6332
6820
|
if (!this.snappedToObject && drag.tool !== "line" && !input.shift && !input.mod && this.snap.objects && drag.targets) end = this.matchShapeSize(drag.targets, drag.start, end, input.alt);
|
|
@@ -6384,14 +6872,14 @@ var VectorEditorController = (_class3 = class {
|
|
|
6384
6872
|
for (const q of drag.lazy.push([p.x, p.y])) {
|
|
6385
6873
|
if (Math.hypot(q[0] - last[0], q[1] - last[1]) * this.viewport.zoom < 1.5) continue;
|
|
6386
6874
|
drag.points.push(q);
|
|
6387
|
-
_optionalChain([drag, 'access',
|
|
6875
|
+
_optionalChain([drag, 'access', _184 => _184.pressures, 'optionalAccess', _185 => _185.push, 'call', _186 => _186(drag.pressure)]);
|
|
6388
6876
|
moved = true;
|
|
6389
6877
|
}
|
|
6390
6878
|
const string = drag.lazy.string();
|
|
6391
6879
|
const node = this.getNode(drag.nodeId);
|
|
6392
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
6880
|
+
if (_optionalChain([node, 'optionalAccess', _187 => _187.type]) !== "path") return;
|
|
6393
6881
|
if (!moved) {
|
|
6394
|
-
if (string && _optionalChain([this, 'access',
|
|
6882
|
+
if (string && _optionalChain([this, 'access', _188 => _188.interaction, 'optionalAccess', _189 => _189.type]) === "draw") {
|
|
6395
6883
|
this.interaction = { ...this.interaction, string: [{ x: string[0][0], y: string[0][1] }, { x: string[1][0], y: string[1][1] }] };
|
|
6396
6884
|
this.notify();
|
|
6397
6885
|
}
|
|
@@ -6427,8 +6915,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
6427
6915
|
}
|
|
6428
6916
|
this.setGuides(res);
|
|
6429
6917
|
return {
|
|
6430
|
-
dx: _optionalChain([res, 'optionalAccess',
|
|
6431
|
-
dy: _optionalChain([res, 'optionalAccess',
|
|
6918
|
+
dx: _optionalChain([res, 'optionalAccess', _190 => _190.x]) ? dx + res.dx : axes.x ? this.gridValue(origin.x + dx) - origin.x : dx,
|
|
6919
|
+
dy: _optionalChain([res, 'optionalAccess', _191 => _191.y]) ? dy + res.dy : axes.y ? this.gridValue(origin.y + dy) - origin.y : dy
|
|
6432
6920
|
};
|
|
6433
6921
|
}
|
|
6434
6922
|
/** The anchor a point drag snaps by, where it started: the grabbed one, else the moving one nearest the press. */
|
|
@@ -6507,7 +6995,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
6507
6995
|
if (drag.moved) return this.commit("Corner Radius", drag.before);
|
|
6508
6996
|
if (drag.alt) {
|
|
6509
6997
|
const kind = nextVectorCornerKind(drag.widget.kind);
|
|
6510
|
-
this.doc = this.updateAnchors(drag.base, drag.refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access',
|
|
6998
|
+
this.doc = this.updateAnchors(drag.base, drag.refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access', _192 => _192.corner, 'optionalAccess', _193 => _193.radius]), () => ( 0)), kind));
|
|
6511
6999
|
return this.commit("Corner Kind", drag.before);
|
|
6512
7000
|
}
|
|
6513
7001
|
const ref = drag.widget.ref;
|
|
@@ -6526,6 +7014,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
6526
7014
|
} else this.notify();
|
|
6527
7015
|
return;
|
|
6528
7016
|
}
|
|
7017
|
+
case "builder":
|
|
7018
|
+
return this.upBuilder(drag);
|
|
6529
7019
|
case "stroke": {
|
|
6530
7020
|
this.notify();
|
|
6531
7021
|
if (drag.tool === "knife") this.knife(drag.points);
|
|
@@ -6551,14 +7041,14 @@ var VectorEditorController = (_class3 = class {
|
|
|
6551
7041
|
}
|
|
6552
7042
|
case "pencil": {
|
|
6553
7043
|
const node = this.getNode(drag.nodeId);
|
|
6554
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
7044
|
+
if (_optionalChain([node, 'optionalAccess', _194 => _194.type]) !== "path" || drag.points.length < 2) {
|
|
6555
7045
|
this.doc = drag.before.doc;
|
|
6556
7046
|
this.notify(true);
|
|
6557
7047
|
return;
|
|
6558
7048
|
}
|
|
6559
7049
|
for (const q of drag.lazy.finish()) {
|
|
6560
7050
|
drag.points.push(q);
|
|
6561
|
-
_optionalChain([drag, 'access',
|
|
7051
|
+
_optionalChain([drag, 'access', _195 => _195.pressures, 'optionalAccess', _196 => _196.push, 'call', _197 => _197(drag.pressure)]);
|
|
6562
7052
|
}
|
|
6563
7053
|
const shape = this.editing.recognizeShapes ? recognizeInkShape(drag.points, { minSize: 6 / this.viewport.zoom }) : null;
|
|
6564
7054
|
if (shape) {
|
|
@@ -6566,7 +7056,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
6566
7056
|
this.selection = [drag.nodeId];
|
|
6567
7057
|
return this.commit(`Draw ${inkShapeLabel(shape)}`, drag.before);
|
|
6568
7058
|
}
|
|
6569
|
-
const fitted =
|
|
7059
|
+
const fitted = _chunk7EDLVBOOcjs.fitCubics.call(void 0, drag.points, 1.5 / this.viewport.zoom, { cornerAngleDeg: 60 });
|
|
6570
7060
|
const anchors = [];
|
|
6571
7061
|
for (const c of fitted) {
|
|
6572
7062
|
if (!anchors.length) anchors.push({ x: c.p0[0], y: c.p0[1] });
|
|
@@ -6597,7 +7087,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
6597
7087
|
this.drag = null;
|
|
6598
7088
|
this.interaction = null;
|
|
6599
7089
|
this.guides = null;
|
|
6600
|
-
if (drag.kind === "pan") {
|
|
7090
|
+
if (drag.kind === "pan" || drag.kind === "builder") {
|
|
7091
|
+
if (drag.kind === "builder") this.builderPreview = null;
|
|
6601
7092
|
this.notify();
|
|
6602
7093
|
return;
|
|
6603
7094
|
}
|
|
@@ -6629,7 +7120,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
6629
7120
|
this.convertAnchors(a.in || a.out ? "corner" : "smooth", [anchor]);
|
|
6630
7121
|
return;
|
|
6631
7122
|
}
|
|
6632
|
-
const id = _nullishCoalesce(_optionalChain([this, 'access',
|
|
7123
|
+
const id = _nullishCoalesce(_optionalChain([this, 'access', _198 => _198.hover, 'optionalAccess', _199 => _199.segment, 'optionalAccess', _200 => _200.nodeId]), () => ( this.editingId));
|
|
6633
7124
|
if (id) {
|
|
6634
7125
|
const node = this.getNode(id);
|
|
6635
7126
|
const seg = node ? nearestSegment(node, this.toLocal(id, p)) : null;
|
|
@@ -6712,7 +7203,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
6712
7203
|
this.finishPath();
|
|
6713
7204
|
return true;
|
|
6714
7205
|
}
|
|
6715
|
-
if (this.tool === "select" && this.selection.length === 1 && _optionalChain([this, 'access',
|
|
7206
|
+
if (this.tool === "select" && this.selection.length === 1 && _optionalChain([this, 'access', _201 => _201.getNode, 'call', _202 => _202(this.selection[0]), 'optionalAccess', _203 => _203.type]) === "path") {
|
|
6716
7207
|
this.tool = "direct";
|
|
6717
7208
|
this.editingId = this.selection[0];
|
|
6718
7209
|
this.notify();
|
|
@@ -6854,7 +7345,7 @@ function renderNode(node, defs, idPrefix) {
|
|
|
6854
7345
|
strokeWidth: _nullishCoalesce(node.strokeWidth, () => ( 1)),
|
|
6855
7346
|
...node.strokeLinecap ? { strokeLinecap: node.strokeLinecap } : {},
|
|
6856
7347
|
...node.strokeLinejoin ? { strokeLinejoin: node.strokeLinejoin } : {},
|
|
6857
|
-
..._optionalChain([node, 'access',
|
|
7348
|
+
..._optionalChain([node, 'access', _204 => _204.strokeDasharray, 'optionalAccess', _205 => _205.length]) ? { strokeDasharray: node.strokeDasharray.join(" ") } : {},
|
|
6858
7349
|
fillRule: _nullishCoalesce(node.fillRule, () => ( "nonzero")),
|
|
6859
7350
|
opacity: _nullishCoalesce(node.opacity, () => ( 1))
|
|
6860
7351
|
};
|
|
@@ -6878,7 +7369,7 @@ function screenOutline(state, node) {
|
|
|
6878
7369
|
const v2 = state.viewport;
|
|
6879
7370
|
const view = [v2.zoom, 0, 0, v2.zoom, v2.x, v2.y];
|
|
6880
7371
|
const parent = _nullishCoalesce(vectorParentMatrix(state.document.nodes, node.id), () => ( IDENTITY_MATRIX));
|
|
6881
|
-
return collectWithMatrix(node, parent).map(({ path, parent: m }) =>
|
|
7372
|
+
return collectWithMatrix(node, parent).map(({ path, parent: m }) => _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, _chunk7EDLVBOOcjs.transformBezierPath.call(void 0, vectorPathWorldBezier(path, m), view), { precision: 2 })).join(" ");
|
|
6882
7373
|
}
|
|
6883
7374
|
function collectWithMatrix(node, parent) {
|
|
6884
7375
|
if (node.type === "path") return [{ path: node, parent }];
|
|
@@ -6903,9 +7394,9 @@ function getVectorOverlayRenderData(state) {
|
|
|
6903
7394
|
};
|
|
6904
7395
|
for (const id of state.selection) outline(id, true);
|
|
6905
7396
|
if (state.editingId) outline(state.editingId, true);
|
|
6906
|
-
if (_optionalChain([state, 'access',
|
|
7397
|
+
if (_optionalChain([state, 'access', _206 => _206.hover, 'optionalAccess', _207 => _207.nodeId]) && !state.interaction) outline(state.hover.nodeId, false);
|
|
6907
7398
|
let selectionBox = null;
|
|
6908
|
-
if (state.tool === "select" && state.selectionFrame && _optionalChain([state, 'access',
|
|
7399
|
+
if (state.tool === "select" && state.selectionFrame && _optionalChain([state, 'access', _208 => _208.interaction, 'optionalAccess', _209 => _209.type]) !== "marquee") {
|
|
6909
7400
|
const g = getVectorSelectionBoxGeometry(state.selectionFrame, state.viewport);
|
|
6910
7401
|
selectionBox = { ...g.box, angle: g.angle, transform: g.transform, corners: g.corners, handles: g.handles };
|
|
6911
7402
|
}
|
|
@@ -6915,9 +7406,9 @@ function getVectorOverlayRenderData(state) {
|
|
|
6915
7406
|
const a = getAnchorWorld(doc, ref);
|
|
6916
7407
|
const s = toScreen(state, a);
|
|
6917
7408
|
const closes = !!state.pen && state.pen.nodeId === ref.nodeId && state.pen.subpath === ref.subpath && ref.index === 0;
|
|
6918
|
-
return { ref, x: s.x, y: s.y, type: _nullishCoalesce(a.type, () => ( inferAnchorType(a))), selected: selected(ref), hovered: sameAnchor(_optionalChain([state, 'access',
|
|
7409
|
+
return { ref, x: s.x, y: s.y, type: _nullishCoalesce(a.type, () => ( inferAnchorType(a))), selected: selected(ref), hovered: sameAnchor(_optionalChain([state, 'access', _210 => _210.hover, 'optionalAccess', _211 => _211.anchor]), ref), closes };
|
|
6919
7410
|
});
|
|
6920
|
-
if (state.tool === "pen" && !state.pen && _optionalChain([state, 'access',
|
|
7411
|
+
if (state.tool === "pen" && !state.pen && _optionalChain([state, 'access', _212 => _212.hover, 'optionalAccess', _213 => _213.anchor])) {
|
|
6921
7412
|
const a = getAnchorWorld(doc, state.hover.anchor);
|
|
6922
7413
|
if (a) {
|
|
6923
7414
|
const s = toScreen(state, a);
|
|
@@ -6926,15 +7417,15 @@ function getVectorOverlayRenderData(state) {
|
|
|
6926
7417
|
}
|
|
6927
7418
|
const handles = getVisibleHandles(state).flatMap((ref) => {
|
|
6928
7419
|
const a = getAnchorWorld(doc, ref);
|
|
6929
|
-
const h = _optionalChain([a, 'optionalAccess',
|
|
7420
|
+
const h = _optionalChain([a, 'optionalAccess', _214 => _214[ref.handle]]);
|
|
6930
7421
|
if (!a || !h) return [];
|
|
6931
7422
|
const s = toScreen(state, h);
|
|
6932
7423
|
const sa = toScreen(state, a);
|
|
6933
|
-
const hovered = !!_optionalChain([state, 'access',
|
|
7424
|
+
const hovered = !!_optionalChain([state, 'access', _215 => _215.hover, 'optionalAccess', _216 => _216.handle]) && sameAnchor(state.hover.handle, ref) && state.hover.handle.handle === ref.handle;
|
|
6934
7425
|
return [{ ref, x: s.x, y: s.y, anchorX: sa.x, anchorY: sa.y, hovered }];
|
|
6935
7426
|
});
|
|
6936
7427
|
let marquee = null;
|
|
6937
|
-
if (_optionalChain([state, 'access',
|
|
7428
|
+
if (_optionalChain([state, 'access', _217 => _217.interaction, 'optionalAccess', _218 => _218.type]) === "marquee") {
|
|
6938
7429
|
const b = state.interaction.bounds;
|
|
6939
7430
|
const tl = toScreen(state, b);
|
|
6940
7431
|
marquee = { x: tl.x, y: tl.y, width: b.width * z, height: b.height * z };
|
|
@@ -6942,7 +7433,7 @@ function getVectorOverlayRenderData(state) {
|
|
|
6942
7433
|
let penPreview = null;
|
|
6943
7434
|
if (state.tool === "pen" && state.pen && state.pointer && !state.interaction) {
|
|
6944
7435
|
const node = findVectorNode(doc.nodes, state.pen.nodeId);
|
|
6945
|
-
const sp = _optionalChain([node, 'optionalAccess',
|
|
7436
|
+
const sp = _optionalChain([node, 'optionalAccess', _219 => _219.type]) === "path" ? node.subpaths[state.pen.subpath] : void 0;
|
|
6946
7437
|
const last = sp ? getAnchorWorld(doc, { nodeId: state.pen.nodeId, subpath: state.pen.subpath, index: sp.anchors.length - 1 }) : void 0;
|
|
6947
7438
|
if (last) {
|
|
6948
7439
|
const a = toScreen(state, last);
|
|
@@ -6955,9 +7446,9 @@ function getVectorOverlayRenderData(state) {
|
|
|
6955
7446
|
const artboard = { x: origin.x, y: origin.y, width: doc.width * z, height: doc.height * z };
|
|
6956
7447
|
let status = null;
|
|
6957
7448
|
const it = state.interaction;
|
|
6958
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
6959
|
-
else if (_optionalChain([it, 'optionalAccess',
|
|
6960
|
-
else if (_optionalChain([it, 'optionalAccess',
|
|
7449
|
+
if (_optionalChain([it, 'optionalAccess', _220 => _220.type]) === "rotate") status = `${Math.round(it.angle)}\xB0`;
|
|
7450
|
+
else if (_optionalChain([it, 'optionalAccess', _221 => _221.type]) === "move" || _optionalChain([it, 'optionalAccess', _222 => _222.type]) === "anchors") status = `\u0394 ${fmt(it.dx)}, ${fmt(it.dy)}`;
|
|
7451
|
+
else if (_optionalChain([it, 'optionalAccess', _223 => _223.type]) === "scale" || _optionalChain([it, 'optionalAccess', _224 => _224.type]) === "draw") {
|
|
6961
7452
|
const b = it.type === "draw" ? findVectorNode(doc.nodes, it.nodeId) ? vectorNodeBounds(findVectorNode(doc.nodes, it.nodeId)) : null : state.selectionFrame;
|
|
6962
7453
|
if (b) status = `W ${fmt(b.width)} \xD7 H ${fmt(b.height)}`;
|
|
6963
7454
|
}
|
|
@@ -6974,24 +7465,24 @@ function getVectorOverlayRenderData(state) {
|
|
|
6974
7465
|
}
|
|
6975
7466
|
}
|
|
6976
7467
|
let toolStroke = null;
|
|
6977
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
7468
|
+
if (_optionalChain([it, 'optionalAccess', _225 => _225.type]) === "stroke") {
|
|
6978
7469
|
const pts = it.points.map((q) => toScreen(state, q));
|
|
6979
7470
|
const d = pts.map((q, i) => `${i ? "L" : "M"}${fmt(q.x)} ${fmt(q.y)}`).join("") + (pts.length === 1 ? `L${fmt(pts[0].x)} ${fmt(pts[0].y)}` : "");
|
|
6980
7471
|
toolStroke = { tool: it.tool, d, width: fmt(it.width * z) };
|
|
6981
7472
|
}
|
|
6982
7473
|
let pencilString = null;
|
|
6983
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
7474
|
+
if (_optionalChain([it, 'optionalAccess', _226 => _226.type]) === "draw" && it.string) {
|
|
6984
7475
|
const a = toScreen(state, it.string[0]);
|
|
6985
7476
|
const b = toScreen(state, it.string[1]);
|
|
6986
7477
|
pencilString = { x1: fmt(a.x), y1: fmt(a.y), x2: fmt(b.x), y2: fmt(b.y) };
|
|
6987
7478
|
}
|
|
6988
|
-
const dragged = _optionalChain([it, 'optionalAccess',
|
|
7479
|
+
const dragged = _optionalChain([it, 'optionalAccess', _227 => _227.type]) === "corner" ? it.ref : null;
|
|
6989
7480
|
const cornerWidgets = getVectorCornerWidgets(state).map((w) => {
|
|
6990
7481
|
const s = toScreen(state, w);
|
|
6991
|
-
return { ref: w.ref, x: fmt(s.x), y: fmt(s.y), radius: w.radius, kind: w.kind, hovered: sameAnchor(_optionalChain([state, 'access',
|
|
7482
|
+
return { ref: w.ref, x: fmt(s.x), y: fmt(s.y), radius: w.radius, kind: w.kind, hovered: sameAnchor(_optionalChain([state, 'access', _228 => _228.hover, 'optionalAccess', _229 => _229.corner]), w.ref), active: !!dragged };
|
|
6992
7483
|
});
|
|
6993
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
6994
|
-
const cutPoint = state.tool === "scissors" && _optionalChain([state, 'access',
|
|
7484
|
+
if (_optionalChain([it, 'optionalAccess', _230 => _230.type]) === "corner") status = `R ${fmt(it.radius)}`;
|
|
7485
|
+
const cutPoint = state.tool === "scissors" && _optionalChain([state, 'access', _231 => _231.hover, 'optionalAccess', _232 => _232.segment]) && !it ? (({ x, y }) => ({ x: fmt(x), y: fmt(y) }))(toScreen(state, state.hover.segment.point)) : null;
|
|
6995
7486
|
const sc = (p) => {
|
|
6996
7487
|
const q = toScreen(state, p);
|
|
6997
7488
|
return { x: fmt(q.x), y: fmt(q.y) };
|
|
@@ -6999,14 +7490,26 @@ function getVectorOverlayRenderData(state) {
|
|
|
6999
7490
|
const sameWidth = (a, b) => !!a && a.nodeId === b.nodeId && a.index === b.index;
|
|
7000
7491
|
const widthPoints = getVectorWidthHandles(state).map((h) => {
|
|
7001
7492
|
const c = sc(h);
|
|
7002
|
-
const hw = _optionalChain([state, 'access',
|
|
7493
|
+
const hw = _optionalChain([state, 'access', _233 => _233.hover, 'optionalAccess', _234 => _234.widthPoint]);
|
|
7003
7494
|
const hovered = hw && sameWidth(hw, h.ref) && hw.subpath === h.ref.subpath ? hw.part : null;
|
|
7004
|
-
return { ref: h.ref, x: c.x, y: c.y, left: sc(h.left), right: sc(h.right), selected: h.selected, hovered, active: _optionalChain([it, 'optionalAccess',
|
|
7495
|
+
return { ref: h.ref, x: c.x, y: c.y, left: sc(h.left), right: sc(h.right), selected: h.selected, hovered, active: _optionalChain([it, 'optionalAccess', _235 => _235.type]) === "width" && sameWidth(it.ref, h.ref) };
|
|
7005
7496
|
});
|
|
7006
|
-
const spot = state.tool === "width" && !it ? _optionalChain([state, 'access',
|
|
7497
|
+
const spot = state.tool === "width" && !it ? _optionalChain([state, 'access', _236 => _236.hover, 'optionalAccess', _237 => _237.strokeSpot]) : null;
|
|
7007
7498
|
const widthSpot = spot ? { ...sc(spot.point), left: sc(spot.left), right: sc(spot.right) } : null;
|
|
7008
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
7009
|
-
|
|
7499
|
+
if (_optionalChain([it, 'optionalAccess', _238 => _238.type]) === "width") status = it.mode === "move" ? "Move width point" : `W ${fmt(it.width)}`;
|
|
7500
|
+
let builder = null;
|
|
7501
|
+
if (state.builder) {
|
|
7502
|
+
const v2 = state.viewport;
|
|
7503
|
+
const view = [v2.zoom, 0, 0, v2.zoom, v2.x, v2.y];
|
|
7504
|
+
const d = (path) => _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, _chunk7EDLVBOOcjs.transformBezierPath.call(void 0, path, view), { precision: 2 });
|
|
7505
|
+
const trail = state.builder.trail && state.builder.trail.length > 1 ? state.builder.trail.map((q, i) => `${i ? "L" : "M"}${sc(q).x} ${sc(q).y}`).join("") : null;
|
|
7506
|
+
builder = { mode: state.builder.mode, faces: state.builder.faces.map(d), lines: state.builder.lines.map(d), trail };
|
|
7507
|
+
if (state.builder.mode !== "fill" && _optionalChain([it, 'optionalAccess', _239 => _239.type]) === "builder") {
|
|
7508
|
+
const n = state.builder.faces.length;
|
|
7509
|
+
status = state.builder.mode === "erase" ? `Delete ${n} ${n === 1 ? "face" : "faces"}` : `Merge ${n} ${n === 1 ? "face" : "faces"}`;
|
|
7510
|
+
}
|
|
7511
|
+
}
|
|
7512
|
+
return { outlines, selectionBox, anchors, handles, marquee, penPreview, artboard, guides, status, toolStroke, pencilString, cutPoint, cornerWidgets, widthPoints, widthSpot, builder };
|
|
7010
7513
|
}
|
|
7011
7514
|
var VECTOR_OVERLAY_THEME = {
|
|
7012
7515
|
accent: "#0ea5e9",
|
|
@@ -7022,7 +7525,12 @@ var VECTOR_OVERLAY_THEME = {
|
|
|
7022
7525
|
/** Radius of a live corner widget (a ring with a dot). */
|
|
7023
7526
|
cornerWidgetRadius: 4,
|
|
7024
7527
|
/** Half the diagonal of a width point's diamond. */
|
|
7025
|
-
widthPointSize: 5
|
|
7528
|
+
widthPointSize: 5,
|
|
7529
|
+
/** Shape Builder faces to merge and paint bucket regions. */
|
|
7530
|
+
builderFill: "rgba(14, 165, 233, 0.22)",
|
|
7531
|
+
/** Shape Builder faces and line pieces an Alt gesture deletes. */
|
|
7532
|
+
builderErase: "#ef4444",
|
|
7533
|
+
builderEraseFill: "rgba(239, 68, 68, 0.22)"
|
|
7026
7534
|
};
|
|
7027
7535
|
function vectorDiamondPath(x, y, r = VECTOR_OVERLAY_THEME.widthPointSize) {
|
|
7028
7536
|
return `M${fmt(x)} ${fmt(y - r)}L${fmt(x + r)} ${fmt(y)}L${fmt(x)} ${fmt(y + r)}L${fmt(x - r)} ${fmt(y)}Z`;
|
|
@@ -7046,7 +7554,7 @@ function isVectorTextTarget(target) {
|
|
|
7046
7554
|
if (!el || typeof el !== "object") return false;
|
|
7047
7555
|
const tag = (_nullishCoalesce(el.tagName, () => ( ""))).toUpperCase();
|
|
7048
7556
|
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
7049
|
-
return !!el.isContentEditable || _optionalChain([el, 'access',
|
|
7557
|
+
return !!el.isContentEditable || _optionalChain([el, 'access', _240 => _240.getAttribute, 'optionalCall', _241 => _241("contenteditable")]) === "true";
|
|
7050
7558
|
}
|
|
7051
7559
|
function getVectorSelectionStyle(state) {
|
|
7052
7560
|
const paths = [];
|
|
@@ -7054,12 +7562,12 @@ function getVectorSelectionStyle(state) {
|
|
|
7054
7562
|
const node = findVectorNode(state.document.nodes, id);
|
|
7055
7563
|
if (node) paths.push(...collect(node));
|
|
7056
7564
|
}
|
|
7057
|
-
const anchorMode = state.tool === "direct" && !!_optionalChain([state, 'access',
|
|
7565
|
+
const anchorMode = state.tool === "direct" && !!_optionalChain([state, 'access', _242 => _242.selectedAnchors, 'optionalAccess', _243 => _243.length]);
|
|
7058
7566
|
if (anchorMode) {
|
|
7059
7567
|
for (const r of state.selectedAnchors) {
|
|
7060
7568
|
if (paths.some((p) => p.id === r.nodeId)) continue;
|
|
7061
7569
|
const node = findVectorNode(state.document.nodes, r.nodeId);
|
|
7062
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
7570
|
+
if (_optionalChain([node, 'optionalAccess', _244 => _244.type]) === "path") paths.push(node);
|
|
7063
7571
|
}
|
|
7064
7572
|
}
|
|
7065
7573
|
if (!paths.length) return null;
|
|
@@ -7070,7 +7578,7 @@ function getVectorSelectionStyle(state) {
|
|
|
7070
7578
|
for (const c of vectorCorners(p.subpaths)) {
|
|
7071
7579
|
if (anchorMode && !state.selectedAnchors.some((r) => r.nodeId === p.id && r.subpath === c.subpath && r.index === c.index)) continue;
|
|
7072
7580
|
const corner = p.subpaths[c.subpath].anchors[c.index].corner;
|
|
7073
|
-
corners2.push({ radius: _nullishCoalesce(_optionalChain([corner, 'optionalAccess',
|
|
7581
|
+
corners2.push({ radius: _nullishCoalesce(_optionalChain([corner, 'optionalAccess', _245 => _245.radius]), () => ( 0)), kind: _nullishCoalesce(_optionalChain([corner, 'optionalAccess', _246 => _246.kind]), () => ( "round")) });
|
|
7074
7582
|
}
|
|
7075
7583
|
}
|
|
7076
7584
|
const c0 = _nullishCoalesce(corners2[0], () => ( { radius: 0, kind: "round" }));
|
|
@@ -7138,6 +7646,14 @@ var VECTOR_PATH_ACTIONS = [
|
|
|
7138
7646
|
{ id: "smooth", label: "\u223F", title: "Smooth", enabled: (s, p) => s + p > 0, run: (c) => c.smoothPaths() },
|
|
7139
7647
|
{ id: "outline", label: "\u22A1", title: "Outline Stroke", enabled: (s) => s > 0, run: (c) => c.outlineStroke() }
|
|
7140
7648
|
];
|
|
7649
|
+
var VECTOR_PATHFINDER_ACTIONS = [
|
|
7650
|
+
{ id: "divide", label: "\u229E", title: "Divide", min: 1 },
|
|
7651
|
+
{ id: "trim", label: "\u29C9", title: "Trim", min: 2 },
|
|
7652
|
+
{ id: "merge", label: "\u29C8", title: "Merge", min: 2 },
|
|
7653
|
+
{ id: "crop", label: "\u2317", title: "Crop", min: 2 },
|
|
7654
|
+
{ id: "outline", label: "\u2B1A", title: "Outline", min: 1 },
|
|
7655
|
+
{ id: "minusBack", label: "\u2296", title: "Minus Back", min: 2 }
|
|
7656
|
+
];
|
|
7141
7657
|
var VECTOR_EDIT_TOGGLES = [
|
|
7142
7658
|
{ key: "keepShapeOnDelete", label: "Keep", title: "Keep shape when deleting points" },
|
|
7143
7659
|
{ key: "curvatureMoves", label: "Curv", title: "Curvature point moves (Alt flips while dragging)" },
|
|
@@ -7210,17 +7726,17 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7210
7726
|
const base = { group, ...options.scope ? { scope: options.scope } : {} };
|
|
7211
7727
|
const hasSelection = () => controller.getState().selection.length ? true : "Nothing is selected.";
|
|
7212
7728
|
const ids = (params) => {
|
|
7213
|
-
const list2 = _nullishCoalesce(_optionalChain([params, 'optionalAccess',
|
|
7729
|
+
const list2 = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _247 => _247.ids]), () => ( controller.getState().selection));
|
|
7214
7730
|
for (const id of list2) if (!controller.getNode(id)) fail(`There is no node "${id}".`);
|
|
7215
7731
|
if (!list2.length) fail("Nothing is selected; pass ids.");
|
|
7216
7732
|
return list2;
|
|
7217
7733
|
};
|
|
7218
|
-
const enabledFor = (_, params) => _optionalChain([params, 'optionalAccess',
|
|
7734
|
+
const enabledFor = (_, params) => _optionalChain([params, 'optionalAccess', _248 => _248.ids, 'optionalAccess', _249 => _249.length]) ? true : hasSelection();
|
|
7219
7735
|
const anchorsOf = (refs) => {
|
|
7220
7736
|
if (!refs) return [...controller.getState().selectedAnchors];
|
|
7221
7737
|
for (const r of refs) {
|
|
7222
7738
|
const node = controller.getNode(r.nodeId);
|
|
7223
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
7739
|
+
if (_optionalChain([node, 'optionalAccess', _250 => _250.type]) !== "path" || !_optionalChain([node, 'access', _251 => _251.subpaths, 'access', _252 => _252[r.subpath], 'optionalAccess', _253 => _253.anchors, 'access', _254 => _254[r.index]])) fail(`There is no anchor ${r.index} on subpath ${r.subpath} of "${r.nodeId}".`);
|
|
7224
7740
|
}
|
|
7225
7741
|
return refs;
|
|
7226
7742
|
};
|
|
@@ -7311,7 +7827,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7311
7827
|
run: (_ctx, params) => {
|
|
7312
7828
|
const id = controller.addPath(params.d, { ...pickStyle(params), ...params.name ? { name: params.name } : {} });
|
|
7313
7829
|
const node = controller.getNode(id);
|
|
7314
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
7830
|
+
if (_optionalChain([node, 'optionalAccess', _255 => _255.type]) === "path" && !node.subpaths.length) {
|
|
7315
7831
|
controller.undo();
|
|
7316
7832
|
fail("The path data has no points.");
|
|
7317
7833
|
}
|
|
@@ -7343,10 +7859,10 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7343
7859
|
params: { type: "object", properties: { radius: { type: "number", minimum: 0 }, kind: { type: "string", enum: VECTOR_CORNER_KINDS }, ids: IDS, anchors: ANCHORS } },
|
|
7344
7860
|
undoable: true,
|
|
7345
7861
|
run: (_ctx, params) => {
|
|
7346
|
-
const refs = _optionalChain([params, 'optionalAccess',
|
|
7347
|
-
const target = { refs, ids: _optionalChain([params, 'optionalAccess',
|
|
7348
|
-
if (_optionalChain([params, 'optionalAccess',
|
|
7349
|
-
else if (_optionalChain([params, 'optionalAccess',
|
|
7862
|
+
const refs = _optionalChain([params, 'optionalAccess', _256 => _256.anchors]) ? anchorsOf(params.anchors) : void 0;
|
|
7863
|
+
const target = { refs, ids: _optionalChain([params, 'optionalAccess', _257 => _257.ids]) ? ids(params) : void 0 };
|
|
7864
|
+
if (_optionalChain([params, 'optionalAccess', _258 => _258.radius]) !== void 0) check(controller.setCornerRadius(params.radius, { ...target, kind: params.kind }));
|
|
7865
|
+
else if (_optionalChain([params, 'optionalAccess', _259 => _259.kind])) check(controller.setCornerKind(params.kind, target));
|
|
7350
7866
|
else fail("Pass `radius` and / or `kind`.");
|
|
7351
7867
|
return { ok: true };
|
|
7352
7868
|
}
|
|
@@ -7381,12 +7897,12 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7381
7897
|
undoable: true,
|
|
7382
7898
|
run: (_ctx, params) => {
|
|
7383
7899
|
const target = { ids: ids(params) };
|
|
7384
|
-
if (_optionalChain([params, 'optionalAccess',
|
|
7385
|
-
else if (_optionalChain([params, 'optionalAccess',
|
|
7386
|
-
else if (_optionalChain([params, 'optionalAccess',
|
|
7900
|
+
if (_optionalChain([params, 'optionalAccess', _260 => _260.preset])) check(controller.setWidthProfile(params.preset, target));
|
|
7901
|
+
else if (_optionalChain([params, 'optionalAccess', _261 => _261.points]) !== void 0) check(controller.setWidthProfile(_nullishCoalesce(params.points, () => ( null)), target));
|
|
7902
|
+
else if (_optionalChain([params, 'optionalAccess', _262 => _262.taper]) || _optionalChain([params, 'optionalAccess', _263 => _263.wave])) check(controller.setWidthProfile({ taper: params.taper, wave: params.wave }, target));
|
|
7387
7903
|
else fail("Pass `preset`, `points`, `taper` or `wave`.");
|
|
7388
7904
|
const node = controller.getNode(target.ids[0]);
|
|
7389
|
-
return { ok: true, points: _optionalChain([node, 'optionalAccess',
|
|
7905
|
+
return { ok: true, points: _optionalChain([node, 'optionalAccess', _264 => _264.type]) === "path" ? _nullishCoalesce(node.strokeWidthProfile, () => ( [])) : [] };
|
|
7390
7906
|
}
|
|
7391
7907
|
},
|
|
7392
7908
|
{
|
|
@@ -7399,7 +7915,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7399
7915
|
enabled: enabledFor,
|
|
7400
7916
|
undoable: true,
|
|
7401
7917
|
run: (_ctx, params) => {
|
|
7402
|
-
const created = controller.outlineStroke({ ids: _optionalChain([params, 'optionalAccess',
|
|
7918
|
+
const created = controller.outlineStroke({ ids: _optionalChain([params, 'optionalAccess', _265 => _265.ids]) ? ids(params) : void 0 });
|
|
7403
7919
|
if (!created.length) fail("No selected path has a stroke.");
|
|
7404
7920
|
return { ids: created };
|
|
7405
7921
|
}
|
|
@@ -7461,6 +7977,62 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7461
7977
|
return { id };
|
|
7462
7978
|
}
|
|
7463
7979
|
},
|
|
7980
|
+
{
|
|
7981
|
+
...base,
|
|
7982
|
+
id: `${prefix}pathfinder`,
|
|
7983
|
+
label: "Pathfinder\u2026",
|
|
7984
|
+
keywords: ["divide", "trim", "merge", "crop", "outline", "minus back", "split", "faces"],
|
|
7985
|
+
description: "Pathfinder over the given paths (bottom to top): divide (every face its own shape, painted like the top-most shape over it; open unfilled paths cut), trim (hidden parts removed), merge (trim, then touching parts of one fill joined), crop (the top shape crops the others), outline (outlines cut into open strokes where they meet) or minusBack (the top shape minus everything below). Results replace the paths, grouped when there are several.",
|
|
7986
|
+
params: { type: "object", properties: { operation: { type: "string", enum: [...VECTOR_PATHFINDER_OPERATIONS] }, ids: IDS }, required: ["operation"] },
|
|
7987
|
+
undoable: true,
|
|
7988
|
+
run: (_ctx, params) => {
|
|
7989
|
+
if (!VECTOR_PATHFINDER_OPERATIONS.includes(params.operation)) fail(`Unknown Pathfinder operation "${params.operation}".`);
|
|
7990
|
+
const created = controller.pathfinder(params.operation, { ids: ids(params) });
|
|
7991
|
+
if (!created.length) fail("Nothing came out: select paths that overlap (two or more, except for divide and outline).");
|
|
7992
|
+
return { ids: created, selection: [...controller.getState().selection] };
|
|
7993
|
+
}
|
|
7994
|
+
},
|
|
7995
|
+
{
|
|
7996
|
+
...base,
|
|
7997
|
+
id: `${prefix}shapeBuilderFaces`,
|
|
7998
|
+
label: "List Shape Builder Faces",
|
|
7999
|
+
keywords: ["shape builder", "regions", "faces", "planar"],
|
|
8000
|
+
description: "Lists the faces the given paths divide the plane into: path data, area, a point inside and the ids of the paths filling each (empty when only outlines enclose it).",
|
|
8001
|
+
params: { type: "object", properties: { ids: IDS } },
|
|
8002
|
+
run: (_ctx, params) => ({ faces: controller.getShapeBuilderFaces({ ids: ids(params) }) })
|
|
8003
|
+
},
|
|
8004
|
+
{
|
|
8005
|
+
...base,
|
|
8006
|
+
id: `${prefix}shapeBuilder`,
|
|
8007
|
+
label: "Shape Builder",
|
|
8008
|
+
keywords: ["merge faces", "build shape", "combine regions", "delete region"],
|
|
8009
|
+
description: "Shape Builder gesture over the faces of the given paths: `points` is the pointer path in document units (one point is a click; [[x, y], \u2026]; use the points from shapeBuilderFaces). Merges the faces it touches into one shape, or with `erase: true` deletes them and the pieces of unfilled open paths within `tolerance`. Shapes covering those faces lose that area.",
|
|
8010
|
+
params: {
|
|
8011
|
+
type: "object",
|
|
8012
|
+
properties: { points: POINTS, erase: { type: "boolean" }, tolerance: { type: "number", minimum: 0 }, ids: IDS },
|
|
8013
|
+
required: ["points"]
|
|
8014
|
+
},
|
|
8015
|
+
undoable: true,
|
|
8016
|
+
run: (_ctx, params) => {
|
|
8017
|
+
const result = controller.shapeBuilder(params.points.map(([x, y]) => ({ x, y })), { ids: ids(params), erase: params.erase, tolerance: params.tolerance });
|
|
8018
|
+
check(result);
|
|
8019
|
+
return { merged: result.merged, faces: result.faces, lines: result.lines };
|
|
8020
|
+
}
|
|
8021
|
+
},
|
|
8022
|
+
{
|
|
8023
|
+
...base,
|
|
8024
|
+
id: `${prefix}fillRegion`,
|
|
8025
|
+
label: "Fill Region",
|
|
8026
|
+
keywords: ["paint bucket", "live paint", "fill area", "enclosed"],
|
|
8027
|
+
description: "Paint bucket: fills the area the visible outlines enclose around `point` (crossings split, nested shapes left as holes) with a new path in the current fill, below the selection or on top. `gap` closes gaps up to that size between loose ends.",
|
|
8028
|
+
params: { type: "object", properties: { point: { type: "array", items: { type: "number" }, minItems: 2, maxItems: 2, description: "[x, y] in document units." }, gap: { type: "number", minimum: 0 } }, required: ["point"] },
|
|
8029
|
+
undoable: true,
|
|
8030
|
+
run: (_ctx, params) => {
|
|
8031
|
+
const id = controller.fillRegion({ x: params.point[0], y: params.point[1] }, { gap: params.gap });
|
|
8032
|
+
if (!id) fail("No closed region surrounds that point.");
|
|
8033
|
+
return { id };
|
|
8034
|
+
}
|
|
8035
|
+
},
|
|
7464
8036
|
{
|
|
7465
8037
|
...base,
|
|
7466
8038
|
id: `${prefix}align`,
|
|
@@ -7514,7 +8086,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7514
8086
|
enabled: enabledFor,
|
|
7515
8087
|
undoable: true,
|
|
7516
8088
|
run: (_ctx, params) => {
|
|
7517
|
-
const id = controller.group({ ids: ids(params), name: _optionalChain([params, 'optionalAccess',
|
|
8089
|
+
const id = controller.group({ ids: ids(params), name: _optionalChain([params, 'optionalAccess', _266 => _266.name]) });
|
|
7518
8090
|
if (!id) fail("Only nodes that share a parent can be grouped.");
|
|
7519
8091
|
return { id };
|
|
7520
8092
|
}
|
|
@@ -7542,7 +8114,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7542
8114
|
params: { type: "object", properties: { anchors: ANCHORS, keepShape: { type: "boolean" } } },
|
|
7543
8115
|
undoable: true,
|
|
7544
8116
|
run: (_ctx, params) => {
|
|
7545
|
-
check(controller.deleteAnchors(anchorsOf(_optionalChain([params, 'optionalAccess',
|
|
8117
|
+
check(controller.deleteAnchors(anchorsOf(_optionalChain([params, 'optionalAccess', _267 => _267.anchors])), { keepShape: _optionalChain([params, 'optionalAccess', _268 => _268.keepShape]) }));
|
|
7546
8118
|
return { ok: true };
|
|
7547
8119
|
}
|
|
7548
8120
|
},
|
|
@@ -7597,7 +8169,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7597
8169
|
params: { type: "object", properties: { ids: IDS, tolerance: { type: "number", minimum: 0 } } },
|
|
7598
8170
|
undoable: true,
|
|
7599
8171
|
run: (_ctx, params) => {
|
|
7600
|
-
check(controller.joinPaths({ ids: _optionalChain([params, 'optionalAccess',
|
|
8172
|
+
check(controller.joinPaths({ ids: _optionalChain([params, 'optionalAccess', _269 => _269.ids]) ? ids(params) : void 0, tolerance: _optionalChain([params, 'optionalAccess', _270 => _270.tolerance]) }));
|
|
7601
8173
|
return { selection: controller.getState().selection };
|
|
7602
8174
|
}
|
|
7603
8175
|
},
|
|
@@ -7611,7 +8183,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7611
8183
|
params: { type: "object", properties: { axis: { type: "string", enum: ["horizontal", "vertical", "both"] }, anchors: ANCHORS } },
|
|
7612
8184
|
undoable: true,
|
|
7613
8185
|
run: (_ctx, params) => {
|
|
7614
|
-
check(controller.averageAnchors(_nullishCoalesce(_optionalChain([params, 'optionalAccess',
|
|
8186
|
+
check(controller.averageAnchors(_nullishCoalesce(_optionalChain([params, 'optionalAccess', _271 => _271.axis]), () => ( "both")), anchorsOf(_optionalChain([params, 'optionalAccess', _272 => _272.anchors]))));
|
|
7615
8187
|
return { ok: true };
|
|
7616
8188
|
}
|
|
7617
8189
|
},
|
|
@@ -7625,7 +8197,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7625
8197
|
enabled: enabledFor,
|
|
7626
8198
|
undoable: true,
|
|
7627
8199
|
run: (_ctx, params) => {
|
|
7628
|
-
check(controller.removeRedundantPoints({ ids: _optionalChain([params, 'optionalAccess',
|
|
8200
|
+
check(controller.removeRedundantPoints({ ids: _optionalChain([params, 'optionalAccess', _273 => _273.ids]) ? ids(params) : void 0, tolerance: _optionalChain([params, 'optionalAccess', _274 => _274.tolerance]) }));
|
|
7629
8201
|
return { ok: true };
|
|
7630
8202
|
}
|
|
7631
8203
|
},
|
|
@@ -7638,7 +8210,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7638
8210
|
params: { type: "object", properties: { ids: IDS, amount: { type: "number", minimum: 0, maximum: 1 }, anchors: ANCHORS } },
|
|
7639
8211
|
undoable: true,
|
|
7640
8212
|
run: (_ctx, params) => {
|
|
7641
|
-
check(controller.smoothPaths({ ids: _optionalChain([params, 'optionalAccess',
|
|
8213
|
+
check(controller.smoothPaths({ ids: _optionalChain([params, 'optionalAccess', _275 => _275.ids]) ? ids(params) : void 0, amount: _optionalChain([params, 'optionalAccess', _276 => _276.amount]), refs: _optionalChain([params, 'optionalAccess', _277 => _277.anchors]) }));
|
|
7642
8214
|
return { ok: true };
|
|
7643
8215
|
}
|
|
7644
8216
|
},
|
|
@@ -7651,14 +8223,14 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7651
8223
|
params: { type: "object", properties: { nodeId: { type: "string" }, x: { type: "number" }, y: { type: "number" }, anchors: ANCHORS } },
|
|
7652
8224
|
undoable: true,
|
|
7653
8225
|
run: (_ctx, params) => {
|
|
7654
|
-
if (_optionalChain([params, 'optionalAccess',
|
|
8226
|
+
if (_optionalChain([params, 'optionalAccess', _278 => _278.nodeId]) !== void 0) {
|
|
7655
8227
|
if (!controller.getNode(params.nodeId)) fail(`There is no node "${params.nodeId}".`);
|
|
7656
8228
|
if (params.x === void 0 || params.y === void 0) fail("Pass x and y with nodeId.");
|
|
7657
8229
|
const created = controller.cutPathAt(params.nodeId, { x: params.x, y: params.y });
|
|
7658
8230
|
if (!created) fail("Nothing to cut there (the end of an open path, or a locked path).");
|
|
7659
8231
|
return { ids: created };
|
|
7660
8232
|
}
|
|
7661
|
-
check(controller.cutAtAnchors(anchorsOf(_optionalChain([params, 'optionalAccess',
|
|
8233
|
+
check(controller.cutAtAnchors(anchorsOf(_optionalChain([params, 'optionalAccess', _279 => _279.anchors]))));
|
|
7662
8234
|
return { ids: controller.getState().selection };
|
|
7663
8235
|
}
|
|
7664
8236
|
},
|
|
@@ -7709,7 +8281,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7709
8281
|
},
|
|
7710
8282
|
run: (_ctx, params) => {
|
|
7711
8283
|
const patch = {};
|
|
7712
|
-
for (const key of ["keepShapeOnDelete", "curvatureMoves", "pencilSmoothing", "recognizeShapes", "eraserSize", "pencilPressure"]) if (_optionalChain([params, 'optionalAccess',
|
|
8284
|
+
for (const key of ["keepShapeOnDelete", "curvatureMoves", "pencilSmoothing", "recognizeShapes", "eraserSize", "pencilPressure"]) if (_optionalChain([params, 'optionalAccess', _280 => _280[key]]) !== void 0) patch[key] = params[key];
|
|
7713
8285
|
controller.setEditing(patch);
|
|
7714
8286
|
return { editing: controller.getState().editing };
|
|
7715
8287
|
}
|
|
@@ -7734,7 +8306,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7734
8306
|
keywords: ["download", "save", "markup"],
|
|
7735
8307
|
description: "Returns the document as SVG markup.",
|
|
7736
8308
|
params: { type: "object", properties: { precision: { type: "integer", minimum: 0, maximum: 8 } } },
|
|
7737
|
-
run: (_ctx, params) => ({ svg: controller.toSvg({ precision: _optionalChain([params, 'optionalAccess',
|
|
8309
|
+
run: (_ctx, params) => ({ svg: controller.toSvg({ precision: _optionalChain([params, 'optionalAccess', _281 => _281.precision]) }) })
|
|
7738
8310
|
},
|
|
7739
8311
|
{
|
|
7740
8312
|
...base,
|
|
@@ -7932,5 +8504,19 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7932
8504
|
|
|
7933
8505
|
|
|
7934
8506
|
|
|
7935
|
-
|
|
8507
|
+
|
|
8508
|
+
|
|
8509
|
+
|
|
8510
|
+
|
|
8511
|
+
|
|
8512
|
+
|
|
8513
|
+
|
|
8514
|
+
|
|
8515
|
+
|
|
8516
|
+
|
|
8517
|
+
|
|
8518
|
+
|
|
8519
|
+
|
|
8520
|
+
|
|
8521
|
+
exports.DEFAULT_VECTOR_PATH_EDIT = DEFAULT_VECTOR_PATH_EDIT; exports.DEFAULT_VECTOR_SNAP = DEFAULT_VECTOR_SNAP; exports.IDENTITY_MATRIX = IDENTITY_MATRIX; exports.KAPPA = KAPPA2; exports.LazyMouse = LazyMouse; exports.VECTOR_ARROWHEADS = VECTOR_ARROWHEADS; exports.VECTOR_ARROWHEAD_LABELS = VECTOR_ARROWHEAD_LABELS; exports.VECTOR_CLIPBOARD_TYPE = VECTOR_CLIPBOARD_TYPE; exports.VECTOR_CONSTRUCTION_ANGLES = VECTOR_CONSTRUCTION_ANGLES; exports.VECTOR_CORNER_KINDS = VECTOR_CORNER_KINDS; exports.VECTOR_CORNER_KIND_LABELS = VECTOR_CORNER_KIND_LABELS; exports.VECTOR_CORNER_WIDGET_INSET = VECTOR_CORNER_WIDGET_INSET; exports.VECTOR_EDIT_TOGGLES = VECTOR_EDIT_TOGGLES; exports.VECTOR_FILL_GAP = VECTOR_FILL_GAP; exports.VECTOR_INK_MAX_CORNERS = VECTOR_INK_MAX_CORNERS; exports.VECTOR_OVERLAY_THEME = VECTOR_OVERLAY_THEME; exports.VECTOR_PATHFINDER_ACTIONS = VECTOR_PATHFINDER_ACTIONS; exports.VECTOR_PATHFINDER_LABELS = VECTOR_PATHFINDER_LABELS; exports.VECTOR_PATHFINDER_OPERATIONS = VECTOR_PATHFINDER_OPERATIONS; exports.VECTOR_PATH_ACTIONS = VECTOR_PATH_ACTIONS; exports.VECTOR_PENCIL_STRING_PX = VECTOR_PENCIL_STRING_PX; exports.VECTOR_PRESSURE_NOMINAL = VECTOR_PRESSURE_NOMINAL; exports.VECTOR_ROTATE_HANDLE_OFFSET = VECTOR_ROTATE_HANDLE_OFFSET; exports.VECTOR_STROKE_ALIGN_LABELS = VECTOR_STROKE_ALIGN_LABELS; exports.VECTOR_STYLE_KEYS = VECTOR_STYLE_KEYS; exports.VECTOR_TOOLS = VECTOR_TOOLS; exports.VECTOR_TOOL_GLYPHS = VECTOR_TOOL_GLYPHS; exports.VECTOR_TOOL_SHORTCUTS = VECTOR_TOOL_SHORTCUTS; exports.VECTOR_TRANSFORM_HANDLES = VECTOR_TRANSFORM_HANDLES; exports.VECTOR_WIDTH_PRESETS = VECTOR_WIDTH_PRESETS; exports.VECTOR_WIDTH_PRESET_IDS = VECTOR_WIDTH_PRESET_IDS; exports.VECTOR_WIDTH_PROFILE_MAX_POINTS = VECTOR_WIDTH_PROFILE_MAX_POINTS; exports.VECTOR_WIDTH_PROFILE_MAX_SCALE = VECTOR_WIDTH_PROFILE_MAX_SCALE; exports.VECTOR_WIDTH_SAME_T = VECTOR_WIDTH_SAME_T; exports.VectorEditorController = VectorEditorController; exports.VectorSnapTargets = VectorSnapTargets; exports.addBuilderHit = addBuilderHit; exports.applyMatrix = applyMatrix; exports.applyMatrixLinear = applyMatrixLinear; exports.applyVectorCornersAttribute = applyVectorCornersAttribute; exports.arrowheadInset = arrowheadInset; exports.arrowheadPath = arrowheadPath; exports.arrowheadWeight = arrowheadWeight; exports.bendSegment = bendSegment; exports.bezierToSubpaths = bezierToSubpaths; exports.boundsFromPoints = boundsFromPoints; exports.boundsIntersect = boundsIntersect; exports.cloneAnchor = cloneAnchor; exports.cloneSubpath = cloneSubpath; exports.cloneVectorDocument = cloneVectorDocument; exports.cloneVectorNode = cloneVectorNode; exports.collectPathNodes = collectPathNodes; exports.constrainToLeave = constrainToLeave; exports.convertAnchor = convertAnchor; exports.cornerBisectorPoint = cornerBisectorPoint; exports.cornerRadiusChange = cornerRadiusChange; exports.cornerSetback = cornerSetback; exports.createVectorCommands = createVectorCommands; exports.curvatureMoveAnchor = curvatureMoveAnchor; exports.cutSubpathAt = cutSubpathAt; exports.dashIntervals = dashIntervals; exports.decomposeRigid = decomposeRigid; exports.effectiveStrokeAlign = effectiveStrokeAlign; exports.ellipseSubpath = ellipseSubpath; exports.eraseFromFill = eraseFromFill; exports.eraseFromOutline = eraseFromOutline; exports.eraserRegion = eraserRegion; exports.expandVectorCorners = expandVectorCorners; exports.expandVectorCornersOf = expandVectorCornersOf; exports.findVectorNode = findVectorNode; exports.fitCornerRadius = fitCornerRadius; exports.generateWidthProfile = generateWidthProfile; exports.getAnchor = getAnchor; exports.getAnchorWorld = getAnchorWorld; exports.getEditablePathIds = getEditablePathIds; exports.getTransformHandlePositions = getTransformHandlePositions; exports.getVectorCornerWidgets = getVectorCornerWidgets; exports.getVectorOverlayRenderData = getVectorOverlayRenderData; exports.getVectorSceneRenderData = getVectorSceneRenderData; exports.getVectorSelectionBoxGeometry = getVectorSelectionBoxGeometry; exports.getVectorSelectionFrame = getVectorSelectionFrame; exports.getVectorSelectionStyle = getVectorSelectionStyle; exports.getVectorWidthHandles = getVectorWidthHandles; exports.getVisibleAnchors = getVisibleAnchors; exports.getVisibleHandles = getVisibleHandles; exports.hasPaint = hasPaint; exports.hasStrokeExtras = hasStrokeExtras; exports.hasVectorCorners = hasVectorCorners; exports.hitTestVectorNode = hitTestVectorNode; exports.hitTestVectorNodes = hitTestVectorNodes; exports.hitTestVectorStroke = hitTestVectorStroke; exports.inferAnchorType = inferAnchorType; exports.insertAnchor = insertAnchor; exports.insertWidthPoint = insertWidthPoint; exports.invertMatrix = invertMatrix; exports.isClosedBezierShape = isClosedBezierShape; exports.isIdentityMatrix = isIdentityMatrix; exports.isUniformWidthProfile = isUniformWidthProfile; exports.isVectorTextTarget = isVectorTextTarget; exports.joinSubpaths = joinSubpaths; exports.knifePath = knifePath; exports.lineSubpath = lineSubpath; exports.locateVectorNode = locateVectorNode; exports.matrixRotation = matrixRotation; exports.mirrorWidthProfile = mirrorWidthProfile; exports.moveAnchorHandle = moveAnchorHandle; exports.multiplyMatrices = multiplyMatrices; exports.nearestSegment = nearestSegment; exports.nearestStrokePosition = nearestStrokePosition; exports.nextVectorCornerKind = nextVectorCornerKind; exports.nodeMatrix = nodeMatrix; exports.parseSvgTransform = parseSvgTransform; exports.parseVectorSvg = parseVectorSvg; exports.planShapeBuilder = planShapeBuilder; exports.polygonSubpath = polygonSubpath; exports.polylineBounds = polylineBounds; exports.pressureWidthProfile = pressureWidthProfile; exports.recognizeInkShape = recognizeInkShape; exports.rectSubpath = rectSubpath; exports.removeAnchorKeepingShape = removeAnchorKeepingShape; exports.removeAnchors = removeAnchors; exports.removeAnchorsKeepingShape = removeAnchorsKeepingShape; exports.removeRedundantPoints = removeRedundantPoints; exports.removeWidthPoints = removeWidthPoints; exports.reverseSubpath = reverseSubpath; exports.reverseWidthProfile = reverseWidthProfile; exports.rotateMatrix = rotateMatrix; exports.roundSubpaths = roundSubpaths; exports.samplePolyline = samplePolyline; exports.sanitizeWidthProfile = sanitizeWidthProfile; exports.scaleFor = scaleFor; exports.scaleMatrix = scaleMatrix; exports.setAnchorCorner = setAnchorCorner; exports.setSubpathCorners = setSubpathCorners; exports.setWidthPoint = setWidthPoint; exports.simplifyPolyline = simplifyPolyline; exports.smoothSubpath = smoothSubpath; exports.splitIntoFaces = splitIntoFaces; exports.splitSubpathAt = splitSubpathAt; exports.starSubpath = starSubpath; exports.strokePositionPoint = strokePositionPoint; exports.strokeWidthProfileOf = strokeWidthProfileOf; exports.subpathEnclosesArea = subpathEnclosesArea; exports.subpathPointAt = subpathPointAt; exports.subpathSegment = subpathSegment; exports.subpathSegmentCount = subpathSegmentCount; exports.subpathsToBezier = subpathsToBezier; exports.taperWaveFactor = taperWaveFactor; exports.toVectorKeyInput = toVectorKeyInput; exports.toVectorModifiers = toVectorModifiers; exports.toVectorPointerInput = toVectorPointerInput; exports.transformVectorNode = transformVectorNode; exports.translateAnchor = translateAnchor; exports.translateMatrix = translateMatrix; exports.unionBounds = unionBounds; exports.variableStrokeOutline = variableStrokeOutline; exports.variableStrokeRings = variableStrokeRings; exports.vectorCornerAt = vectorCornerAt; exports.vectorCorners = vectorCorners; exports.vectorCornersAttribute = vectorCornersAttribute; exports.vectorDiamondPath = vectorDiamondPath; exports.vectorDocumentToSvg = vectorDocumentToSvg; exports.vectorFillMap = vectorFillMap; exports.vectorInkShapeName = vectorInkShapeName; exports.vectorNodeBounds = vectorNodeBounds; exports.vectorNodeRotation = vectorNodeRotation; exports.vectorNodeToBezier = vectorNodeToBezier; exports.vectorPaintToHex = vectorPaintToHex; exports.vectorPaintToSvg = vectorPaintToSvg; exports.vectorParentMatrix = vectorParentMatrix; exports.vectorPathData = vectorPathData; exports.vectorPathEntries = vectorPathEntries; exports.vectorPathWorldBezier = vectorPathWorldBezier; exports.vectorPathfinderShape = vectorPathfinderShape; exports.vectorResizeCursor = vectorResizeCursor; exports.vectorResultStyle = vectorResultStyle; exports.vectorShapeBuilderHit = vectorShapeBuilderHit; exports.vectorShapeBuilderMap = vectorShapeBuilderMap; exports.vectorStrokeLineArea = vectorStrokeLineArea; exports.vectorStrokeOutline = vectorStrokeOutline; exports.vectorStrokeOutlinePath = vectorStrokeOutlinePath; exports.vectorStrokeParts = vectorStrokeParts; exports.vectorStrokeReach = vectorStrokeReach; exports.vectorStrokeSvgParts = vectorStrokeSvgParts; exports.vectorStrokeWidthGeometry = vectorStrokeWidthGeometry; exports.vectorToolLabel = vectorToolLabel; exports.vectorWorldMatrix = vectorWorldMatrix; exports.walkVectorNodes = walkVectorNodes; exports.widthProfileAt = widthProfileAt; exports.widthProfileFromAttribute = widthProfileFromAttribute; exports.widthProfileMaxScale = widthProfileMaxScale; exports.widthProfilePreset = widthProfilePreset; exports.widthProfilePresetId = widthProfilePresetId; exports.widthProfileToAttribute = widthProfileToAttribute;
|
|
7936
8522
|
//# sourceMappingURL=index.cjs.map
|