@pixerate/editor 0.38.0 → 0.40.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 +3 -3
- package/dist/canvas/index.cjs +31 -25
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +16 -3
- package/dist/canvas/index.d.ts +16 -3
- package/dist/canvas/index.js +7 -1
- package/dist/canvas/index.js.map +1 -1
- package/dist/{chunk-ZCCU3VNI.js → chunk-3LHWTGHW.js} +158 -9
- package/dist/chunk-3LHWTGHW.js.map +1 -0
- package/dist/{chunk-7EDLVBOO.cjs → chunk-VNYRI265.cjs} +159 -10
- package/dist/chunk-VNYRI265.cjs.map +1 -0
- package/dist/{pathfinder-fLmmFOJw.d.ts → pathfinder-D98S2lV5.d.ts} +20 -2
- package/dist/{pathfinder-Bd87_lsQ.d.cts → pathfinder-DKRcXiLS.d.cts} +20 -2
- package/dist/vector/index.cjs +678 -358
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +137 -20
- package/dist/vector/index.d.ts +137 -20
- package/dist/vector/index.js +396 -76
- package/dist/vector/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-7EDLVBOO.cjs.map +0 -1
- package/dist/chunk-ZCCU3VNI.js.map +0 -1
package/dist/vector/index.cjs
CHANGED
|
@@ -36,7 +36,9 @@ var _chunkQKLRAA4Tcjs = require('../chunk-QKLRAA4T.cjs');
|
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
var _chunkVNYRI265cjs = require('../chunk-VNYRI265.cjs');
|
|
40
42
|
|
|
41
43
|
// src/vector/types.ts
|
|
42
44
|
var VECTOR_CORNER_KINDS = ["round", "inverted", "chamfer"];
|
|
@@ -80,7 +82,7 @@ var Side = class {
|
|
|
80
82
|
constructor(a, h1, h2, b) {
|
|
81
83
|
this.straight = onAnchor(a, h1) && onAnchor(b, h2);
|
|
82
84
|
this.curve = this.straight ? [pt(a), pt(b)] : [pt(a), pt(_nullishCoalesce(h1, () => ( a))), pt(_nullishCoalesce(h2, () => ( b))), pt(b)];
|
|
83
|
-
this.length = this.straight ? Math.hypot(b.x - a.x, b.y - a.y) :
|
|
85
|
+
this.length = this.straight ? Math.hypot(b.x - a.x, b.y - a.y) : _chunkVNYRI265cjs.segmentLength.call(void 0, this.curve);
|
|
84
86
|
}
|
|
85
87
|
/** Unit direction the side leaves the corner in (towards its first control point off the corner). */
|
|
86
88
|
direction() {
|
|
@@ -98,10 +100,10 @@ var Side = class {
|
|
|
98
100
|
const t2 = this.length > EPS ? Math.min(1, Math.max(0, s / this.length)) : 0;
|
|
99
101
|
return { t: t2, p: add(vec(this.curve[0]), mul(u, s)), dir: u };
|
|
100
102
|
}
|
|
101
|
-
const t =
|
|
102
|
-
const d = vec(
|
|
103
|
+
const t = _chunkVNYRI265cjs.segmentParamAtLength.call(void 0, this.curve, s, this.length);
|
|
104
|
+
const d = vec(_chunkVNYRI265cjs.segmentDerivative.call(void 0, this.curve, t));
|
|
103
105
|
const l = len(d);
|
|
104
|
-
return { t, p: vec(
|
|
106
|
+
return { t, p: vec(_chunkVNYRI265cjs.segmentPoint.call(void 0, this.curve, t)), dir: l > EPS ? mul(d, 1 / l) : u };
|
|
105
107
|
}
|
|
106
108
|
};
|
|
107
109
|
function cornerOf(sp, s, i) {
|
|
@@ -174,7 +176,7 @@ function cutCorner(c, radius, kind) {
|
|
|
174
176
|
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 };
|
|
175
177
|
}
|
|
176
178
|
var radiusOf = (a) => {
|
|
177
|
-
const r = _optionalChain([a, 'access',
|
|
179
|
+
const r = _optionalChain([a, 'access', _2 => _2.corner, 'optionalAccess', _3 => _3.radius]);
|
|
178
180
|
return typeof r === "number" && r > 0 && Number.isFinite(r) ? r : 0;
|
|
179
181
|
};
|
|
180
182
|
function hasVectorCorners(subpaths) {
|
|
@@ -188,7 +190,7 @@ function expandVectorCornersOf(sp, subpath = 0) {
|
|
|
188
190
|
const c = cornerOf(sp, subpath, i);
|
|
189
191
|
if (!c) return null;
|
|
190
192
|
const fitted = fitCornerRadius(c, r);
|
|
191
|
-
return fitted > EPS ? cutCorner(c, fitted, _nullishCoalesce(_optionalChain([a, 'access',
|
|
193
|
+
return fitted > EPS ? cutCorner(c, fitted, _nullishCoalesce(_optionalChain([a, 'access', _4 => _4.corner, 'optionalAccess', _5 => _5.kind]), () => ( "round"))) : null;
|
|
192
194
|
});
|
|
193
195
|
if (!cuts.some(Boolean)) return { subpath: { closed: sp.closed, anchors: sp.anchors.map(plain) }, sources: sp.anchors.map((_, i) => i) };
|
|
194
196
|
const trimmed = sp.anchors.map((a, j) => {
|
|
@@ -202,7 +204,7 @@ function expandVectorCornersOf(sp, subpath = 0) {
|
|
|
202
204
|
const s0 = from ? from.tv : 0;
|
|
203
205
|
const s1 = to ? 1 - to.tu : 1;
|
|
204
206
|
const seg = [pt(a), pt(_nullishCoalesce(a.out, () => ( a))), pt(_nullishCoalesce(b.in, () => ( b))), pt(b)];
|
|
205
|
-
const part =
|
|
207
|
+
const part = _chunkVNYRI265cjs.subSegment.call(void 0, seg, s0, Math.max(s0, s1));
|
|
206
208
|
return { out: vec(part[1]), in: vec(part[2]) };
|
|
207
209
|
});
|
|
208
210
|
const anchors = [];
|
|
@@ -256,7 +258,7 @@ function expandVectorCorners(subpaths) {
|
|
|
256
258
|
function setAnchorCorner(a, radius, kind) {
|
|
257
259
|
const { corner, ...rest } = a;
|
|
258
260
|
const r = Number.isFinite(radius) ? Math.max(0, radius) : 0;
|
|
259
|
-
const k = _nullishCoalesce(kind, () => ( _optionalChain([corner, 'optionalAccess',
|
|
261
|
+
const k = _nullishCoalesce(kind, () => ( _optionalChain([corner, 'optionalAccess', _6 => _6.kind])));
|
|
260
262
|
if (r <= 0 && !kind) return rest;
|
|
261
263
|
return { ...rest, corner: { radius: r, ...k && k !== "round" ? { kind: k } : {} } };
|
|
262
264
|
}
|
|
@@ -305,7 +307,7 @@ function sanitizeWidthProfile(points) {
|
|
|
305
307
|
return out.map((p, i) => [p, i]).sort((a, b) => a[0].t - b[0].t || a[1] - b[1]).map(([p]) => p);
|
|
306
308
|
}
|
|
307
309
|
function isUniformWidthProfile(points) {
|
|
308
|
-
return !_optionalChain([points, 'optionalAccess',
|
|
310
|
+
return !_optionalChain([points, 'optionalAccess', _7 => _7.length]) || points.every((p) => p.left === 1 && p.right === 1);
|
|
309
311
|
}
|
|
310
312
|
function secant(pts, i, k) {
|
|
311
313
|
const a = pts[i];
|
|
@@ -338,11 +340,11 @@ function interp(pts, t, k) {
|
|
|
338
340
|
return Math.max(0, w);
|
|
339
341
|
}
|
|
340
342
|
function widthProfileAt(points, t) {
|
|
341
|
-
if (!_optionalChain([points, 'optionalAccess',
|
|
343
|
+
if (!_optionalChain([points, 'optionalAccess', _8 => _8.length])) return { left: 1, right: 1 };
|
|
342
344
|
return { left: interp(points, t, "left"), right: interp(points, t, "right") };
|
|
343
345
|
}
|
|
344
346
|
function widthProfileMaxScale(points) {
|
|
345
|
-
if (!_optionalChain([points, 'optionalAccess',
|
|
347
|
+
if (!_optionalChain([points, 'optionalAccess', _9 => _9.length])) return 1;
|
|
346
348
|
return points.reduce((m, p) => Math.max(m, p.left, p.right), 0);
|
|
347
349
|
}
|
|
348
350
|
function widthProfilePreset(id) {
|
|
@@ -352,7 +354,7 @@ function widthProfilePreset(id) {
|
|
|
352
354
|
function widthProfilePresetId(points) {
|
|
353
355
|
if (isUniformWidthProfile(points)) return "uniform";
|
|
354
356
|
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);
|
|
355
|
-
return _nullishCoalesce(_optionalChain([VECTOR_WIDTH_PRESETS, 'access',
|
|
357
|
+
return _nullishCoalesce(_optionalChain([VECTOR_WIDTH_PRESETS, 'access', _10 => _10.find, 'call', _11 => _11((p) => p.points.length && same(points, p.points)), 'optionalAccess', _12 => _12.id]), () => ( "custom"));
|
|
356
358
|
}
|
|
357
359
|
function reverseWidthProfile(points) {
|
|
358
360
|
return points.map((p) => ({ t: 1 - p.t, left: p.right, right: p.left })).reverse();
|
|
@@ -361,12 +363,12 @@ function mirrorWidthProfile(points) {
|
|
|
361
363
|
return points.map((p) => ({ t: p.t, left: p.right, right: p.left }));
|
|
362
364
|
}
|
|
363
365
|
function editable(points) {
|
|
364
|
-
return _optionalChain([points, 'optionalAccess',
|
|
366
|
+
return _optionalChain([points, 'optionalAccess', _13 => _13.length]) ? points.map((p) => ({ ...p })) : [sym(0, 1), sym(1, 1)];
|
|
365
367
|
}
|
|
366
368
|
function insertWidthPoint(points, t, sides2 = {}, options = {}) {
|
|
367
369
|
const pts = editable(points);
|
|
368
370
|
const tt = Math.min(Math.max(Number.isFinite(t) ? t : 0, 0), 1);
|
|
369
|
-
const here = widthProfileAt(_optionalChain([points, 'optionalAccess',
|
|
371
|
+
const here = widthProfileAt(_optionalChain([points, 'optionalAccess', _14 => _14.length]) ? points : null, tt);
|
|
370
372
|
const p = {
|
|
371
373
|
t: tt,
|
|
372
374
|
left: _nullishCoalesce(clean(sides2.left, VECTOR_WIDTH_PROFILE_MAX_SCALE), () => ( here.left)),
|
|
@@ -437,7 +439,7 @@ function generateWidthProfile(options) {
|
|
|
437
439
|
const n = Math.max(8, Math.min(VECTOR_WIDTH_PROFILE_MAX_POINTS * 4, _nullishCoalesce(options.samples, () => ( Math.ceil(32 + cycles * 16)))));
|
|
438
440
|
const raw = [];
|
|
439
441
|
for (let i = 0; i <= n; i++) raw.push([i / n, taperWaveFactor(i / n, options.taper, options.wave)]);
|
|
440
|
-
const ts = [_optionalChain([options, 'access',
|
|
442
|
+
const ts = [_optionalChain([options, 'access', _15 => _15.taper, 'optionalAccess', _16 => _16.startLength]), _optionalChain([options, 'access', _17 => _17.taper, 'optionalAccess', _18 => _18.endLength]) !== void 0 ? 1 - options.taper.endLength : void 0];
|
|
441
443
|
for (const t of ts) if (typeof t === "number" && t > 0 && t < 1) raw.push([t, taperWaveFactor(t, options.taper, options.wave)]);
|
|
442
444
|
raw.sort((a, b) => a[0] - b[0]);
|
|
443
445
|
const kept = simplifySamples(raw, _nullishCoalesce(options.tolerance, () => ( 0.01)), VECTOR_WIDTH_PROFILE_MAX_POINTS);
|
|
@@ -505,7 +507,7 @@ function flatten(segments, closed, tol) {
|
|
|
505
507
|
corner.push(isCorner);
|
|
506
508
|
};
|
|
507
509
|
for (const seg of segments) {
|
|
508
|
-
const flat =
|
|
510
|
+
const flat = _chunkVNYRI265cjs.flattenChain.call(void 0, [seg], tol);
|
|
509
511
|
if (dist(seg[0], seg[seg.length - 1]) <= 1e-12 && flat.length > 1) flat.push(seg[seg.length - 1]);
|
|
510
512
|
flat.forEach((p, i) => push(p, i === 0 || i === flat.length - 1));
|
|
511
513
|
}
|
|
@@ -595,7 +597,7 @@ function variableStrokeRings(path, options) {
|
|
|
595
597
|
const last = out[out.length - 1];
|
|
596
598
|
if (!last || dist(last, p) > 1e-12) out.push(p);
|
|
597
599
|
};
|
|
598
|
-
for (const contour of
|
|
600
|
+
for (const contour of _chunkVNYRI265cjs.pathToContours.call(void 0, path)) {
|
|
599
601
|
if (!contour.segments.length) continue;
|
|
600
602
|
const poly = flatten(contour.segments, contour.closed, Math.min(tol, half) / 4);
|
|
601
603
|
if (!poly) continue;
|
|
@@ -604,7 +606,7 @@ function variableStrokeRings(path, options) {
|
|
|
604
606
|
const w = widthProfileAt(options.profile, s / len2);
|
|
605
607
|
return [w.left * half, w.right * half];
|
|
606
608
|
};
|
|
607
|
-
const intervals = _optionalChain([options, 'access',
|
|
609
|
+
const intervals = _optionalChain([options, 'access', _19 => _19.dash, 'optionalAccess', _20 => _20.some, 'call', _21 => _21((v2) => v2 > 0)]) ? dashIntervals(options.dash, _nullishCoalesce(options.dashOffset, () => ( 0)), len2) : [[0, len2]];
|
|
608
610
|
const whole = intervals.length === 1 && intervals[0][0] <= 0 && intervals[0][1] >= len2;
|
|
609
611
|
for (const [a, b] of intervals) {
|
|
610
612
|
const [pa, ia] = at(poly, a);
|
|
@@ -721,7 +723,7 @@ function variableStrokeOutline(path, options) {
|
|
|
721
723
|
const tol = options.tolerance && options.tolerance > 0 ? options.tolerance : 0.05;
|
|
722
724
|
let polygons;
|
|
723
725
|
try {
|
|
724
|
-
polygons =
|
|
726
|
+
polygons = _chunkVNYRI265cjs.polygonBoolean.call(void 0, "union", [{ rings: pieces, fillRule: "nonzero" }]);
|
|
725
727
|
} catch (e2) {
|
|
726
728
|
return [];
|
|
727
729
|
}
|
|
@@ -729,11 +731,11 @@ function variableStrokeOutline(path, options) {
|
|
|
729
731
|
for (const polygon2 of polygons) {
|
|
730
732
|
for (const ring of polygon2) {
|
|
731
733
|
if (ring.length < 3) continue;
|
|
732
|
-
const cubics =
|
|
734
|
+
const cubics = _chunkVNYRI265cjs.fitCubics.call(void 0, ring, tol, { closed: true, cornerAngleDeg: 25 });
|
|
733
735
|
if (!cubics.length) continue;
|
|
734
736
|
out.push({ type: "M", x: cubics[0].p0[0], y: cubics[0].p0[1] });
|
|
735
737
|
cubics.forEach((c, i) => {
|
|
736
|
-
if (
|
|
738
|
+
if (_chunkVNYRI265cjs.isStraightCubic.call(void 0, c, tol * 0.02)) {
|
|
737
739
|
if (i < cubics.length - 1) out.push({ type: "L", x: c.p3[0], y: c.p3[1] });
|
|
738
740
|
} 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] });
|
|
739
741
|
});
|
|
@@ -744,17 +746,17 @@ function variableStrokeOutline(path, options) {
|
|
|
744
746
|
}
|
|
745
747
|
function nearestStrokePosition(path, p, only) {
|
|
746
748
|
let best = null;
|
|
747
|
-
|
|
749
|
+
_chunkVNYRI265cjs.pathToContours.call(void 0, path).forEach((c, ci) => {
|
|
748
750
|
if (!c.segments.length || only !== void 0 && ci !== only) return;
|
|
749
|
-
const lengths = c.segments.map((s) =>
|
|
751
|
+
const lengths = c.segments.map((s) => _chunkVNYRI265cjs.segmentLength.call(void 0, s));
|
|
750
752
|
const total = lengths.reduce((a, b) => a + b, 0);
|
|
751
753
|
if (!(total > 0)) return;
|
|
752
754
|
let acc = 0;
|
|
753
755
|
c.segments.forEach((seg, si) => {
|
|
754
|
-
const near2 =
|
|
756
|
+
const near2 = _chunkVNYRI265cjs.segmentNearest.call(void 0, seg, p);
|
|
755
757
|
if (!best || near2.distance < best.distance) {
|
|
756
|
-
const s = acc +
|
|
757
|
-
const tan =
|
|
758
|
+
const s = acc + _chunkVNYRI265cjs.segmentLength.call(void 0, seg, 0, near2.t);
|
|
759
|
+
const tan = _chunkVNYRI265cjs.segmentTangent.call(void 0, seg, near2.t);
|
|
758
760
|
const pt2 = seg.length === 2 ? lerp(seg[0], seg[1], near2.t) : evalSeg(seg, near2.t);
|
|
759
761
|
const n = leftNormal([tan[0], tan[1]]);
|
|
760
762
|
const side = (p[0] - pt2[0]) * n[0] + (p[1] - pt2[1]) * n[1] >= 0 ? "left" : "right";
|
|
@@ -771,9 +773,9 @@ function evalSeg(seg, t) {
|
|
|
771
773
|
return pts[0];
|
|
772
774
|
}
|
|
773
775
|
function strokePositionPoint(path, index, t) {
|
|
774
|
-
const c =
|
|
775
|
-
if (!_optionalChain([c, 'optionalAccess',
|
|
776
|
-
const lengths = c.segments.map((s) =>
|
|
776
|
+
const c = _chunkVNYRI265cjs.pathToContours.call(void 0, path)[index];
|
|
777
|
+
if (!_optionalChain([c, 'optionalAccess', _22 => _22.segments, 'access', _23 => _23.length])) return null;
|
|
778
|
+
const lengths = c.segments.map((s) => _chunkVNYRI265cjs.segmentLength.call(void 0, s));
|
|
777
779
|
const total = lengths.reduce((a, b) => a + b, 0);
|
|
778
780
|
let want = Math.min(Math.max(t, 0), 1) * total;
|
|
779
781
|
for (let i = 0; i < c.segments.length; i++) {
|
|
@@ -784,11 +786,11 @@ function strokePositionPoint(path, index, t) {
|
|
|
784
786
|
const target = Math.min(want, lengths[i]);
|
|
785
787
|
for (let k = 0; k < 40; k++) {
|
|
786
788
|
const mid = (lo + hi) / 2;
|
|
787
|
-
if (
|
|
789
|
+
if (_chunkVNYRI265cjs.segmentLength.call(void 0, seg, 0, mid) < target) lo = mid;
|
|
788
790
|
else hi = mid;
|
|
789
791
|
}
|
|
790
792
|
const u = (lo + hi) / 2;
|
|
791
|
-
const tan =
|
|
793
|
+
const tan = _chunkVNYRI265cjs.segmentTangent.call(void 0, seg, u);
|
|
792
794
|
return { point: evalSeg(seg, u), tangent: [tan[0], tan[1]] };
|
|
793
795
|
}
|
|
794
796
|
want -= lengths[i];
|
|
@@ -800,7 +802,7 @@ function strokePositionPoint(path, index, t) {
|
|
|
800
802
|
var KAPPA = 0.5522847498307936;
|
|
801
803
|
var NOTCH = 0.7;
|
|
802
804
|
function isClosedBezierShape(path) {
|
|
803
|
-
const contours =
|
|
805
|
+
const contours = _chunkVNYRI265cjs.pathToContours.call(void 0, path).filter((c) => c.segments.length > 0);
|
|
804
806
|
return contours.length > 0 && contours.every((c) => c.closed);
|
|
805
807
|
}
|
|
806
808
|
function effectiveStrokeAlign(style, closedShape) {
|
|
@@ -808,7 +810,7 @@ function effectiveStrokeAlign(style, closedShape) {
|
|
|
808
810
|
return closedShape ? a : "center";
|
|
809
811
|
}
|
|
810
812
|
function strokeWidthProfileOf(style) {
|
|
811
|
-
if (!_optionalChain([style, 'access',
|
|
813
|
+
if (!_optionalChain([style, 'access', _24 => _24.strokeWidthProfile, 'optionalAccess', _25 => _25.length])) return null;
|
|
812
814
|
const p = sanitizeWidthProfile(style.strokeWidthProfile);
|
|
813
815
|
return isUniformWidthProfile(p) ? null : p;
|
|
814
816
|
}
|
|
@@ -817,17 +819,21 @@ function hasStrokeExtras(style) {
|
|
|
817
819
|
}
|
|
818
820
|
function vectorStrokeLineArea(parts, style, tolerance) {
|
|
819
821
|
const profile = strokeWidthProfileOf(style);
|
|
820
|
-
const dash = _optionalChain([style, 'access',
|
|
822
|
+
const dash = _optionalChain([style, 'access', _26 => _26.strokeDasharray, 'optionalAccess', _27 => _27.length]) ? { dash: style.strokeDasharray } : {};
|
|
821
823
|
const join = _nullishCoalesce(style.strokeLinejoin, () => ( "miter"));
|
|
822
824
|
const cap = _nullishCoalesce(style.strokeLinecap, () => ( "butt"));
|
|
823
825
|
if (profile) return variableStrokeOutline(parts.line, { width: parts.drawWidth, profile, join, cap, ...dash, ...tolerance ? { tolerance } : {} });
|
|
824
|
-
return
|
|
826
|
+
return _chunkVNYRI265cjs.outlineStroke.call(void 0, parts.line, { width: parts.drawWidth, join, cap, ...dash, ...tolerance ? { tolerance } : {} });
|
|
825
827
|
}
|
|
826
828
|
var capExtent = (style, width) => style.strokeLinecap === "round" || style.strokeLinecap === "square" ? width / 2 : 0;
|
|
827
829
|
function arrowheadWeight(style, end) {
|
|
828
830
|
const scale = end === "start" ? style.startArrowScale : style.endArrowScale;
|
|
829
831
|
const s = typeof scale === "number" && scale > 0 && Number.isFinite(scale) ? scale : 1;
|
|
830
|
-
|
|
832
|
+
const width = _nullishCoalesce(style.strokeWidth, () => ( 1));
|
|
833
|
+
const profile = strokeWidthProfileOf(style);
|
|
834
|
+
const at2 = profile ? widthProfileAt(profile, end === "start" ? 0 : 1) : null;
|
|
835
|
+
const here = at2 ? Math.max(width, width * (at2.left + at2.right) / 2) : width;
|
|
836
|
+
return Math.max(0.25, here * s);
|
|
831
837
|
}
|
|
832
838
|
function arrowheadInset(kind, hw, cap) {
|
|
833
839
|
const l = 4 * hw;
|
|
@@ -898,16 +904,16 @@ function arrowheadPath(kind, tip, dir, hw) {
|
|
|
898
904
|
}
|
|
899
905
|
}
|
|
900
906
|
var toVec = (p) => ({ x: p[0], y: p[1] });
|
|
901
|
-
var segLen = (s) =>
|
|
907
|
+
var segLen = (s) => _chunkVNYRI265cjs.segmentLength.call(void 0, s);
|
|
902
908
|
function endOf(segs, atStart) {
|
|
903
909
|
const long = (s2) => segLen(s2) > 1e-9;
|
|
904
910
|
if (atStart) {
|
|
905
911
|
const s2 = _nullishCoalesce(segs.find(long), () => ( segs[0]));
|
|
906
|
-
const t2 =
|
|
912
|
+
const t2 = _chunkVNYRI265cjs.segmentTangent.call(void 0, s2, 0);
|
|
907
913
|
return { p: toVec(segs[0][0]), out: v(-t2[0], -t2[1]) };
|
|
908
914
|
}
|
|
909
915
|
const s = _nullishCoalesce([...segs].reverse().find(long), () => ( segs[segs.length - 1]));
|
|
910
|
-
const t =
|
|
916
|
+
const t = _chunkVNYRI265cjs.segmentTangent.call(void 0, s, 1);
|
|
911
917
|
const last = segs[segs.length - 1];
|
|
912
918
|
return { p: toVec(last[last.length - 1]), out: v(t[0], t[1]) };
|
|
913
919
|
}
|
|
@@ -918,7 +924,7 @@ function pointAlong(segs, fromStart, dist4) {
|
|
|
918
924
|
const l = segLen(s);
|
|
919
925
|
if (acc + l >= dist4) {
|
|
920
926
|
const want = fromStart ? dist4 - acc : l - (dist4 - acc);
|
|
921
|
-
const pts =
|
|
927
|
+
const pts = _chunkVNYRI265cjs.trimSegments.call(void 0, [s], 0, want);
|
|
922
928
|
const p = pts.length ? pts[0][pts[0].length - 1] : s[0];
|
|
923
929
|
return toVec(p);
|
|
924
930
|
}
|
|
@@ -928,7 +934,7 @@ function pointAlong(segs, fromStart, dist4) {
|
|
|
928
934
|
}
|
|
929
935
|
function vectorStrokeParts(path, style) {
|
|
930
936
|
const width = _nullishCoalesce(style.strokeWidth, () => ( 1));
|
|
931
|
-
const contours =
|
|
937
|
+
const contours = _chunkVNYRI265cjs.pathToContours.call(void 0, path).filter((c) => c.segments.length > 0);
|
|
932
938
|
const closedShape = contours.length > 0 && contours.every((c) => c.closed);
|
|
933
939
|
const align = effectiveStrokeAlign(style, closedShape);
|
|
934
940
|
const drawWidth = align === "center" ? width : width * 2;
|
|
@@ -968,26 +974,26 @@ function vectorStrokeParts(path, style) {
|
|
|
968
974
|
if (!s0 && !s1) return c;
|
|
969
975
|
const lengths = c.segments.map(segLen);
|
|
970
976
|
const total = lengths.reduce((a, b) => a + b, 0);
|
|
971
|
-
return { closed: false, segments: total - s1 > s0 ?
|
|
977
|
+
return { closed: false, segments: total - s1 > s0 ? _chunkVNYRI265cjs.trimSegments.call(void 0, c.segments, s0, total - s1, lengths) : [] };
|
|
972
978
|
});
|
|
973
|
-
return { align, line:
|
|
979
|
+
return { align, line: _chunkVNYRI265cjs.contoursToPath.call(void 0, trimmed), drawWidth, heads };
|
|
974
980
|
}
|
|
975
981
|
function vectorStrokeOutlinePath(path, style) {
|
|
976
982
|
const parts = vectorStrokeParts(path, style);
|
|
977
983
|
const stroke = vectorStrokeLineArea(parts, style);
|
|
978
984
|
const fill = { path, fillRule: _nullishCoalesce(style.fillRule, () => ( "nonzero")) };
|
|
979
985
|
let area = stroke;
|
|
980
|
-
if (parts.align === "inside") area =
|
|
981
|
-
else if (parts.align === "outside") area =
|
|
986
|
+
if (parts.align === "inside") area = _chunkVNYRI265cjs.pathBoolean.call(void 0, "intersection", [stroke, fill]).path;
|
|
987
|
+
else if (parts.align === "outside") area = _chunkVNYRI265cjs.pathBoolean.call(void 0, "difference", [stroke, fill]).path;
|
|
982
988
|
if (!parts.heads.length) return area;
|
|
983
|
-
return
|
|
989
|
+
return _chunkVNYRI265cjs.pathBoolean.call(void 0, "union", [area, ...parts.heads.map((h) => h.path)]).path;
|
|
984
990
|
}
|
|
985
991
|
function hitTestVectorStroke(path, p, style, tolerance = 0) {
|
|
986
992
|
const parts = vectorStrokeParts(path, style);
|
|
987
993
|
const point = [p.x, p.y];
|
|
988
994
|
const width = _nullishCoalesce(style.strokeWidth, () => ( 1));
|
|
989
995
|
for (const h of parts.heads) {
|
|
990
|
-
if (
|
|
996
|
+
if (_chunkVNYRI265cjs.pointInBezierPath.call(void 0, h.path, point) || tolerance > 0 && _chunkVNYRI265cjs.distanceToBezierPath.call(void 0, h.path, point) <= tolerance) return true;
|
|
991
997
|
}
|
|
992
998
|
if (!parts.line.length) return false;
|
|
993
999
|
const profile = strokeWidthProfileOf(style);
|
|
@@ -1005,13 +1011,13 @@ function hitTestVectorStroke(path, p, style, tolerance = 0) {
|
|
|
1005
1011
|
reach = Math.max(reach, width / 2 * (w.left + w.right) / 2);
|
|
1006
1012
|
}
|
|
1007
1013
|
} else {
|
|
1008
|
-
d =
|
|
1014
|
+
d = _chunkVNYRI265cjs.distanceToBezierPath.call(void 0, parts.line, point);
|
|
1009
1015
|
if (parts.align !== "center") reach = width;
|
|
1010
1016
|
}
|
|
1011
1017
|
if (parts.align === "center") return d <= reach + tolerance;
|
|
1012
1018
|
if (d > reach + tolerance) return false;
|
|
1013
1019
|
if (d <= tolerance) return true;
|
|
1014
|
-
const inside =
|
|
1020
|
+
const inside = _chunkVNYRI265cjs.pointInBezierPath.call(void 0, path, point, _nullishCoalesce(style.fillRule, () => ( "nonzero")));
|
|
1015
1021
|
return parts.align === "inside" ? inside : !inside;
|
|
1016
1022
|
}
|
|
1017
1023
|
function vectorStrokeReach(style) {
|
|
@@ -1087,7 +1093,7 @@ function vectorNodeToBezier(node) {
|
|
|
1087
1093
|
}
|
|
1088
1094
|
function vectorPathData(input, precision = 3) {
|
|
1089
1095
|
const subpaths = Array.isArray(input) ? input : input.subpaths;
|
|
1090
|
-
return
|
|
1096
|
+
return _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, subpathsToBezier(subpaths), { precision });
|
|
1091
1097
|
}
|
|
1092
1098
|
function inferAnchorType(a) {
|
|
1093
1099
|
if (isOnAnchor(a, a.in) || isOnAnchor(a, a.out)) return "corner";
|
|
@@ -1103,7 +1109,7 @@ function inferAnchorType(a) {
|
|
|
1103
1109
|
return Math.abs(li - lo) <= 1e-3 * Math.max(li, lo) ? "symmetric" : "smooth";
|
|
1104
1110
|
}
|
|
1105
1111
|
function bezierToSubpaths(input) {
|
|
1106
|
-
const path =
|
|
1112
|
+
const path = _chunkVNYRI265cjs.toBezierPath.call(void 0, input);
|
|
1107
1113
|
const out = [];
|
|
1108
1114
|
let current = null;
|
|
1109
1115
|
const last = () => current.anchors[current.anchors.length - 1];
|
|
@@ -1200,14 +1206,14 @@ function nodeMatrix(node) {
|
|
|
1200
1206
|
function vectorPathWorldBezier(node, parent = IDENTITY_MATRIX) {
|
|
1201
1207
|
const m = multiplyMatrices(nodeMatrix(node), parent);
|
|
1202
1208
|
const path = subpathsToBezier(node.subpaths);
|
|
1203
|
-
return isIdentityMatrix(m) ? path :
|
|
1209
|
+
return isIdentityMatrix(m) ? path : _chunkVNYRI265cjs.transformBezierPath.call(void 0, path, m);
|
|
1204
1210
|
}
|
|
1205
1211
|
function vectorNodeBounds(node, parent = IDENTITY_MATRIX) {
|
|
1206
1212
|
if (node.type === "group") {
|
|
1207
1213
|
const m = multiplyMatrices(nodeMatrix(node), parent);
|
|
1208
1214
|
return unionBounds(node.children.map((c) => vectorNodeBounds(c, m)));
|
|
1209
1215
|
}
|
|
1210
|
-
const b =
|
|
1216
|
+
const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, vectorPathWorldBezier(node, parent));
|
|
1211
1217
|
if (!b) return null;
|
|
1212
1218
|
return { x: b.minX, y: b.minY, width: b.maxX - b.minX, height: b.maxY - b.minY };
|
|
1213
1219
|
}
|
|
@@ -1241,9 +1247,9 @@ function hitTestVectorNode(node, p, tolerance = 0, parent = IDENTITY_MATRIX) {
|
|
|
1241
1247
|
const path = vectorPathWorldBezier(node, parent);
|
|
1242
1248
|
if (path.length === 0) return false;
|
|
1243
1249
|
const point = [p.x, p.y];
|
|
1244
|
-
if (hasPaint(node.fill) &&
|
|
1250
|
+
if (hasPaint(node.fill) && _chunkVNYRI265cjs.pointInBezierPath.call(void 0, path, point, _nullishCoalesce(node.fillRule, () => ( "nonzero")))) return true;
|
|
1245
1251
|
if (hasPaint(node.stroke)) return hitTestVectorStroke(path, p, node, tolerance);
|
|
1246
|
-
return
|
|
1252
|
+
return _chunkVNYRI265cjs.distanceToBezierPath.call(void 0, path, point) <= tolerance;
|
|
1247
1253
|
}
|
|
1248
1254
|
function vectorStrokeOutline(node, parent = IDENTITY_MATRIX) {
|
|
1249
1255
|
if (!hasPaint(node.stroke) || !((_nullishCoalesce(node.strokeWidth, () => ( 1))) > 0)) return [];
|
|
@@ -1263,9 +1269,9 @@ function nearestSegment(node, p) {
|
|
|
1263
1269
|
const count = subpathSegmentCount(sp);
|
|
1264
1270
|
for (let i = 0; i < count; i++) {
|
|
1265
1271
|
const seg = subpathSegment(sp, i);
|
|
1266
|
-
const hit =
|
|
1272
|
+
const hit = _chunkVNYRI265cjs.segmentNearest.call(void 0, seg, [p.x, p.y]);
|
|
1267
1273
|
if (!best || hit.distance < best.distance) {
|
|
1268
|
-
const pt2 =
|
|
1274
|
+
const pt2 = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, hit.t);
|
|
1269
1275
|
best = { subpath: s, segment: i, t: hit.t, point: { x: pt2[0], y: pt2[1] }, distance: hit.distance };
|
|
1270
1276
|
}
|
|
1271
1277
|
}
|
|
@@ -1325,7 +1331,7 @@ function bakeIntoGeometry(node, m) {
|
|
|
1325
1331
|
if (isIdentityMatrix(m)) return node;
|
|
1326
1332
|
if (node.type === "group") return { ...node, children: node.children.map((c) => transformVectorNode(c, m)) };
|
|
1327
1333
|
const path = node;
|
|
1328
|
-
const mirrored = m[0] * m[3] - m[1] * m[2] < 0 && _optionalChain([path, 'access',
|
|
1334
|
+
const mirrored = m[0] * m[3] - m[1] * m[2] < 0 && _optionalChain([path, 'access', _28 => _28.strokeWidthProfile, 'optionalAccess', _29 => _29.length]);
|
|
1329
1335
|
return {
|
|
1330
1336
|
...path,
|
|
1331
1337
|
...mirrored ? { strokeWidthProfile: mirrorWidthProfile(path.strokeWidthProfile) } : {},
|
|
@@ -1439,7 +1445,7 @@ function insertAnchor(sp, segment, t) {
|
|
|
1439
1445
|
const ia = segment;
|
|
1440
1446
|
const ib = (segment + 1) % n;
|
|
1441
1447
|
const seg = subpathSegment(sp, segment);
|
|
1442
|
-
const [left, right] =
|
|
1448
|
+
const [left, right] = _chunkVNYRI265cjs.splitSegment.call(void 0, seg, t);
|
|
1443
1449
|
const mid = left[left.length - 1];
|
|
1444
1450
|
const anchor = { x: mid[0], y: mid[1] };
|
|
1445
1451
|
if (seg.length === 4) {
|
|
@@ -1535,7 +1541,7 @@ function vectorCornersAttribute(subpaths, precision = 3) {
|
|
|
1535
1541
|
subpaths.forEach(
|
|
1536
1542
|
(sp, s) => sp.anchors.forEach((a, i) => {
|
|
1537
1543
|
if (!a.corner || !(a.corner.radius > 0)) return;
|
|
1538
|
-
out.push(`${s}.${i}:${
|
|
1544
|
+
out.push(`${s}.${i}:${_chunkVNYRI265cjs.formatNumber.call(void 0, a.corner.radius, precision)}${a.corner.kind && a.corner.kind !== "round" ? `:${a.corner.kind}` : ""}`);
|
|
1539
1545
|
})
|
|
1540
1546
|
);
|
|
1541
1547
|
return out.join(" ");
|
|
@@ -1544,7 +1550,7 @@ function applyVectorCornersAttribute(subpaths, value) {
|
|
|
1544
1550
|
for (const item of value.trim().split(/\s+/)) {
|
|
1545
1551
|
const m = /^(\d+)\.(\d+):([\d.eE+-]+)(?::([a-z]+))?$/.exec(item);
|
|
1546
1552
|
if (!m) continue;
|
|
1547
|
-
const a = _optionalChain([subpaths, 'access',
|
|
1553
|
+
const a = _optionalChain([subpaths, 'access', _30 => _30[+m[1]], 'optionalAccess', _31 => _31.anchors, 'access', _32 => _32[+m[2]]]);
|
|
1548
1554
|
const radius = parseFloat(m[3]);
|
|
1549
1555
|
if (!a || !(radius > 0)) continue;
|
|
1550
1556
|
const kind = VECTOR_CORNER_KINDS.includes(m[4]) ? m[4] : void 0;
|
|
@@ -1556,7 +1562,7 @@ var escapeAttr = (value) => value.replace(/&/g, "&").replace(/"/g, """)
|
|
|
1556
1562
|
function vectorPaintToSvg(paint, gradientId) {
|
|
1557
1563
|
if (!hasPaint(paint)) return { value: "none", gradient: null };
|
|
1558
1564
|
if (typeof paint === "string") return { value: paint, gradient: null };
|
|
1559
|
-
return { value: `url(#${gradientId})`, gradient:
|
|
1565
|
+
return { value: `url(#${gradientId})`, gradient: _chunkVNYRI265cjs.gradientToSvgDef.call(void 0, paint, gradientId) };
|
|
1560
1566
|
}
|
|
1561
1567
|
var partsCache = /* @__PURE__ */ new WeakMap();
|
|
1562
1568
|
function vectorStrokeSvgParts(node, clipId, precision = 3) {
|
|
@@ -1574,22 +1580,22 @@ function computeStrokeSvgParts(node, clipId, precision) {
|
|
|
1574
1580
|
if (parts.align === "center" && !parts.heads.length && !profiled) return void 0;
|
|
1575
1581
|
let clip = null;
|
|
1576
1582
|
if (parts.align !== "center") {
|
|
1577
|
-
const b =
|
|
1583
|
+
const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, path);
|
|
1578
1584
|
const pad = vectorStrokeReach(node) + 1;
|
|
1579
1585
|
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 };
|
|
1580
1586
|
clip = { kind: parts.align === "inside" ? "clip" : "mask", id: clipId, bounds };
|
|
1581
1587
|
}
|
|
1582
1588
|
return {
|
|
1583
1589
|
align: parts.align,
|
|
1584
|
-
d:
|
|
1590
|
+
d: _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, parts.line, { precision }),
|
|
1585
1591
|
width: parts.drawWidth,
|
|
1586
|
-
...profiled && (_nullishCoalesce(node.strokeWidth, () => ( 1))) > 0 ? { outline:
|
|
1592
|
+
...profiled && (_nullishCoalesce(node.strokeWidth, () => ( 1))) > 0 ? { outline: _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, vectorStrokeLineArea(parts, node), { precision }) } : {},
|
|
1587
1593
|
clip,
|
|
1588
|
-
heads: parts.heads.map((h) =>
|
|
1594
|
+
heads: parts.heads.map((h) => _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, h.path, { precision }))
|
|
1589
1595
|
};
|
|
1590
1596
|
}
|
|
1591
1597
|
function widthProfileToAttribute(points, precision = 4) {
|
|
1592
|
-
return points.map((p) => [p.t, p.left, p.right].map((n) =>
|
|
1598
|
+
return points.map((p) => [p.t, p.left, p.right].map((n) => _chunkVNYRI265cjs.formatNumber.call(void 0, n, precision)).join(",")).join(";");
|
|
1593
1599
|
}
|
|
1594
1600
|
function widthProfileFromAttribute(value) {
|
|
1595
1601
|
if (!value) return [];
|
|
@@ -1613,11 +1619,11 @@ function vectorDocumentToSvg(doc, options = {}) {
|
|
|
1613
1619
|
const pretty = options.pretty !== false;
|
|
1614
1620
|
const defs = [];
|
|
1615
1621
|
const lines = [];
|
|
1616
|
-
const num = (n) =>
|
|
1622
|
+
const num = (n) => _chunkVNYRI265cjs.formatNumber.call(void 0, n, precision);
|
|
1617
1623
|
const indent = (depth) => pretty ? " ".repeat(depth) : "";
|
|
1618
1624
|
const common = (node) => {
|
|
1619
1625
|
let out2 = ` id="${escapeAttr(node.id)}"`;
|
|
1620
|
-
if (node.transform) out2 += ` transform="matrix(${node.transform.map((n) =>
|
|
1626
|
+
if (node.transform) out2 += ` transform="matrix(${node.transform.map((n) => _chunkVNYRI265cjs.formatNumber.call(void 0, n, 6)).join(" ")})"`;
|
|
1621
1627
|
if (node.opacity !== void 0 && node.opacity < 1) out2 += ` opacity="${num(node.opacity)}"`;
|
|
1622
1628
|
if (node.visible === false) out2 += ` display="none"`;
|
|
1623
1629
|
return out2;
|
|
@@ -1636,13 +1642,13 @@ function vectorDocumentToSvg(doc, options = {}) {
|
|
|
1636
1642
|
if (stroke.gradient) defs.push(gradientMarkup(stroke.gradient));
|
|
1637
1643
|
const d = vectorPathData(node, precision);
|
|
1638
1644
|
const corners2 = vectorCornersAttribute(node.subpaths, precision);
|
|
1639
|
-
const live = corners2 ? ` data-vector-d="${
|
|
1645
|
+
const live = corners2 ? ` data-vector-d="${_chunkVNYRI265cjs.bezierPathToSvg.call(void 0, subpathsToBezier(node.subpaths, { corners: false }), { precision })}" data-vector-corners="${corners2}"` : "";
|
|
1640
1646
|
const fillAttrs = ` fill="${escapeAttr(fill.value)}"${node.fillRule === "evenodd" ? ` fill-rule="evenodd"` : ""}`;
|
|
1641
1647
|
const lineAttrs = (width) => {
|
|
1642
1648
|
let out2 = ` stroke="${escapeAttr(stroke.value)}" stroke-width="${num(width)}"`;
|
|
1643
1649
|
if (node.strokeLinecap && node.strokeLinecap !== "butt") out2 += ` stroke-linecap="${node.strokeLinecap}"`;
|
|
1644
1650
|
if (node.strokeLinejoin && node.strokeLinejoin !== "miter") out2 += ` stroke-linejoin="${node.strokeLinejoin}"`;
|
|
1645
|
-
if (_optionalChain([node, 'access',
|
|
1651
|
+
if (_optionalChain([node, 'access', _33 => _33.strokeDasharray, 'optionalAccess', _34 => _34.length])) out2 += ` stroke-dasharray="${node.strokeDasharray.map(num).join(" ")}"`;
|
|
1646
1652
|
return out2;
|
|
1647
1653
|
};
|
|
1648
1654
|
const parts = stroke.value !== "none" ? vectorStrokeSvgParts(node, `${prefix}clip-${node.id}`, precision) : void 0;
|
|
@@ -1662,12 +1668,12 @@ function vectorDocumentToSvg(doc, options = {}) {
|
|
|
1662
1668
|
data += ` data-vector-width-profile="${widthProfileToAttribute(profile)}"`;
|
|
1663
1669
|
if (node.strokeLinecap && node.strokeLinecap !== "butt") data += ` data-vector-stroke-linecap="${node.strokeLinecap}"`;
|
|
1664
1670
|
if (node.strokeLinejoin && node.strokeLinejoin !== "miter") data += ` data-vector-stroke-linejoin="${node.strokeLinejoin}"`;
|
|
1665
|
-
if (_optionalChain([node, 'access',
|
|
1671
|
+
if (_optionalChain([node, 'access', _35 => _35.strokeDasharray, 'optionalAccess', _36 => _36.length])) data += ` data-vector-stroke-dasharray="${node.strokeDasharray.map(num).join(" ")}"`;
|
|
1666
1672
|
}
|
|
1667
1673
|
lines.push(`${indent(depth)}<g${common(node)}${data}>`);
|
|
1668
1674
|
lines.push(`${indent(depth + 1)}<path data-vector-part="fill" d="${d}"${fillAttrs}${live}/>`);
|
|
1669
1675
|
if (options.strokes === "outline") {
|
|
1670
|
-
const area =
|
|
1676
|
+
const area = _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, vectorStrokeOutlinePath(subpathsToBezier(node.subpaths), node), { precision });
|
|
1671
1677
|
lines.push(`${indent(depth + 1)}<path data-vector-part="stroke-outline" d="${area}" fill="${escapeAttr(stroke.value)}"/>`);
|
|
1672
1678
|
} else {
|
|
1673
1679
|
let clip = "";
|
|
@@ -1831,7 +1837,7 @@ function resolveGradient(id, raw, seen = /* @__PURE__ */ new Set()) {
|
|
|
1831
1837
|
seen.add(id);
|
|
1832
1838
|
let stops = readStops(el);
|
|
1833
1839
|
const href = _nullishCoalesce(el.attrs.href, () => ( el.attrs["xlink:href"]));
|
|
1834
|
-
if (!stops.length && _optionalChain([href, 'optionalAccess',
|
|
1840
|
+
if (!stops.length && _optionalChain([href, 'optionalAccess', _37 => _37.startsWith, 'call', _38 => _38("#")])) stops = _nullishCoalesce(_optionalChain([resolveGradient, 'call', _39 => _39(href.slice(1), raw, seen), 'optionalAccess', _40 => _40.stops]), () => ( []));
|
|
1835
1841
|
if (!stops.length) return null;
|
|
1836
1842
|
if (el.name === "radialGradient") {
|
|
1837
1843
|
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 };
|
|
@@ -1935,7 +1941,7 @@ function parseVectorSvg(svg, options = {}) {
|
|
|
1935
1941
|
const part = (name) => g.children.find((c) => c.name === "path" && c.attrs["data-vector-part"] === name);
|
|
1936
1942
|
const fillEl = part("fill");
|
|
1937
1943
|
const subpaths = fillEl ? shapeOf(fillEl) : null;
|
|
1938
|
-
if (!fillEl || !_optionalChain([subpaths, 'optionalAccess',
|
|
1944
|
+
if (!fillEl || !_optionalChain([subpaths, 'optionalAccess', _41 => _41.length])) return null;
|
|
1939
1945
|
const a = g.attrs;
|
|
1940
1946
|
const fs = readStyle(fillEl, style);
|
|
1941
1947
|
const strokeEl = part("stroke");
|
|
@@ -1972,7 +1978,7 @@ function parseVectorSvg(svg, options = {}) {
|
|
|
1972
1978
|
...profile.length ? { strokeWidthProfile: profile } : {},
|
|
1973
1979
|
...keptCap ? { strokeLinecap: keptCap } : {},
|
|
1974
1980
|
...keptJoin ? { strokeLinejoin: keptJoin } : {},
|
|
1975
|
-
..._optionalChain([keptDash, 'optionalAccess',
|
|
1981
|
+
..._optionalChain([keptDash, 'optionalAccess', _42 => _42.length]) ? { strokeDasharray: keptDash } : {}
|
|
1976
1982
|
};
|
|
1977
1983
|
return placed(node, m);
|
|
1978
1984
|
};
|
|
@@ -2026,7 +2032,7 @@ function parseVectorSvg(svg, options = {}) {
|
|
|
2026
2032
|
// src/vector/snap.ts
|
|
2027
2033
|
var VECTOR_CONSTRUCTION_ANGLES = [0, 45, 90, 135];
|
|
2028
2034
|
function constrainToLeave(leave, p) {
|
|
2029
|
-
if (!_optionalChain([leave, 'optionalAccess',
|
|
2035
|
+
if (!_optionalChain([leave, 'optionalAccess', _43 => _43.constrain])) return p;
|
|
2030
2036
|
const dx = p.x - leave.at.x;
|
|
2031
2037
|
const dy = p.y - leave.at.y;
|
|
2032
2038
|
switch (leave.constrain) {
|
|
@@ -2137,7 +2143,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2137
2143
|
moving.set(r.nodeId, set);
|
|
2138
2144
|
}
|
|
2139
2145
|
const t = _VectorSnapTargets.collect(doc, new Set(moving.keys()), "segments", false);
|
|
2140
|
-
t.pushPaths(doc, new Set(moving.keys()), (id, s, i) => !!_optionalChain([moving, 'access',
|
|
2146
|
+
t.pushPaths(doc, new Set(moving.keys()), (id, s, i) => !!_optionalChain([moving, 'access', _44 => _44.get, 'call', _45 => _45(id), 'optionalAccess', _46 => _46.has, 'call', _47 => _47(`${s}:${i}`)]), true);
|
|
2141
2147
|
return t.index();
|
|
2142
2148
|
}
|
|
2143
2149
|
/**
|
|
@@ -2255,7 +2261,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2255
2261
|
}
|
|
2256
2262
|
const b = vectorNodeBounds(n, parent);
|
|
2257
2263
|
const f = nodeFrame(n, parent, b);
|
|
2258
|
-
if (b) self.pushRect(b, "edge", _nullishCoalesce(_optionalChain([f, 'optionalAccess',
|
|
2264
|
+
if (b) self.pushRect(b, "edge", _nullishCoalesce(_optionalChain([f, 'optionalAccess', _48 => _48.centre]), () => ( null)));
|
|
2259
2265
|
}
|
|
2260
2266
|
};
|
|
2261
2267
|
visit(doc.nodes, IDENTITY_MATRIX);
|
|
@@ -2300,7 +2306,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2300
2306
|
lines: lines2,
|
|
2301
2307
|
labels: [this.label(q, kind)]
|
|
2302
2308
|
});
|
|
2303
|
-
if (_optionalChain([leave, 'optionalAccess',
|
|
2309
|
+
if (_optionalChain([leave, 'optionalAccess', _49 => _49.constrain])) {
|
|
2304
2310
|
const q = constrainToLeave(leave, p);
|
|
2305
2311
|
const hit = this.slide(leave.at, { x: q.x - leave.at.x, y: q.y - leave.at.y }, q, tol, true);
|
|
2306
2312
|
return hit ? { point: hit.point, x: true, y: true, ...this.linedUp(hit.point, hit.from) } : none(q);
|
|
@@ -2316,7 +2322,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2316
2322
|
}
|
|
2317
2323
|
const on = this.onSegment(near2);
|
|
2318
2324
|
if (on) return at2(on, "path");
|
|
2319
|
-
if (_optionalChain([leave, 'optionalAccess',
|
|
2325
|
+
if (_optionalChain([leave, 'optionalAccess', _50 => _50.angles, 'optionalAccess', _51 => _51.length])) {
|
|
2320
2326
|
const c = construction(leave, p, tol);
|
|
2321
2327
|
if (c) {
|
|
2322
2328
|
const hit = this.slide(leave.at, c.dir, c.point, tol, false);
|
|
@@ -2392,13 +2398,13 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2392
2398
|
const pt2 = toPoint(p);
|
|
2393
2399
|
for (const s of this.segments) {
|
|
2394
2400
|
if (p.x < s.minX - tol || p.x > s.maxX + tol || p.y < s.minY - tol || p.y > s.maxY + tol) continue;
|
|
2395
|
-
const hit =
|
|
2401
|
+
const hit = _chunkVNYRI265cjs.segmentNearest.call(void 0, s.seg, pt2);
|
|
2396
2402
|
if (hit.distance <= tol) out.push({ seg: s.seg, t: hit.t, distance: hit.distance });
|
|
2397
2403
|
}
|
|
2398
2404
|
return out.sort((a, b) => a.distance - b.distance);
|
|
2399
2405
|
}
|
|
2400
2406
|
onSegment(near2) {
|
|
2401
|
-
return near2.length ? toVec2(
|
|
2407
|
+
return near2.length ? toVec2(_chunkVNYRI265cjs.segmentPoint.call(void 0, near2[0].seg, near2[0].t)) : null;
|
|
2402
2408
|
}
|
|
2403
2409
|
/** Where two of the target segments near `p` cross, the crossing nearest `p` within `tol`. */
|
|
2404
2410
|
crossing(near2, p, tol) {
|
|
@@ -2407,7 +2413,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2407
2413
|
let bestD = Infinity;
|
|
2408
2414
|
for (let i = 0; i < list.length; i++) {
|
|
2409
2415
|
for (let j = i + 1; j < list.length; j++) {
|
|
2410
|
-
for (const hit of
|
|
2416
|
+
for (const hit of _chunkVNYRI265cjs.segmentIntersections.call(void 0, list[i].seg, list[j].seg)) {
|
|
2411
2417
|
const q = toVec2(hit.point);
|
|
2412
2418
|
const d = distance(q, p);
|
|
2413
2419
|
if (d <= tol && d < bestD) {
|
|
@@ -2446,7 +2452,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2446
2452
|
* with nothing spaces the box evenly in its row or column. Returns the correction and guides.
|
|
2447
2453
|
*/
|
|
2448
2454
|
snapRect(r, tol, options = {}) {
|
|
2449
|
-
const axes = { x: _optionalChain([options, 'access',
|
|
2455
|
+
const axes = { x: _optionalChain([options, 'access', _52 => _52.axes, 'optionalAccess', _53 => _53.x]) !== false, y: _optionalChain([options, 'access', _54 => _54.axes, 'optionalAccess', _55 => _55.y]) !== false };
|
|
2450
2456
|
const nearest = (lines, values) => {
|
|
2451
2457
|
let best = null;
|
|
2452
2458
|
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 };
|
|
@@ -2454,7 +2460,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2454
2460
|
};
|
|
2455
2461
|
const bx = axes.x ? nearest(this.xs, [r.x, r.x + r.width / 2, r.x + r.width]) : null;
|
|
2456
2462
|
const by = axes.y ? nearest(this.ys, [r.y, r.y + r.height / 2, r.y + r.height]) : null;
|
|
2457
|
-
const out = { dx: _nullishCoalesce(_optionalChain([bx, 'optionalAccess',
|
|
2463
|
+
const out = { dx: _nullishCoalesce(_optionalChain([bx, 'optionalAccess', _56 => _56.d]), () => ( 0)), dy: _nullishCoalesce(_optionalChain([by, 'optionalAccess', _57 => _57.d]), () => ( 0)), x: !!bx, y: !!by, lines: [], labels: [] };
|
|
2458
2464
|
const done = { ...r, x: r.x + out.dx, y: r.y + out.dy };
|
|
2459
2465
|
if (bx) {
|
|
2460
2466
|
const x = bx.from.x;
|
|
@@ -2577,9 +2583,9 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2577
2583
|
const on = this.nearestPoint(p, tol);
|
|
2578
2584
|
const tries = [];
|
|
2579
2585
|
if (on) tries.push({ tx: on.p.x, ty: on.p.y, s: { hx: null, hy: null, on } });
|
|
2580
|
-
tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess',
|
|
2581
|
-
tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess',
|
|
2582
|
-
tries.push({ tx: null, ty: _nullishCoalesce(_optionalChain([hy, 'optionalAccess',
|
|
2586
|
+
tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess', _58 => _58.v]), () => ( null)), ty: _nullishCoalesce(_optionalChain([hy, 'optionalAccess', _59 => _59.v]), () => ( null)), s: { hx, hy, on: null } });
|
|
2587
|
+
tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess', _60 => _60.v]), () => ( null)), ty: null, s: { hx, hy: null, on: null } });
|
|
2588
|
+
tries.push({ tx: null, ty: _nullishCoalesce(_optionalChain([hy, 'optionalAccess', _61 => _61.v]), () => ( null)), s: { hx: null, hy, on: null } });
|
|
2583
2589
|
for (const { tx, ty, s } of tries) {
|
|
2584
2590
|
if (tx === null && ty === null) continue;
|
|
2585
2591
|
const q = applyMatrix(toLocal, { x: _nullishCoalesce(tx, () => ( p.x)), y: _nullishCoalesce(ty, () => ( p.y)) });
|
|
@@ -2729,15 +2735,15 @@ var crossCondition = (r, d) => r[0] * d[1] - r[1] * d[0];
|
|
|
2729
2735
|
function solveOnSegment(seg, base, cond) {
|
|
2730
2736
|
const b = [base.x, base.y];
|
|
2731
2737
|
const g = (t) => {
|
|
2732
|
-
const p =
|
|
2733
|
-
return cond([p[0] - b[0], p[1] - b[1]],
|
|
2738
|
+
const p = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, t);
|
|
2739
|
+
return cond([p[0] - b[0], p[1] - b[1]], _chunkVNYRI265cjs.segmentDerivative.call(void 0, seg, t));
|
|
2734
2740
|
};
|
|
2735
2741
|
const vals = [];
|
|
2736
2742
|
let scale = 0;
|
|
2737
2743
|
for (let i = 0; i <= CURVE_SAMPLES; i++) {
|
|
2738
2744
|
const t = i / CURVE_SAMPLES;
|
|
2739
|
-
const p =
|
|
2740
|
-
const d =
|
|
2745
|
+
const p = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, t);
|
|
2746
|
+
const d = _chunkVNYRI265cjs.segmentDerivative.call(void 0, seg, t);
|
|
2741
2747
|
const r = [p[0] - b[0], p[1] - b[1]];
|
|
2742
2748
|
vals.push(cond(r, d));
|
|
2743
2749
|
scale = Math.max(scale, Math.hypot(r[0], r[1]) * Math.hypot(d[0], d[1]));
|
|
@@ -2764,8 +2770,8 @@ function solveOnSegment(seg, base, cond) {
|
|
|
2764
2770
|
} else hi = m;
|
|
2765
2771
|
}
|
|
2766
2772
|
const t = (lo + hi) / 2;
|
|
2767
|
-
const p =
|
|
2768
|
-
const dv =
|
|
2773
|
+
const p = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, t);
|
|
2774
|
+
const dv = _chunkVNYRI265cjs.segmentDerivative.call(void 0, seg, t);
|
|
2769
2775
|
const r = Math.hypot(p[0] - b[0], p[1] - b[1]);
|
|
2770
2776
|
const dl = Math.hypot(dv[0], dv[1]);
|
|
2771
2777
|
if (!(r > 1e-9 && dl > 0) || Math.abs(cond([p[0] - b[0], p[1] - b[1]], dv)) > 1e-6 * r * dl) continue;
|
|
@@ -2802,7 +2808,7 @@ function endTangent(c) {
|
|
|
2802
2808
|
return [1, 0];
|
|
2803
2809
|
}
|
|
2804
2810
|
function sample(c, n, out, withStart) {
|
|
2805
|
-
for (let i = withStart ? 0 : 1; i <= n; i++) out.push(
|
|
2811
|
+
for (let i = withStart ? 0 : 1; i <= n; i++) out.push(_chunkVNYRI265cjs.segmentPoint.call(void 0, c, i / n));
|
|
2806
2812
|
}
|
|
2807
2813
|
var onAnchor2 = (a, h) => !h || Math.abs(h.x - a.x) < EPS3 && Math.abs(h.y - a.y) < EPS3;
|
|
2808
2814
|
function tidy(a, keepType = true) {
|
|
@@ -2848,7 +2854,7 @@ function fitAcross(pts, N, t0, t1) {
|
|
|
2848
2854
|
const u = [];
|
|
2849
2855
|
for (let i = 0; i <= N; i++) u.push(k * i / N);
|
|
2850
2856
|
for (let i = 1; i <= N; i++) u.push(k + (1 - k) * i / N);
|
|
2851
|
-
return
|
|
2857
|
+
return _chunkVNYRI265cjs.fitCubicWithTangents.call(void 0, pts, u, t0, t1);
|
|
2852
2858
|
};
|
|
2853
2859
|
return goldenMin(fit, 0, 1);
|
|
2854
2860
|
}
|
|
@@ -2908,7 +2914,7 @@ function bendSegment(sp, segment, t, p) {
|
|
|
2908
2914
|
return { anchors, closed: sp.closed };
|
|
2909
2915
|
}
|
|
2910
2916
|
function subpathPointAt(sp, segment, t) {
|
|
2911
|
-
const [x, y] =
|
|
2917
|
+
const [x, y] = _chunkVNYRI265cjs.segmentPoint.call(void 0, subpathSegment(sp, segment), t);
|
|
2912
2918
|
return { x, y };
|
|
2913
2919
|
}
|
|
2914
2920
|
function curvatureMoveAnchor(sp, index, q) {
|
|
@@ -3169,12 +3175,12 @@ function removeRedundantPoints(sp, tolerance) {
|
|
|
3169
3175
|
}
|
|
3170
3176
|
|
|
3171
3177
|
// src/vector/pathCut.ts
|
|
3172
|
-
var loopArea = (l) =>
|
|
3178
|
+
var loopArea = (l) => _chunkVNYRI265cjs.contourSignedArea.call(void 0, l.segs);
|
|
3173
3179
|
function loopSample(l) {
|
|
3174
3180
|
const k = l.chord.findIndex((c) => !c);
|
|
3175
|
-
return
|
|
3181
|
+
return _chunkVNYRI265cjs.segmentPoint.call(void 0, l.segs[k >= 0 ? k : 0], 0.5);
|
|
3176
3182
|
}
|
|
3177
|
-
var contains2 = (l, p) =>
|
|
3183
|
+
var contains2 = (l, p) => _chunkVNYRI265cjs.windingNumber.call(void 0, [l.segs], p) !== 0;
|
|
3178
3184
|
function groupFaces(loops) {
|
|
3179
3185
|
const usable2 = loops.filter((l) => l.segs.length && Math.abs(loopArea(l)) > 1e-12);
|
|
3180
3186
|
if (!usable2.length) return [];
|
|
@@ -3190,12 +3196,12 @@ function groupFaces(loops) {
|
|
|
3190
3196
|
return outers.reverse().map((o) => faces.get(o));
|
|
3191
3197
|
}
|
|
3192
3198
|
function faceToPath(face) {
|
|
3193
|
-
return
|
|
3199
|
+
return _chunkVNYRI265cjs.contoursToPath.call(void 0, face.loops.map((l) => ({ segments: l.segs, closed: true })));
|
|
3194
3200
|
}
|
|
3195
3201
|
function facesOf(path, fillRule) {
|
|
3196
|
-
const normalized =
|
|
3197
|
-
const loops =
|
|
3198
|
-
const segs =
|
|
3202
|
+
const normalized = _chunkVNYRI265cjs.normalizeBezierPath.call(void 0, path, fillRule);
|
|
3203
|
+
const loops = _chunkVNYRI265cjs.pathToContours.call(void 0, normalized).map((c) => {
|
|
3204
|
+
const segs = _chunkVNYRI265cjs.closeContour.call(void 0, c, true).map((s) => s.slice());
|
|
3199
3205
|
return { segs, chord: segs.map(() => false) };
|
|
3200
3206
|
});
|
|
3201
3207
|
return groupFaces(loops);
|
|
@@ -3265,7 +3271,7 @@ function lineHits(p, q, seg) {
|
|
|
3265
3271
|
const scale = Math.sqrt(len2) * Math.max(1, ...seg.map((pt2) => Math.abs(pt2[0]) + Math.abs(pt2[1])));
|
|
3266
3272
|
const out = [];
|
|
3267
3273
|
for (const t of rootsInUnit(...coeffs, scale)) {
|
|
3268
|
-
const point =
|
|
3274
|
+
const point = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, t);
|
|
3269
3275
|
const s = ((point[0] - p[0]) * dx + (point[1] - p[1]) * dy) / len2;
|
|
3270
3276
|
if (s >= -1e-9 && s <= 1 + 1e-9) out.push({ s: Math.min(1, Math.max(0, s)), t, point });
|
|
3271
3277
|
}
|
|
@@ -3278,7 +3284,7 @@ function arc(l, a, b, eps) {
|
|
|
3278
3284
|
const segs = [];
|
|
3279
3285
|
const chord = [];
|
|
3280
3286
|
const push = (k, t0, t1) => {
|
|
3281
|
-
const piece = t0 <= 0 && t1 >= 1 ? l.segs[k].slice() :
|
|
3287
|
+
const piece = t0 <= 0 && t1 >= 1 ? l.segs[k].slice() : _chunkVNYRI265cjs.subSegment.call(void 0, l.segs[k], t0, t1);
|
|
3282
3288
|
if (!degenerate(piece, eps)) {
|
|
3283
3289
|
segs.push(piece);
|
|
3284
3290
|
chord.push(l.chord[k]);
|
|
@@ -3303,7 +3309,7 @@ function knifePath(path, fillRule, knife) {
|
|
|
3303
3309
|
if (pts.length < 2) return null;
|
|
3304
3310
|
let faces = facesOf(path, fillRule);
|
|
3305
3311
|
if (!faces.length) return null;
|
|
3306
|
-
const b =
|
|
3312
|
+
const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, path);
|
|
3307
3313
|
const size = b ? Math.max(b.maxX - b.minX, b.maxY - b.minY, 1) : 1;
|
|
3308
3314
|
const eps = size * 1e-9;
|
|
3309
3315
|
let cursor = -Infinity;
|
|
@@ -3317,7 +3323,7 @@ function knifePath(path, fillRule, knife) {
|
|
|
3317
3323
|
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]) };
|
|
3318
3324
|
face2.loops.forEach(
|
|
3319
3325
|
(l, li) => l.segs.forEach((seg, si) => {
|
|
3320
|
-
const sb =
|
|
3326
|
+
const sb = _chunkVNYRI265cjs.segmentBounds.call(void 0, seg);
|
|
3321
3327
|
if (sb.maxX < kb.minX - eps || sb.minX > kb.maxX + eps || sb.maxY < kb.minY - eps || sb.minY > kb.maxY + eps) return;
|
|
3322
3328
|
for (const h of lineHits(pts[m], pts[m + 1], seg)) {
|
|
3323
3329
|
const s = m + h.s;
|
|
@@ -3332,7 +3338,7 @@ function knifePath(path, fillRule, knife) {
|
|
|
3332
3338
|
const m = Math.min(pts.length - 2, Math.floor(s));
|
|
3333
3339
|
const u = s - m;
|
|
3334
3340
|
const q = [pts[m][0] + (pts[m + 1][0] - pts[m][0]) * u, pts[m][1] + (pts[m + 1][1] - pts[m][1]) * u];
|
|
3335
|
-
return
|
|
3341
|
+
return _chunkVNYRI265cjs.windingNumber.call(void 0, face2.loops.map((l) => l.segs), q) !== 0;
|
|
3336
3342
|
};
|
|
3337
3343
|
for (let i = 0; i < unique.length - 1; i++) {
|
|
3338
3344
|
const from2 = unique[i];
|
|
@@ -3392,33 +3398,33 @@ function eraserRegion(points, width) {
|
|
|
3392
3398
|
];
|
|
3393
3399
|
}
|
|
3394
3400
|
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] }))];
|
|
3395
|
-
return
|
|
3401
|
+
return _chunkVNYRI265cjs.outlineStroke.call(void 0, line2, { width, cap: "round", join: "round" });
|
|
3396
3402
|
}
|
|
3397
3403
|
function eraseFromFill(path, fillRule, region) {
|
|
3398
|
-
const overlap =
|
|
3399
|
-
if (!
|
|
3400
|
-
const rest =
|
|
3404
|
+
const overlap = _chunkVNYRI265cjs.pathBoolean.call(void 0, "intersection", [{ path, fillRule }, { path: region }]).path;
|
|
3405
|
+
if (!_chunkVNYRI265cjs.pathToContours.call(void 0, overlap).some((c) => Math.abs(_chunkVNYRI265cjs.contourSignedArea.call(void 0, _chunkVNYRI265cjs.closeContour.call(void 0, c, true))) > 1e-9)) return null;
|
|
3406
|
+
const rest = _chunkVNYRI265cjs.pathBoolean.call(void 0, "difference", [{ path, fillRule }, { path: region }]).path;
|
|
3401
3407
|
return splitIntoFaces(rest);
|
|
3402
3408
|
}
|
|
3403
3409
|
function eraseFromOutline(sp, region) {
|
|
3404
|
-
const regionSegs =
|
|
3410
|
+
const regionSegs = _chunkVNYRI265cjs.pathToContours.call(void 0, region).flatMap((c) => _chunkVNYRI265cjs.closeContour.call(void 0, c, true));
|
|
3405
3411
|
if (!regionSegs.length) return null;
|
|
3406
|
-
const rb =
|
|
3412
|
+
const rb = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, region);
|
|
3407
3413
|
const count = subpathSegmentCount(sp);
|
|
3408
3414
|
if (!rb || count === 0) return null;
|
|
3409
|
-
const removed = (p) =>
|
|
3415
|
+
const removed = (p) => _chunkVNYRI265cjs.pointInBezierPath.call(void 0, region, p, "nonzero");
|
|
3410
3416
|
const runs = [];
|
|
3411
3417
|
let cur = [];
|
|
3412
3418
|
let any = false;
|
|
3413
3419
|
for (let i = 0; i < count; i++) {
|
|
3414
3420
|
const seg = subpathSegment(sp, i);
|
|
3415
|
-
const sb =
|
|
3421
|
+
const sb = _chunkVNYRI265cjs.segmentBounds.call(void 0, seg);
|
|
3416
3422
|
const ts = [0, 1];
|
|
3417
3423
|
if (!(sb.maxX < rb.minX || sb.minX > rb.maxX || sb.maxY < rb.minY || sb.minY > rb.maxY)) {
|
|
3418
3424
|
for (const r of regionSegs) {
|
|
3419
|
-
const b =
|
|
3425
|
+
const b = _chunkVNYRI265cjs.segmentBounds.call(void 0, r);
|
|
3420
3426
|
if (b.maxX < sb.minX || b.minX > sb.maxX || b.maxY < sb.minY || b.minY > sb.maxY) continue;
|
|
3421
|
-
for (const hit of
|
|
3427
|
+
for (const hit of _chunkVNYRI265cjs.segmentIntersections.call(void 0, seg, r)) if (hit.ta > 1e-9 && hit.ta < 1 - 1e-9) ts.push(hit.ta);
|
|
3422
3428
|
}
|
|
3423
3429
|
}
|
|
3424
3430
|
ts.sort((a, b) => a - b);
|
|
@@ -3426,7 +3432,7 @@ function eraseFromOutline(sp, region) {
|
|
|
3426
3432
|
const t0 = ts[k];
|
|
3427
3433
|
const t1 = ts[k + 1];
|
|
3428
3434
|
if (t1 - t0 < 1e-9) continue;
|
|
3429
|
-
if (removed(
|
|
3435
|
+
if (removed(_chunkVNYRI265cjs.segmentPoint.call(void 0, seg, (t0 + t1) / 2))) {
|
|
3430
3436
|
any = true;
|
|
3431
3437
|
if (cur.length) runs.push(cur);
|
|
3432
3438
|
cur = [];
|
|
@@ -3445,7 +3451,7 @@ function eraseFromOutline(sp, region) {
|
|
|
3445
3451
|
for (const run of runs) {
|
|
3446
3452
|
const anchors = [];
|
|
3447
3453
|
for (const { seg, t0, t1 } of run) {
|
|
3448
|
-
const c =
|
|
3454
|
+
const c = _chunkVNYRI265cjs.subSegment.call(void 0, subpathSegment(sp, seg), t0, t1);
|
|
3449
3455
|
const line2 = c.length === 2;
|
|
3450
3456
|
const start = c[0];
|
|
3451
3457
|
const end = c[c.length - 1];
|
|
@@ -3753,14 +3759,14 @@ function worldOf(entry, subpaths) {
|
|
|
3753
3759
|
return vectorPathWorldBezier({ ...entry.node, subpaths }, entry.parent);
|
|
3754
3760
|
}
|
|
3755
3761
|
function subpathEnclosesArea(sp) {
|
|
3756
|
-
const contour =
|
|
3762
|
+
const contour = _chunkVNYRI265cjs.pathToContours.call(void 0, subpathsToBezier([{ ...sp, closed: true }]))[0];
|
|
3757
3763
|
if (!contour) return false;
|
|
3758
|
-
const segs =
|
|
3759
|
-
const b =
|
|
3764
|
+
const segs = _chunkVNYRI265cjs.closeContour.call(void 0, contour, true);
|
|
3765
|
+
const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, _chunkVNYRI265cjs.contoursToPath.call(void 0, [{ segments: segs, closed: true }]));
|
|
3760
3766
|
if (!b) return false;
|
|
3761
3767
|
const w = b.maxX - b.minX;
|
|
3762
3768
|
const h = b.maxY - b.minY;
|
|
3763
|
-
return Math.abs(
|
|
3769
|
+
return Math.abs(_chunkVNYRI265cjs.contourSignedArea.call(void 0, segs)) > 1e-9 * (w * w + h * h);
|
|
3764
3770
|
}
|
|
3765
3771
|
var paintKey = (paint) => typeof paint === "string" ? paint.trim().toLowerCase() : JSON.stringify(_nullishCoalesce(paint, () => ( null)));
|
|
3766
3772
|
function vectorPathfinderShape(entry, op) {
|
|
@@ -3813,31 +3819,50 @@ function vectorShapeBuilderMap(entries) {
|
|
|
3813
3819
|
lines.push(!subpaths.some((s) => s.closed));
|
|
3814
3820
|
return { path: worldOf(entry, subpaths), fillRule: _nullishCoalesce(entry.node.fillRule, () => ( "nonzero")) };
|
|
3815
3821
|
});
|
|
3816
|
-
const map =
|
|
3822
|
+
const map = _chunkVNYRI265cjs.PlanarMap.build(inputs);
|
|
3817
3823
|
if (!map) return null;
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3824
|
+
let chains = null;
|
|
3825
|
+
const runs = (line2) => (chains ??= map.chains()).filter((c) => lines[c.source] === line2 && !(line2 && c.closed)).map((c) => {
|
|
3826
|
+
const path = _chunkVNYRI265cjs.contoursToPath.call(void 0, [{ segments: c.segments, closed: c.closed }]);
|
|
3827
|
+
return { path, segments: c.segments, closed: c.closed, source: c.source, bounds: _chunkVNYRI265cjs.bezierPathBounds.call(void 0, path) };
|
|
3821
3828
|
});
|
|
3822
|
-
|
|
3829
|
+
const pieces = lines.some(Boolean) ? runs(true) : [];
|
|
3830
|
+
let edges = null;
|
|
3831
|
+
let size = 0;
|
|
3832
|
+
for (const input of inputs) {
|
|
3833
|
+
const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, input.path);
|
|
3834
|
+
if (b) size = Math.max(size, b.maxX - b.minX, b.maxY - b.minY);
|
|
3835
|
+
}
|
|
3836
|
+
return {
|
|
3837
|
+
entries: [...entries],
|
|
3838
|
+
map,
|
|
3839
|
+
lines,
|
|
3840
|
+
pieces,
|
|
3841
|
+
get edges() {
|
|
3842
|
+
return edges ??= runs(false);
|
|
3843
|
+
},
|
|
3844
|
+
tolerance: 0.2 * Math.max(size / 2e3, 0.25)
|
|
3845
|
+
};
|
|
3823
3846
|
}
|
|
3824
|
-
function
|
|
3847
|
+
function pieceNear(pieces, p, tol) {
|
|
3825
3848
|
const point = [p.x, p.y];
|
|
3849
|
+
let best = null;
|
|
3850
|
+
pieces.forEach((piece, index) => {
|
|
3851
|
+
const b = piece.bounds;
|
|
3852
|
+
if (p.x < b.minX - tol || p.x > b.maxX + tol || p.y < b.minY - tol || p.y > b.maxY + tol) return;
|
|
3853
|
+
const d = _chunkVNYRI265cjs.distanceToBezierPath.call(void 0, piece.path, point);
|
|
3854
|
+
if (d <= tol && (!best || d < best.d)) best = { index, d };
|
|
3855
|
+
});
|
|
3856
|
+
return best;
|
|
3857
|
+
}
|
|
3858
|
+
function vectorShapeBuilderHit(m, p, lineTolerance = null) {
|
|
3826
3859
|
if (lineTolerance !== null && lineTolerance > 0) {
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
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 };
|
|
3860
|
+
const line2 = pieceNear(m.pieces, p, lineTolerance);
|
|
3861
|
+
const edge = pieceNear(m.edges, p, lineTolerance);
|
|
3862
|
+
if (edge && (!line2 || edge.d < line2.d)) return { edge: edge.index };
|
|
3863
|
+
if (line2) return { line: line2.index };
|
|
3839
3864
|
}
|
|
3840
|
-
const face = m.map.faceAt(
|
|
3865
|
+
const face = m.map.faceAt([p.x, p.y]);
|
|
3841
3866
|
return face >= 0 ? { face } : null;
|
|
3842
3867
|
}
|
|
3843
3868
|
function samplePolyline(points, step) {
|
|
@@ -3855,25 +3880,31 @@ function samplePolyline(points, step) {
|
|
|
3855
3880
|
}
|
|
3856
3881
|
function addBuilderHit(touched, hit) {
|
|
3857
3882
|
if (!hit) return false;
|
|
3858
|
-
const [list, i] = "face" in hit ? [touched.faces, hit.face] : [touched.lines, hit.line];
|
|
3883
|
+
const [list, i] = "face" in hit ? [touched.faces, hit.face] : "line" in hit ? [touched.lines, hit.line] : [touched.edges, hit.edge];
|
|
3859
3884
|
if (list.includes(i)) return false;
|
|
3860
3885
|
list.push(i);
|
|
3861
3886
|
return true;
|
|
3862
3887
|
}
|
|
3863
3888
|
function sides(m, piece) {
|
|
3864
3889
|
const seg = piece.segments[Math.floor(piece.segments.length / 2)];
|
|
3865
|
-
const mid =
|
|
3866
|
-
const t =
|
|
3890
|
+
const mid = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, 0.5);
|
|
3891
|
+
const t = _chunkVNYRI265cjs.segmentTangent.call(void 0, seg, 0.5);
|
|
3867
3892
|
const chord = Math.hypot(seg[seg.length - 1][0] - seg[0][0], seg[seg.length - 1][1] - seg[0][1]);
|
|
3868
3893
|
const off = Math.max(1e-6, Math.min(0.05, 0.05 * chord));
|
|
3869
3894
|
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
3895
|
}
|
|
3896
|
+
function vectorBuilderErasedEdges(m, touched) {
|
|
3897
|
+
if (!touched.edges.length) return [];
|
|
3898
|
+
const faces = new Set(touched.faces);
|
|
3899
|
+
return touched.edges.filter((k) => m.edges[k] && !sides(m, m.edges[k]).some((f) => f >= 0 && faces.has(f)));
|
|
3900
|
+
}
|
|
3871
3901
|
function planShapeBuilder(m, touched, erase) {
|
|
3872
3902
|
const replace = /* @__PURE__ */ new Map();
|
|
3873
3903
|
const picked = new Set(touched.faces);
|
|
3874
3904
|
const faces = m.map.faces;
|
|
3875
3905
|
const sourcesOf = faces.map((_, i) => m.map.faceSources(i));
|
|
3876
|
-
m.
|
|
3906
|
+
const cuts = erase ? vectorBuilderErasedEdges(m, touched).map((k) => m.edges[k]) : [];
|
|
3907
|
+
m.entries.forEach((entry, i) => {
|
|
3877
3908
|
if (m.lines[i]) {
|
|
3878
3909
|
const own = m.pieces.flatMap((piece, k) => piece.source === i ? [k] : []);
|
|
3879
3910
|
const keep = own.filter((k) => !touched.lines.includes(k) && !sides(m, m.pieces[k]).every((f) => f >= 0 && picked.has(f)));
|
|
@@ -3881,10 +3912,24 @@ function planShapeBuilder(m, touched, erase) {
|
|
|
3881
3912
|
replace.set(i, keep.length ? { kind: "pieces", paths: keep.map((k) => m.pieces[k].path) } : null);
|
|
3882
3913
|
return;
|
|
3883
3914
|
}
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3915
|
+
const inUnion = touched.faces.some((f) => sourcesOf[f].includes(i));
|
|
3916
|
+
if (!inUnion && !cuts.length) return;
|
|
3917
|
+
let rest;
|
|
3918
|
+
if (inUnion) {
|
|
3919
|
+
const kept = faces.flatMap((_, f) => sourcesOf[f].includes(i) && !picked.has(f) ? [f] : []);
|
|
3920
|
+
rest = kept.length ? m.map.merge(kept) : [];
|
|
3921
|
+
} else rest = worldOf(entry, entry.node.subpaths.filter(usable));
|
|
3922
|
+
const fillCloses = hasPaint(entry.node.fill);
|
|
3923
|
+
let cut = false;
|
|
3924
|
+
for (const piece of cuts) {
|
|
3925
|
+
const r = rest.length ? _chunkVNYRI265cjs.cutOutPiece.call(void 0, rest, piece, fillCloses, m.tolerance) : null;
|
|
3926
|
+
if (r) {
|
|
3927
|
+
rest = r;
|
|
3928
|
+
cut = true;
|
|
3929
|
+
}
|
|
3930
|
+
}
|
|
3931
|
+
if (!inUnion && !cut) return;
|
|
3932
|
+
replace.set(i, rest.length ? { kind: inUnion ? "fill" : "outline", path: rest } : null);
|
|
3888
3933
|
});
|
|
3889
3934
|
let merged = null;
|
|
3890
3935
|
if (!erase && touched.faces.length) {
|
|
@@ -3898,7 +3943,7 @@ function planShapeBuilder(m, touched, erase) {
|
|
|
3898
3943
|
}
|
|
3899
3944
|
function vectorFillMap(doc, gap = 0) {
|
|
3900
3945
|
const entries = vectorPathEntries(doc, null, { locked: true });
|
|
3901
|
-
return
|
|
3946
|
+
return _chunkVNYRI265cjs.PlanarMap.build(
|
|
3902
3947
|
entries.map((e) => ({ path: worldOf(e, e.node.subpaths.filter(usable)), fills: false })),
|
|
3903
3948
|
{ gap, maxSegments: 2e4 }
|
|
3904
3949
|
);
|
|
@@ -3960,7 +4005,7 @@ function getEditablePathIds(state) {
|
|
|
3960
4005
|
}
|
|
3961
4006
|
}
|
|
3962
4007
|
}
|
|
3963
|
-
return [...ids].filter((id) => _optionalChain([findVectorNode, 'call',
|
|
4008
|
+
return [...ids].filter((id) => _optionalChain([findVectorNode, 'call', _62 => _62(state.document.nodes, id), 'optionalAccess', _63 => _63.type]) === "path");
|
|
3964
4009
|
}
|
|
3965
4010
|
function getVisibleAnchors(state) {
|
|
3966
4011
|
const out = [];
|
|
@@ -3975,7 +4020,7 @@ function getVisibleHandles(state) {
|
|
|
3975
4020
|
const seen = /* @__PURE__ */ new Set();
|
|
3976
4021
|
const push = (node, s, i, handle) => {
|
|
3977
4022
|
const sp = node.subpaths[s];
|
|
3978
|
-
const a = _optionalChain([sp, 'optionalAccess',
|
|
4023
|
+
const a = _optionalChain([sp, 'optionalAccess', _64 => _64.anchors, 'access', _65 => _65[i]]);
|
|
3979
4024
|
if (!a || !a[handle]) return;
|
|
3980
4025
|
const key = `${node.id}:${s}:${i}:${handle}`;
|
|
3981
4026
|
if (seen.has(key)) return;
|
|
@@ -3984,8 +4029,8 @@ function getVisibleHandles(state) {
|
|
|
3984
4029
|
};
|
|
3985
4030
|
if (state.tool === "pen" && state.pen) {
|
|
3986
4031
|
const node = findVectorNode(state.document.nodes, state.pen.nodeId);
|
|
3987
|
-
const sp = _optionalChain([node, 'optionalAccess',
|
|
3988
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
4032
|
+
const sp = _optionalChain([node, 'optionalAccess', _66 => _66.type]) === "path" ? node.subpaths[state.pen.subpath] : void 0;
|
|
4033
|
+
if (_optionalChain([node, 'optionalAccess', _67 => _67.type]) === "path" && sp) {
|
|
3989
4034
|
const last = sp.anchors.length - 1;
|
|
3990
4035
|
push(node, state.pen.subpath, last, "in");
|
|
3991
4036
|
push(node, state.pen.subpath, last, "out");
|
|
@@ -4023,11 +4068,11 @@ function getVectorCornerWidgets(state) {
|
|
|
4023
4068
|
const side = Math.min(c.lu, c.lv);
|
|
4024
4069
|
if (side * zoom < 3 * VECTOR_CORNER_WIDGET_INSET) continue;
|
|
4025
4070
|
const a = node.subpaths[c.subpath].anchors[c.index];
|
|
4026
|
-
const radius = _nullishCoalesce(_optionalChain([a, 'access',
|
|
4071
|
+
const radius = _nullishCoalesce(_optionalChain([a, 'access', _68 => _68.corner, 'optionalAccess', _69 => _69.radius]), () => ( 0));
|
|
4027
4072
|
const drawn = fitCornerRadius(c, radius);
|
|
4028
4073
|
const k = Math.min(Math.max(drawn / c.sin, VECTOR_CORNER_WIDGET_INSET / (zoom * Math.sqrt(1 + c.cos))), side / 2);
|
|
4029
4074
|
const p = applyMatrix(m, cornerBisectorPoint(c, k));
|
|
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',
|
|
4075
|
+
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', _70 => _70.corner, 'optionalAccess', _71 => _71.kind]), () => ( "round")), corner: c });
|
|
4031
4076
|
}
|
|
4032
4077
|
}
|
|
4033
4078
|
return out;
|
|
@@ -4037,6 +4082,12 @@ function vectorStrokeWidthGeometry(node) {
|
|
|
4037
4082
|
const parts = vectorStrokeParts(subpathsToBezier(node.subpaths), node);
|
|
4038
4083
|
return parts.line.length ? { line: parts.line, unit: parts.drawWidth / 2 } : null;
|
|
4039
4084
|
}
|
|
4085
|
+
function shiftWidthPoints(profile, indices, dt) {
|
|
4086
|
+
const moving = new Set(indices);
|
|
4087
|
+
const tagged = profile.map((p, i) => ({ p: moving.has(i) ? { ...p, t: Math.min(Math.max(p.t + dt, 0), 1) } : { ...p }, i }));
|
|
4088
|
+
tagged.sort((a, b) => a.p.t - b.p.t || a.i - b.i);
|
|
4089
|
+
return { points: tagged.map((x) => x.p), renumber: new Map(tagged.map((x, k) => [x.i, k])) };
|
|
4090
|
+
}
|
|
4040
4091
|
function getVectorWidthHandles(state) {
|
|
4041
4092
|
if (state.tool !== "width") return [];
|
|
4042
4093
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -4044,13 +4095,13 @@ function getVectorWidthHandles(state) {
|
|
|
4044
4095
|
const n = findVectorNode(state.document.nodes, id);
|
|
4045
4096
|
if (n) for (const p of collectPathNodes(n)) ids.add(p.id);
|
|
4046
4097
|
}
|
|
4047
|
-
if (_optionalChain([state, 'access',
|
|
4048
|
-
if (_optionalChain([state, 'access',
|
|
4049
|
-
|
|
4098
|
+
if (_optionalChain([state, 'access', _72 => _72.hover, 'optionalAccess', _73 => _73.nodeId])) ids.add(state.hover.nodeId);
|
|
4099
|
+
if (_optionalChain([state, 'access', _74 => _74.interaction, 'optionalAccess', _75 => _75.type]) === "width") ids.add(state.interaction.ref.nodeId);
|
|
4100
|
+
for (const r of state.selectedWidthPoints) ids.add(r.nodeId);
|
|
4050
4101
|
const out = [];
|
|
4051
4102
|
for (const id of ids) {
|
|
4052
4103
|
const node = findVectorNode(state.document.nodes, id);
|
|
4053
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
4104
|
+
if (_optionalChain([node, 'optionalAccess', _76 => _76.type]) !== "path" || node.visible === false || !_optionalChain([node, 'access', _77 => _77.strokeWidthProfile, 'optionalAccess', _78 => _78.length])) continue;
|
|
4054
4105
|
const g = vectorStrokeWidthGeometry(node);
|
|
4055
4106
|
if (!g) continue;
|
|
4056
4107
|
const profile = sanitizeWidthProfile(node.strokeWidthProfile);
|
|
@@ -4065,7 +4116,6 @@ function getVectorWidthHandles(state) {
|
|
|
4065
4116
|
const p = applyMatrix(m, c);
|
|
4066
4117
|
const l = applyMatrix(m, { x: c.x + n.x * w.left * g.unit, y: c.y + n.y * w.left * g.unit });
|
|
4067
4118
|
const r = applyMatrix(m, { x: c.x - n.x * w.right * g.unit, y: c.y - n.y * w.right * g.unit });
|
|
4068
|
-
const sel = state.selectedWidthPoint;
|
|
4069
4119
|
out.push({
|
|
4070
4120
|
ref: { nodeId: id, index, subpath: sp },
|
|
4071
4121
|
x: p.x,
|
|
@@ -4075,7 +4125,7 @@ function getVectorWidthHandles(state) {
|
|
|
4075
4125
|
t: w.t,
|
|
4076
4126
|
leftScale: w.left,
|
|
4077
4127
|
rightScale: w.right,
|
|
4078
|
-
selected:
|
|
4128
|
+
selected: state.selectedWidthPoints.some((r2) => r2.nodeId === id && r2.index === index)
|
|
4079
4129
|
});
|
|
4080
4130
|
});
|
|
4081
4131
|
}
|
|
@@ -4084,7 +4134,7 @@ function getVectorWidthHandles(state) {
|
|
|
4084
4134
|
}
|
|
4085
4135
|
function getAnchor(doc, ref) {
|
|
4086
4136
|
const node = findVectorNode(doc.nodes, ref.nodeId);
|
|
4087
|
-
return _optionalChain([node, 'optionalAccess',
|
|
4137
|
+
return _optionalChain([node, 'optionalAccess', _79 => _79.type]) === "path" ? _optionalChain([node, 'access', _80 => _80.subpaths, 'access', _81 => _81[ref.subpath], 'optionalAccess', _82 => _82.anchors, 'access', _83 => _83[ref.index]]) : void 0;
|
|
4088
4138
|
}
|
|
4089
4139
|
function getAnchorWorld(doc, ref) {
|
|
4090
4140
|
const a = getAnchor(doc, ref);
|
|
@@ -4271,43 +4321,44 @@ var VectorEditorController = (_class3 = class {
|
|
|
4271
4321
|
|
|
4272
4322
|
__init9() {this.selection = []}
|
|
4273
4323
|
__init10() {this.anchors = []}
|
|
4274
|
-
__init11() {this.
|
|
4275
|
-
__init12() {this.
|
|
4276
|
-
__init13() {this.
|
|
4324
|
+
__init11() {this.widthPoints = []}
|
|
4325
|
+
__init12() {this.widthEdit = null}
|
|
4326
|
+
__init13() {this.editingId = null}
|
|
4327
|
+
__init14() {this.pen = null}
|
|
4277
4328
|
|
|
4278
4329
|
|
|
4279
4330
|
|
|
4280
4331
|
|
|
4281
4332
|
|
|
4282
4333
|
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4334
|
+
__init15() {this.hover = null}
|
|
4335
|
+
__init16() {this.pointer = null}
|
|
4336
|
+
__init17() {this.drag = null}
|
|
4337
|
+
__init18() {this.interaction = null}
|
|
4338
|
+
__init19() {this.guides = null}
|
|
4288
4339
|
/** Whether the last `snapDrawn` landed on an object (guides may be hidden). */
|
|
4289
|
-
|
|
4340
|
+
__init20() {this.snappedToObject = false}
|
|
4290
4341
|
/** Drawing targets for hovering the pen and shape tools, kept while the document and the excluded path stay the same. */
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4342
|
+
__init21() {this.hoverTargets = null}
|
|
4343
|
+
__init22() {this.spaceHeld = false}
|
|
4344
|
+
__init23() {this.clipboard = null}
|
|
4294
4345
|
/** Shape Builder map of the selection, kept while the document and the selection stay the same. */
|
|
4295
|
-
|
|
4346
|
+
__init24() {this.builderCache = null}
|
|
4296
4347
|
/** Paint bucket map of the visible outlines. */
|
|
4297
|
-
|
|
4298
|
-
|
|
4348
|
+
__init25() {this.fillCache = null}
|
|
4349
|
+
__init26() {this.builderPreview = null}
|
|
4299
4350
|
/** What the highlight shows, to skip notifying when the pointer stays over the same face. */
|
|
4300
|
-
|
|
4351
|
+
__init27() {this.builderHoverKey = null}
|
|
4301
4352
|
|
|
4302
4353
|
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4354
|
+
__init28() {this.listeners = /* @__PURE__ */ new Set()}
|
|
4355
|
+
__init29() {this.cleanups = []}
|
|
4356
|
+
__init30() {this.applying = false}
|
|
4306
4357
|
/** Set while a commit records a change that was already applied, so `restore` still reports it. */
|
|
4307
|
-
|
|
4308
|
-
|
|
4358
|
+
__init31() {this.committing = false}
|
|
4359
|
+
__init32() {this.revision = 0}
|
|
4309
4360
|
|
|
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);
|
|
4361
|
+
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);_class3.prototype.__init34.call(this);
|
|
4311
4362
|
this.history = _nullishCoalesce(options.history, () => ( new (0, _chunkQKLRAA4Tcjs.HistoryManager)()));
|
|
4312
4363
|
this.doc = options.document ? cloneVectorDocument(options.document) : { width: 800, height: 600, nodes: [] };
|
|
4313
4364
|
this.tool = _nullishCoalesce(options.tool, () => ( "select"));
|
|
@@ -4336,9 +4387,9 @@ var VectorEditorController = (_class3 = class {
|
|
|
4336
4387
|
// State
|
|
4337
4388
|
// -------------------------------------------------------------------------
|
|
4338
4389
|
/** The current snapshot (stable until the next change). */
|
|
4339
|
-
|
|
4390
|
+
__init33() {this.getState = () => this.state}
|
|
4340
4391
|
/** Calls `listener` after every change. Returns an unsubscribe function. */
|
|
4341
|
-
|
|
4392
|
+
__init34() {this.subscribe = (listener) => {
|
|
4342
4393
|
this.listeners.add(listener);
|
|
4343
4394
|
return () => {
|
|
4344
4395
|
this.listeners.delete(listener);
|
|
@@ -4357,7 +4408,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
4357
4408
|
tool: this.tool,
|
|
4358
4409
|
selection: this.selection,
|
|
4359
4410
|
selectedAnchors: this.anchors,
|
|
4360
|
-
|
|
4411
|
+
selectedWidthPoints: this.widthPoints,
|
|
4412
|
+
widthPointEdit: this.widthEdit,
|
|
4361
4413
|
editingId: this.editingId,
|
|
4362
4414
|
selectionBounds: this.boundsOf(this.selection),
|
|
4363
4415
|
selectionFrame: this.frameOf(this.selectedRoots()),
|
|
@@ -4383,7 +4435,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4383
4435
|
notify(docChanged = false) {
|
|
4384
4436
|
this.revision++;
|
|
4385
4437
|
this.state = this.computeState();
|
|
4386
|
-
if (docChanged) _optionalChain([this, 'access',
|
|
4438
|
+
if (docChanged) _optionalChain([this, 'access', _84 => _84.onChange, 'optionalCall', _85 => _85(this.doc)]);
|
|
4387
4439
|
const state = this.state;
|
|
4388
4440
|
this.listeners.forEach((listener) => {
|
|
4389
4441
|
try {
|
|
@@ -4413,26 +4465,26 @@ var VectorEditorController = (_class3 = class {
|
|
|
4413
4465
|
return applyMatrix(invertMatrix(this.worldOf(id, doc)), p);
|
|
4414
4466
|
}
|
|
4415
4467
|
cursorFor() {
|
|
4416
|
-
if (_optionalChain([this, 'access',
|
|
4417
|
-
if (_optionalChain([this, 'access',
|
|
4418
|
-
if (_optionalChain([this, 'access',
|
|
4468
|
+
if (_optionalChain([this, 'access', _86 => _86.drag, 'optionalAccess', _87 => _87.kind]) === "pan" || this.spaceHeld) return this.drag ? "grabbing" : "grab";
|
|
4469
|
+
if (_optionalChain([this, 'access', _88 => _88.drag, 'optionalAccess', _89 => _89.kind]) === "rotate") return "grabbing";
|
|
4470
|
+
if (_optionalChain([this, 'access', _90 => _90.drag, 'optionalAccess', _91 => _91.kind]) === "move") return "move";
|
|
4419
4471
|
const h = this.hover;
|
|
4420
4472
|
switch (this.tool) {
|
|
4421
4473
|
case "select":
|
|
4422
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
4423
|
-
return _optionalChain([h, 'optionalAccess',
|
|
4474
|
+
if (_optionalChain([h, 'optionalAccess', _92 => _92.transformHandle])) return vectorResizeCursor(h.transformHandle, _nullishCoalesce(_optionalChain([this, 'access', _93 => _93.frameOf, 'call', _94 => _94(this.selectedRoots()), 'optionalAccess', _95 => _95.angle]), () => ( 0)));
|
|
4475
|
+
return _optionalChain([h, 'optionalAccess', _96 => _96.nodeId]) ? "move" : "default";
|
|
4424
4476
|
case "direct":
|
|
4425
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
4426
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
4427
|
-
return _optionalChain([h, 'optionalAccess',
|
|
4477
|
+
if (_optionalChain([h, 'optionalAccess', _97 => _97.anchor]) || _optionalChain([h, 'optionalAccess', _98 => _98.handle]) || _optionalChain([h, 'optionalAccess', _99 => _99.corner])) return "pointer";
|
|
4478
|
+
if (_optionalChain([h, 'optionalAccess', _100 => _100.segment])) return "copy";
|
|
4479
|
+
return _optionalChain([h, 'optionalAccess', _101 => _101.nodeId]) ? "move" : "default";
|
|
4428
4480
|
case "pen":
|
|
4429
|
-
return _optionalChain([h, 'optionalAccess',
|
|
4481
|
+
return _optionalChain([h, 'optionalAccess', _102 => _102.anchor]) ? "pointer" : "crosshair";
|
|
4430
4482
|
case "width":
|
|
4431
|
-
if (_optionalChain([this, 'access',
|
|
4432
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
4433
|
-
return _optionalChain([h, 'optionalAccess',
|
|
4483
|
+
if (_optionalChain([this, 'access', _103 => _103.drag, 'optionalAccess', _104 => _104.kind]) === "width") return this.drag.mode === "width" ? "ew-resize" : "grabbing";
|
|
4484
|
+
if (_optionalChain([h, 'optionalAccess', _105 => _105.widthPoint])) return h.widthPoint.part === "center" ? "grab" : "ew-resize";
|
|
4485
|
+
return _optionalChain([h, 'optionalAccess', _106 => _106.strokeSpot]) ? "copy" : "default";
|
|
4434
4486
|
case "shapeBuilder":
|
|
4435
|
-
if (!_optionalChain([this, 'access',
|
|
4487
|
+
if (!_optionalChain([this, 'access', _107 => _107.builderPreview, 'optionalAccess', _108 => _108.faces, 'access', _109 => _109.length]) && !_optionalChain([this, 'access', _110 => _110.builderPreview, 'optionalAccess', _111 => _111.lines, 'access', _112 => _112.length])) return "crosshair";
|
|
4436
4488
|
return this.builderPreview.mode === "erase" ? "not-allowed" : "cell";
|
|
4437
4489
|
case "paintBucket":
|
|
4438
4490
|
return this.builderPreview ? "cell" : "crosshair";
|
|
@@ -4448,6 +4500,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4448
4500
|
}
|
|
4449
4501
|
restore(s) {
|
|
4450
4502
|
const docChanged = s.doc !== this.doc || this.committing;
|
|
4503
|
+
if (!this.committing) this.widthEdit = null;
|
|
4451
4504
|
this.committing = false;
|
|
4452
4505
|
this.applying = true;
|
|
4453
4506
|
try {
|
|
@@ -4455,7 +4508,14 @@ var VectorEditorController = (_class3 = class {
|
|
|
4455
4508
|
this.selection = s.selection.filter((id) => this.getNode(id));
|
|
4456
4509
|
this.anchors = s.anchors.filter((r) => getAnchor(this.doc, r));
|
|
4457
4510
|
this.editingId = s.editingId && this.getNode(s.editingId) ? s.editingId : null;
|
|
4458
|
-
this.pen = s.pen && _optionalChain([this, 'access',
|
|
4511
|
+
this.pen = s.pen && _optionalChain([this, 'access', _113 => _113.getNode, 'call', _114 => _114(s.pen.nodeId), 'optionalAccess', _115 => _115.subpaths, 'optionalAccess', _116 => _116[s.pen.subpath]]) ? s.pen : null;
|
|
4512
|
+
if (this.widthPoints.length) {
|
|
4513
|
+
const kept = this.widthPoints.filter((r) => {
|
|
4514
|
+
const n = this.getNode(r.nodeId);
|
|
4515
|
+
return _optionalChain([n, 'optionalAccess', _117 => _117.type]) === "path" && !!_optionalChain([n, 'access', _118 => _118.strokeWidthProfile, 'optionalAccess', _119 => _119[r.index]]);
|
|
4516
|
+
});
|
|
4517
|
+
if (kept.length !== this.widthPoints.length) this.widthPoints = kept;
|
|
4518
|
+
}
|
|
4459
4519
|
} finally {
|
|
4460
4520
|
this.applying = false;
|
|
4461
4521
|
}
|
|
@@ -4561,7 +4621,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
4561
4621
|
this.tool = tool;
|
|
4562
4622
|
this.hover = null;
|
|
4563
4623
|
this.guides = null;
|
|
4564
|
-
this.
|
|
4624
|
+
this.widthPoints = [];
|
|
4625
|
+
this.widthEdit = null;
|
|
4565
4626
|
this.builderPreview = null;
|
|
4566
4627
|
this.builderHoverKey = null;
|
|
4567
4628
|
if (tool !== "direct") {
|
|
@@ -4622,7 +4683,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4622
4683
|
if (res.kind) {
|
|
4623
4684
|
this.snappedToObject = true;
|
|
4624
4685
|
this.setGuides(res);
|
|
4625
|
-
return _optionalChain([leave, 'optionalAccess',
|
|
4686
|
+
return _optionalChain([leave, 'optionalAccess', _120 => _120.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) };
|
|
4626
4687
|
}
|
|
4627
4688
|
}
|
|
4628
4689
|
this.setGuides(null);
|
|
@@ -4640,14 +4701,14 @@ var VectorEditorController = (_class3 = class {
|
|
|
4640
4701
|
/** Where the pointer at `p` would place a point with the pen or a shape tool (and the guides showing why). */
|
|
4641
4702
|
hoverSnap(p, input) {
|
|
4642
4703
|
if (this.tool === "pen") {
|
|
4643
|
-
const sp = this.pen ? _optionalChain([this, 'access',
|
|
4644
|
-
if (this.pen && sp && _optionalChain([this, 'access',
|
|
4704
|
+
const sp = this.pen ? _optionalChain([this, 'access', _121 => _121.getNode, 'call', _122 => _122(this.pen.nodeId), 'optionalAccess', _123 => _123.subpaths, 'access', _124 => _124[this.pen.subpath]]) : void 0;
|
|
4705
|
+
if (this.pen && sp && _optionalChain([this, 'access', _125 => _125.hover, 'optionalAccess', _126 => _126.anchor])) {
|
|
4645
4706
|
this.setGuides(null);
|
|
4646
4707
|
return p;
|
|
4647
4708
|
}
|
|
4648
4709
|
const last = this.pen && sp ? getAnchorWorld(this.doc, { nodeId: this.pen.nodeId, subpath: this.pen.subpath, index: sp.anchors.length - 1 }) : void 0;
|
|
4649
4710
|
const leave = last ? { at: { x: last.x, y: last.y }, constrain: input.shift ? "angle" : null } : null;
|
|
4650
|
-
return this.snapDrawn(p, leave, input, () => this.drawingTargets(_nullishCoalesce(_optionalChain([this, 'access',
|
|
4711
|
+
return this.snapDrawn(p, leave, input, () => this.drawingTargets(_nullishCoalesce(_optionalChain([this, 'access', _127 => _127.pen, 'optionalAccess', _128 => _128.nodeId]), () => ( null))));
|
|
4651
4712
|
}
|
|
4652
4713
|
if (SHAPE_TOOLS.has(this.tool)) return this.snapDrawn(p, null, input, () => this.drawingTargets(null));
|
|
4653
4714
|
this.setGuides(null);
|
|
@@ -4795,7 +4856,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4795
4856
|
if (d.fillRule) out.fillRule = d.fillRule;
|
|
4796
4857
|
if (d.strokeAlign && d.strokeAlign !== "center") out.strokeAlign = d.strokeAlign;
|
|
4797
4858
|
for (const key of ["startArrow", "endArrow", "arrowAlign", "startArrowScale", "endArrowScale"]) if (d[key]) out[key] = d[key];
|
|
4798
|
-
if (_optionalChain([d, 'access',
|
|
4859
|
+
if (_optionalChain([d, 'access', _129 => _129.strokeWidthProfile, 'optionalAccess', _130 => _130.length])) out.strokeWidthProfile = d.strokeWidthProfile.map((p) => ({ ...p }));
|
|
4799
4860
|
return out;
|
|
4800
4861
|
}
|
|
4801
4862
|
/** Merges `patch` into a node (paths take style and geometry; groups name / visibility / opacity). */
|
|
@@ -4837,18 +4898,143 @@ var VectorEditorController = (_class3 = class {
|
|
|
4837
4898
|
const p = profile;
|
|
4838
4899
|
points = p.taper || p.wave ? generateWidthProfile(p) : [];
|
|
4839
4900
|
}
|
|
4840
|
-
this.
|
|
4901
|
+
this.widthPoints = [];
|
|
4902
|
+
this.widthEdit = null;
|
|
4841
4903
|
return this.setStyle({ strokeWidthProfile: points.length ? points : null }, _nullishCoalesce(options.ids, () => ( this.selection)), { label: points.length ? "Width Profile" : "Uniform Width" });
|
|
4842
4904
|
}
|
|
4843
|
-
/** Removes one width point of a path's profile
|
|
4905
|
+
/** Removes one width point of a path's profile. */
|
|
4844
4906
|
removeWidthPoint(ref) {
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4907
|
+
return this.removeWidthPoints([ref]);
|
|
4908
|
+
}
|
|
4909
|
+
/** Removes width points (default: the selected ones — the width tool's Delete), as one undo step. */
|
|
4910
|
+
removeWidthPoints(refs = this.widthPoints) {
|
|
4911
|
+
const byNode = /* @__PURE__ */ new Map();
|
|
4912
|
+
for (const r of refs) {
|
|
4913
|
+
const node = this.getNode(r.nodeId);
|
|
4914
|
+
if (_optionalChain([node, 'optionalAccess', _131 => _131.type]) !== "path" || !_optionalChain([node, 'access', _132 => _132.strokeWidthProfile, 'optionalAccess', _133 => _133[r.index]])) continue;
|
|
4915
|
+
byNode.set(r.nodeId, [..._nullishCoalesce(byNode.get(r.nodeId), () => ( [])), r.index]);
|
|
4916
|
+
}
|
|
4917
|
+
if (!byNode.size) return { ok: false, message: "There is no such width point." };
|
|
4918
|
+
const count = [...byNode.values()].reduce((n, l) => n + new Set(l).size, 0);
|
|
4919
|
+
this.widthPoints = [];
|
|
4920
|
+
this.widthEdit = null;
|
|
4921
|
+
this.change(count > 1 ? "Delete Width Points" : "Delete Width Point", () => {
|
|
4922
|
+
for (const [id, indices] of byNode) {
|
|
4923
|
+
const node = this.getNode(id);
|
|
4924
|
+
const rest = removeWidthPoints(sanitizeWidthProfile(node.strokeWidthProfile), indices);
|
|
4925
|
+
this.replaceNode(id, withStyle(node, { strokeWidthProfile: rest.length ? rest : null }));
|
|
4926
|
+
}
|
|
4927
|
+
});
|
|
4850
4928
|
return { ok: true };
|
|
4851
4929
|
}
|
|
4930
|
+
/** Selects width points (width tool); points on other paths than the first are dropped. */
|
|
4931
|
+
selectWidthPoints(refs) {
|
|
4932
|
+
const first = _optionalChain([refs, 'access', _134 => _134[0], 'optionalAccess', _135 => _135.nodeId]);
|
|
4933
|
+
const next = [];
|
|
4934
|
+
for (const r of refs) {
|
|
4935
|
+
if (r.nodeId !== first || next.some((q) => q.index === r.index)) continue;
|
|
4936
|
+
const n = this.getNode(r.nodeId);
|
|
4937
|
+
if (_optionalChain([n, 'optionalAccess', _136 => _136.type]) === "path" && _optionalChain([n, 'access', _137 => _137.strokeWidthProfile, 'optionalAccess', _138 => _138[r.index]])) next.push({ nodeId: r.nodeId, index: r.index, subpath: _nullishCoalesce(r.subpath, () => ( 0)) });
|
|
4938
|
+
}
|
|
4939
|
+
this.widthPoints = next;
|
|
4940
|
+
this.notify();
|
|
4941
|
+
}
|
|
4942
|
+
/**
|
|
4943
|
+
* Sets one width point numerically: `index` names an existing point of path `nodeId`, null
|
|
4944
|
+
* (or left out) adds one at `values.t`. `left` / `right` are side widths in document units
|
|
4945
|
+
* (how far the stroke reaches on each side of the path), `t` the position along each subpath
|
|
4946
|
+
* (0–1). A point moved onto another one's `t` makes a step there. Selects the point and
|
|
4947
|
+
* refreshes an open width-point editor; one undo step. Ported from ArtCraft vectorcraft's
|
|
4948
|
+
* Width Point Edit dialog (`crates/tools/src/distort/width.rs`, MIT OR Apache-2.0).
|
|
4949
|
+
*/
|
|
4950
|
+
setWidthPoint(target, values) {
|
|
4951
|
+
const node = this.getNode(target.nodeId);
|
|
4952
|
+
if (_optionalChain([node, 'optionalAccess', _139 => _139.type]) !== "path") return { ok: false, message: "There is no such path." };
|
|
4953
|
+
const g = vectorStrokeWidthGeometry(node);
|
|
4954
|
+
if (!g || !(g.unit > 0)) return { ok: false, message: "The path has no visible stroke." };
|
|
4955
|
+
const num = (v2) => typeof v2 === "number" && Number.isFinite(v2) ? v2 : void 0;
|
|
4956
|
+
const t = num(values.t);
|
|
4957
|
+
const left = num(values.left);
|
|
4958
|
+
const right = num(values.right);
|
|
4959
|
+
const scale = (w) => w === void 0 ? void 0 : Math.max(0, w) / g.unit;
|
|
4960
|
+
const profile = sanitizeWidthProfile(node.strokeWidthProfile);
|
|
4961
|
+
let points;
|
|
4962
|
+
let index;
|
|
4963
|
+
const existing = _nullishCoalesce(target.index, () => ( null));
|
|
4964
|
+
if (existing === null) {
|
|
4965
|
+
if (t === void 0) return { ok: false, message: "A new width point needs a position t." };
|
|
4966
|
+
if (profile.length >= VECTOR_WIDTH_PROFILE_MAX_POINTS) return { ok: false, message: "The profile has too many width points." };
|
|
4967
|
+
({ points, index } = insertWidthPoint(profile.length ? profile : null, t, { left: scale(left), right: scale(right) }, { step: true }));
|
|
4968
|
+
} else {
|
|
4969
|
+
const p = profile[existing];
|
|
4970
|
+
if (!p) return { ok: false, message: "There is no such width point." };
|
|
4971
|
+
const sides2 = { left: _nullishCoalesce(scale(left), () => ( p.left)), right: _nullishCoalesce(scale(right), () => ( p.right)) };
|
|
4972
|
+
const tt = t === void 0 ? p.t : Math.min(Math.max(t, 0), 1);
|
|
4973
|
+
if (Math.abs(tt - p.t) <= VECTOR_WIDTH_SAME_T) {
|
|
4974
|
+
points = setWidthPoint(profile, existing, sides2);
|
|
4975
|
+
index = existing;
|
|
4976
|
+
} else {
|
|
4977
|
+
const rest = removeWidthPoints(profile, [existing]);
|
|
4978
|
+
if (rest.length) ({ points, index } = insertWidthPoint(rest, tt, sides2, { step: true }));
|
|
4979
|
+
else {
|
|
4980
|
+
points = [{ t: tt, ...sides2 }];
|
|
4981
|
+
index = 0;
|
|
4982
|
+
}
|
|
4983
|
+
}
|
|
4984
|
+
}
|
|
4985
|
+
const subpath = _optionalChain([this, 'access', _140 => _140.widthEdit, 'optionalAccess', _141 => _141.nodeId]) === node.id ? this.widthEdit.subpath : _nullishCoalesce(_optionalChain([this, 'access', _142 => _142.widthPoints, 'access', _143 => _143.find, 'call', _144 => _144((r) => r.nodeId === node.id), 'optionalAccess', _145 => _145.subpath]), () => ( 0));
|
|
4986
|
+
const edit = this.widthEdit;
|
|
4987
|
+
this.change("Width Point", () => this.replaceNode(node.id, withStyle(node, { strokeWidthProfile: points })));
|
|
4988
|
+
this.widthPoints = [{ nodeId: node.id, index, subpath }];
|
|
4989
|
+
if (_optionalChain([edit, 'optionalAccess', _146 => _146.nodeId]) === node.id && (edit.index === existing || existing === null)) this.widthEdit = this.widthEditFor(node.id, subpath, index, null);
|
|
4990
|
+
this.notify();
|
|
4991
|
+
return { ok: true };
|
|
4992
|
+
}
|
|
4993
|
+
/**
|
|
4994
|
+
* Opens the width-point editor (what a double-click with the width tool does) on a width
|
|
4995
|
+
* point, or on a spot of a stroke (`t` without `index`: applying it adds a point there).
|
|
4996
|
+
* Returns false when the path has no visible stroke.
|
|
4997
|
+
*/
|
|
4998
|
+
openWidthPointEdit(target) {
|
|
4999
|
+
const edit = this.widthEditFor(target.nodeId, _nullishCoalesce(target.subpath, () => ( 0)), _nullishCoalesce(target.index, () => ( null)), _nullishCoalesce(target.t, () => ( null)));
|
|
5000
|
+
if (!edit) return false;
|
|
5001
|
+
this.widthEdit = edit;
|
|
5002
|
+
this.widthPoints = edit.index === null ? [] : [{ nodeId: edit.nodeId, index: edit.index, subpath: edit.subpath }];
|
|
5003
|
+
this.notify();
|
|
5004
|
+
return true;
|
|
5005
|
+
}
|
|
5006
|
+
/** Closes the width-point editor without changing anything. */
|
|
5007
|
+
closeWidthPointEdit() {
|
|
5008
|
+
if (!this.widthEdit) return;
|
|
5009
|
+
this.widthEdit = null;
|
|
5010
|
+
this.notify();
|
|
5011
|
+
}
|
|
5012
|
+
/** Applies `values` to the width point being edited (see `setWidthPoint`) and closes the editor. */
|
|
5013
|
+
commitWidthPointEdit(values) {
|
|
5014
|
+
const edit = this.widthEdit;
|
|
5015
|
+
if (!edit) return { ok: false, message: "No width point is being edited." };
|
|
5016
|
+
const r = this.setWidthPoint({ nodeId: edit.nodeId, index: edit.index }, edit.index === null ? { t: edit.t, ...values } : values);
|
|
5017
|
+
if (r.ok) this.closeWidthPointEdit();
|
|
5018
|
+
return r;
|
|
5019
|
+
}
|
|
5020
|
+
/** The editor's view of point `index` (or of the stroke at `t` when index is null) of `nodeId`. */
|
|
5021
|
+
widthEditFor(nodeId, subpath, index, t) {
|
|
5022
|
+
const node = this.getNode(nodeId);
|
|
5023
|
+
if (_optionalChain([node, 'optionalAccess', _147 => _147.type]) !== "path") return null;
|
|
5024
|
+
const g = vectorStrokeWidthGeometry(node);
|
|
5025
|
+
if (!g) return null;
|
|
5026
|
+
const profile = sanitizeWidthProfile(node.strokeWidthProfile);
|
|
5027
|
+
const p = index === null ? null : profile[index];
|
|
5028
|
+
if (index !== null && !p) return null;
|
|
5029
|
+
const tt = p ? p.t : Math.min(Math.max(_nullishCoalesce(t, () => ( 0)), 0), 1);
|
|
5030
|
+
const sides2 = _nullishCoalesce(p, () => ( widthProfileAt(profile.length ? profile : null, tt)));
|
|
5031
|
+
const sp = Math.min(Math.max(0, subpath), Math.max(0, node.subpaths.length - 1));
|
|
5032
|
+
const at2 = strokePositionPoint(g.line, sp, tt);
|
|
5033
|
+
const round = (v2) => Math.round(v2 * 1e6) / 1e6;
|
|
5034
|
+
const q = at2 ? applyMatrix(this.worldOf(nodeId), { x: at2.point[0], y: at2.point[1] }) : { x: 0, y: 0 };
|
|
5035
|
+
const point = { x: round(q.x), y: round(q.y) };
|
|
5036
|
+
return { nodeId, subpath: sp, index, t: round(tt), left: round(sides2.left * g.unit), right: round(sides2.right * g.unit), point };
|
|
5037
|
+
}
|
|
4852
5038
|
/**
|
|
4853
5039
|
* Sets the live corner radius (and optionally the kind) of anchors: `refs`, else the selected
|
|
4854
5040
|
* anchors (direct tool), else every anchor of the `ids` / selected paths. Radius 0 makes the
|
|
@@ -4868,7 +5054,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4868
5054
|
const refs = this.cornerTargets(options);
|
|
4869
5055
|
if (!refs.length) return { ok: false, message: "Nothing is selected." };
|
|
4870
5056
|
this.change("Corner Kind", () => {
|
|
4871
|
-
this.doc = this.updateAnchors(this.doc, refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access',
|
|
5057
|
+
this.doc = this.updateAnchors(this.doc, refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access', _148 => _148.corner, 'optionalAccess', _149 => _149.radius]), () => ( 0)), kind));
|
|
4872
5058
|
});
|
|
4873
5059
|
return { ok: true };
|
|
4874
5060
|
}
|
|
@@ -5007,10 +5193,10 @@ var VectorEditorController = (_class3 = class {
|
|
|
5007
5193
|
return this.selection.filter((id) => {
|
|
5008
5194
|
let covered = false;
|
|
5009
5195
|
const loc = locateVectorNode(this.doc.nodes, id);
|
|
5010
|
-
let parent = _nullishCoalesce(_optionalChain([loc, 'optionalAccess',
|
|
5196
|
+
let parent = _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _150 => _150.parent]), () => ( null));
|
|
5011
5197
|
while (parent) {
|
|
5012
5198
|
if (this.selection.includes(parent.id)) covered = true;
|
|
5013
|
-
parent = _nullishCoalesce(_optionalChain([locateVectorNode, 'call',
|
|
5199
|
+
parent = _nullishCoalesce(_optionalChain([locateVectorNode, 'call', _151 => _151(this.doc.nodes, parent.id), 'optionalAccess', _152 => _152.parent]), () => ( null));
|
|
5014
5200
|
}
|
|
5015
5201
|
return !covered;
|
|
5016
5202
|
});
|
|
@@ -5193,8 +5379,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
5193
5379
|
if (!ids.length) return null;
|
|
5194
5380
|
const locs = ids.map((id2) => locateVectorNode(this.doc.nodes, id2));
|
|
5195
5381
|
if (locs.some((l) => !l)) return null;
|
|
5196
|
-
const parent = _nullishCoalesce(_optionalChain([locs, 'access',
|
|
5197
|
-
if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access',
|
|
5382
|
+
const parent = _nullishCoalesce(_optionalChain([locs, 'access', _153 => _153[0], 'access', _154 => _154.parent, 'optionalAccess', _155 => _155.id]), () => ( null));
|
|
5383
|
+
if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access', _156 => _156.parent, 'optionalAccess', _157 => _157.id]), () => ( null))) !== parent)) return null;
|
|
5198
5384
|
const id = this.newId();
|
|
5199
5385
|
this.change("Group", () => {
|
|
5200
5386
|
const set = new Set(ids);
|
|
@@ -5217,7 +5403,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5217
5403
|
}
|
|
5218
5404
|
/** Replaces selected groups with their children. */
|
|
5219
5405
|
ungroup(options = {}) {
|
|
5220
|
-
const groups = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess',
|
|
5406
|
+
const groups = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess', _158 => _158.type]) === "group");
|
|
5221
5407
|
if (!groups.length) return { ok: false, message: "Select a group to ungroup." };
|
|
5222
5408
|
const set = new Set(groups.map((g) => g.id));
|
|
5223
5409
|
this.change("Ungroup", () => {
|
|
@@ -5277,7 +5463,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5277
5463
|
});
|
|
5278
5464
|
const paths = [...new Set(order)].map((id2) => this.getNode(id2));
|
|
5279
5465
|
if (paths.length < 2) return null;
|
|
5280
|
-
const result =
|
|
5466
|
+
const result = _chunkVNYRI265cjs.pathBoolean.call(void 0,
|
|
5281
5467
|
BOOLEAN_OPS[op],
|
|
5282
5468
|
paths.map((p) => ({
|
|
5283
5469
|
path: vectorPathWorldBezier(
|
|
@@ -5327,11 +5513,11 @@ var VectorEditorController = (_class3 = class {
|
|
|
5327
5513
|
/** A document-space path mapped into the parent space of node `id`. */
|
|
5328
5514
|
intoParentSpace(id, path) {
|
|
5329
5515
|
const parent = _nullishCoalesce(vectorParentMatrix(this.doc.nodes, id), () => ( IDENTITY_MATRIX));
|
|
5330
|
-
return isRoot(parent) ? path :
|
|
5516
|
+
return isRoot(parent) ? path : _chunkVNYRI265cjs.transformBezierPath.call(void 0, path, invertMatrix(parent));
|
|
5331
5517
|
}
|
|
5332
5518
|
/** Splits selected compound paths into one path per subpath. */
|
|
5333
5519
|
breakApart(options = {}) {
|
|
5334
|
-
const paths = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess',
|
|
5520
|
+
const paths = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess', _159 => _159.type]) === "path" && n.subpaths.length > 1);
|
|
5335
5521
|
if (!paths.length) return { ok: false, message: "Select a compound path to break apart." };
|
|
5336
5522
|
const created = [];
|
|
5337
5523
|
const set = new Set(paths.map((p) => p.id));
|
|
@@ -5366,7 +5552,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5366
5552
|
const entries = vectorPathEntries(this.doc, roots);
|
|
5367
5553
|
if (entries.length < (op === "divide" || op === "outline" ? 1 : 2)) return [];
|
|
5368
5554
|
const shapes = entries.map((e) => vectorPathfinderShape(e, op));
|
|
5369
|
-
const result =
|
|
5555
|
+
const result = _chunkVNYRI265cjs.pathfinder.call(void 0, op, shapes);
|
|
5370
5556
|
if (result.error || !result.pieces.length) return [];
|
|
5371
5557
|
const last = entries[entries.length - 1].node.id;
|
|
5372
5558
|
const topRoot = _nullishCoalesce([...roots].reverse().find((r) => {
|
|
@@ -5397,7 +5583,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5397
5583
|
shapeBuilderMap(ids) {
|
|
5398
5584
|
const roots = _nullishCoalesce(ids, () => ( this.selectedRoots()));
|
|
5399
5585
|
const key = roots.join("\0");
|
|
5400
|
-
if (_optionalChain([this, 'access',
|
|
5586
|
+
if (_optionalChain([this, 'access', _160 => _160.builderCache, 'optionalAccess', _161 => _161.doc]) === this.doc && this.builderCache.key === key) return this.builderCache.map;
|
|
5401
5587
|
const entries = roots.length ? vectorPathEntries(this.doc, roots) : [];
|
|
5402
5588
|
const map = entries.length ? vectorShapeBuilderMap(entries) : null;
|
|
5403
5589
|
this.builderCache = { doc: this.doc, key, map };
|
|
@@ -5411,7 +5597,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5411
5597
|
const p = m.map.faceInterior(index);
|
|
5412
5598
|
return {
|
|
5413
5599
|
index,
|
|
5414
|
-
d:
|
|
5600
|
+
d: _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, f.path, { precision: 3 }),
|
|
5415
5601
|
area: f.area,
|
|
5416
5602
|
sources: m.map.faceSources(index).map((i) => m.entries[i].node.id),
|
|
5417
5603
|
point: p ? { x: p[0], y: p[1] } : null
|
|
@@ -5426,20 +5612,23 @@ var VectorEditorController = (_class3 = class {
|
|
|
5426
5612
|
* Shape Builder gesture along `points` (document units; one point is a click) over the faces
|
|
5427
5613
|
* the selected (or given) paths make. Merges the faces touched into one shape styled like the
|
|
5428
5614
|
* top-most shape over the first face (the current fill for a face only outlines enclose);
|
|
5429
|
-
* with `erase` deletes them,
|
|
5430
|
-
*
|
|
5615
|
+
* with `erase` deletes them, the pieces of unfilled open paths and the edges of other outlines
|
|
5616
|
+
* (cut where paths meet) within `tolerance`: a deleted edge opens a closed subpath there,
|
|
5617
|
+
* splits an open one or takes a subpath it runs all the way round, and edges bounding a face
|
|
5618
|
+
* deleted in the same gesture go with the face. Every shape covering a touched face loses
|
|
5619
|
+
* that area; paths keep their own transforms. One undo step.
|
|
5431
5620
|
*/
|
|
5432
5621
|
shapeBuilder(points, options = {}) {
|
|
5433
|
-
const none = (message) => ({ ok: false, message, merged: null, faces: 0, lines: 0 });
|
|
5622
|
+
const none = (message) => ({ ok: false, message, merged: null, faces: 0, lines: 0, edges: 0 });
|
|
5434
5623
|
if (!points.length || !points.every((p) => Number.isFinite(p.x) && Number.isFinite(p.y))) return none("Give the points of the gesture.");
|
|
5435
5624
|
const m = this.shapeBuilderMap(options.ids);
|
|
5436
5625
|
if (!m) return none("Select paths that make faces.");
|
|
5437
5626
|
const erase = !!options.erase;
|
|
5438
5627
|
const tol = erase ? _nullishCoalesce(options.tolerance, () => ( this.builderLineTolerance())) : null;
|
|
5439
|
-
const touched = { faces: [], lines: [] };
|
|
5628
|
+
const touched = { faces: [], lines: [], edges: [] };
|
|
5440
5629
|
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
5630
|
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.");
|
|
5631
|
+
if (!touched.faces.length && !touched.lines.length && !touched.edges.length) return none("There is no face under the pointer.");
|
|
5443
5632
|
return this.applyShapeBuilder(m, touched, erase);
|
|
5444
5633
|
}
|
|
5445
5634
|
applyShapeBuilder(m, touched, erase) {
|
|
@@ -5450,12 +5639,13 @@ var VectorEditorController = (_class3 = class {
|
|
|
5450
5639
|
let nodes = this.doc.nodes;
|
|
5451
5640
|
m.entries.forEach((entry, i) => {
|
|
5452
5641
|
const node = entry.node;
|
|
5453
|
-
const toLocal = (path) =>
|
|
5642
|
+
const toLocal = (path) => _chunkVNYRI265cjs.transformBezierPath.call(void 0, path, invertMatrix(multiplyMatrices(nodeMatrix(node), entry.parent)));
|
|
5454
5643
|
const list = [];
|
|
5455
5644
|
const r = plan.replace.get(i);
|
|
5456
5645
|
if (r === void 0) list.push(node);
|
|
5457
|
-
else if (_optionalChain([r, 'optionalAccess',
|
|
5458
|
-
else if (_optionalChain([r, 'optionalAccess',
|
|
5646
|
+
else if (_optionalChain([r, 'optionalAccess', _162 => _162.kind]) === "fill") list.push({ ...node, fillRule: "nonzero", subpaths: bezierToSubpaths(toLocal(r.path)) });
|
|
5647
|
+
else if (_optionalChain([r, 'optionalAccess', _163 => _163.kind]) === "outline") list.push({ ...node, subpaths: bezierToSubpaths(toLocal(r.path)) });
|
|
5648
|
+
else if (_optionalChain([r, 'optionalAccess', _164 => _164.kind]) === "pieces") {
|
|
5459
5649
|
r.paths.forEach(
|
|
5460
5650
|
(path, k) => list.push({ ...node, id: k === 0 ? node.id : this.newId(), subpaths: bezierToSubpaths(toLocal(path)).map((sp) => ({ ...sp, closed: false })) })
|
|
5461
5651
|
);
|
|
@@ -5485,11 +5675,11 @@ var VectorEditorController = (_class3 = class {
|
|
|
5485
5675
|
this.editingId = null;
|
|
5486
5676
|
});
|
|
5487
5677
|
this.builderCache = null;
|
|
5488
|
-
return { ok: true, merged: mergedId, faces: touched.faces.length, lines: touched.lines.length };
|
|
5678
|
+
return { ok: true, merged: mergedId, faces: touched.faces.length, lines: touched.lines.length, edges: erase ? vectorBuilderErasedEdges(m, touched).length : 0 };
|
|
5489
5679
|
}
|
|
5490
5680
|
/** The paint bucket's map of the visible outlines, cached per document and gap. */
|
|
5491
5681
|
fillMap(gap) {
|
|
5492
|
-
if (_optionalChain([this, 'access',
|
|
5682
|
+
if (_optionalChain([this, 'access', _165 => _165.fillCache, 'optionalAccess', _166 => _166.doc]) === this.doc && this.fillCache.gap === gap) return this.fillCache.map;
|
|
5493
5683
|
const map = vectorFillMap(this.doc, gap);
|
|
5494
5684
|
this.fillCache = { doc: this.doc, gap, map };
|
|
5495
5685
|
return map;
|
|
@@ -5503,8 +5693,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
5503
5693
|
*/
|
|
5504
5694
|
fillRegion(point, options = {}) {
|
|
5505
5695
|
if (!Number.isFinite(point.x) || !Number.isFinite(point.y)) return null;
|
|
5506
|
-
const region = _optionalChain([this, 'access',
|
|
5507
|
-
if (!_optionalChain([region, 'optionalAccess',
|
|
5696
|
+
const region = _optionalChain([this, 'access', _167 => _167.fillMap, 'call', _168 => _168(_nullishCoalesce(options.gap, () => ( this.editing.fillGap))), 'optionalAccess', _169 => _169.regionAt, 'call', _170 => _170([point.x, point.y])]);
|
|
5697
|
+
if (!_optionalChain([region, 'optionalAccess', _171 => _171.length])) return null;
|
|
5508
5698
|
let below = null;
|
|
5509
5699
|
const roots = new Set(this.selectedRoots());
|
|
5510
5700
|
walkVectorNodes(this.doc.nodes, (n) => {
|
|
@@ -5530,8 +5720,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
5530
5720
|
/** Updates the Shape Builder / paint bucket highlight for the pointer at `p`; true when it changed. */
|
|
5531
5721
|
hoverBuilder(p, alt) {
|
|
5532
5722
|
if (this.tool === "paintBucket") {
|
|
5533
|
-
const region = _nullishCoalesce(_optionalChain([this, 'access',
|
|
5534
|
-
const key2 = region ?
|
|
5723
|
+
const region = _nullishCoalesce(_optionalChain([this, 'access', _172 => _172.fillMap, 'call', _173 => _173(this.editing.fillGap), 'optionalAccess', _174 => _174.regionAt, 'call', _175 => _175([p.x, p.y])]), () => ( null));
|
|
5724
|
+
const key2 = region ? _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, region, { precision: 2 }) : null;
|
|
5535
5725
|
if (key2 === this.builderHoverKey) return false;
|
|
5536
5726
|
this.builderHoverKey = key2;
|
|
5537
5727
|
this.builderPreview = region ? { mode: "fill", faces: [region], lines: [], trail: null } : null;
|
|
@@ -5542,7 +5732,9 @@ var VectorEditorController = (_class3 = class {
|
|
|
5542
5732
|
const key = hit ? `${alt ? "erase" : "merge"}:${JSON.stringify(hit)}` : null;
|
|
5543
5733
|
if (key === this.builderHoverKey) return false;
|
|
5544
5734
|
this.builderHoverKey = key;
|
|
5545
|
-
|
|
5735
|
+
const touched = { faces: [], lines: [], edges: [] };
|
|
5736
|
+
addBuilderHit(touched, hit);
|
|
5737
|
+
this.builderPreview = hit && m ? this.builderPreviewOf(m, touched, alt, null) : null;
|
|
5546
5738
|
return true;
|
|
5547
5739
|
}
|
|
5548
5740
|
builderPreviewOf(m, touched, erase, trail) {
|
|
@@ -5550,7 +5742,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
5550
5742
|
return {
|
|
5551
5743
|
mode: erase ? "erase" : "merge",
|
|
5552
5744
|
faces: touched.faces.map((f) => faces[f].path),
|
|
5553
|
-
|
|
5745
|
+
// Edges bounding a face touched too go with the face, so they are not shown apart.
|
|
5746
|
+
lines: [...touched.lines.map((k) => m.pieces[k].path), ...erase ? vectorBuilderErasedEdges(m, touched).map((k) => m.edges[k].path) : []],
|
|
5554
5747
|
trail
|
|
5555
5748
|
};
|
|
5556
5749
|
}
|
|
@@ -5566,7 +5759,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5566
5759
|
const m = this.selectedRoots().length ? this.shapeBuilderMap() : null;
|
|
5567
5760
|
if (!m) return;
|
|
5568
5761
|
const erase = !!input.alt;
|
|
5569
|
-
const touched = { faces: [], lines: [] };
|
|
5762
|
+
const touched = { faces: [], lines: [], edges: [] };
|
|
5570
5763
|
addBuilderHit(touched, vectorShapeBuilderHit(m, p, erase ? this.builderLineTolerance() : null));
|
|
5571
5764
|
this.drag = { kind: "builder", erase, points: [p], touched, map: m };
|
|
5572
5765
|
this.interaction = { type: "builder", mode: erase ? "erase" : "merge", points: [p] };
|
|
@@ -5586,7 +5779,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5586
5779
|
upBuilder(drag) {
|
|
5587
5780
|
this.builderPreview = null;
|
|
5588
5781
|
this.builderHoverKey = null;
|
|
5589
|
-
if (!drag.touched.faces.length && !drag.touched.lines.length) {
|
|
5782
|
+
if (!drag.touched.faces.length && !drag.touched.lines.length && !drag.touched.edges.length) {
|
|
5590
5783
|
this.notify();
|
|
5591
5784
|
return;
|
|
5592
5785
|
}
|
|
@@ -5635,7 +5828,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5635
5828
|
/** `doc` with anchor `ref` moved to document point `to` by a Curvature-tool move. */
|
|
5636
5829
|
curvatureMoved(doc, ref, to) {
|
|
5637
5830
|
const node = findVectorNode(doc.nodes, ref.nodeId);
|
|
5638
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
5831
|
+
if (_optionalChain([node, 'optionalAccess', _176 => _176.type]) !== "path" || node.locked || !node.subpaths[ref.subpath]) return doc;
|
|
5639
5832
|
const q = this.toLocal(ref.nodeId, to, doc);
|
|
5640
5833
|
const subpaths = node.subpaths.map((sp, i) => i === ref.subpath ? curvatureMoveAnchor(sp, ref.index, q) : sp);
|
|
5641
5834
|
const nodes = mapTree(doc.nodes, (n) => n.id === ref.nodeId ? { ...node, subpaths } : n);
|
|
@@ -5644,7 +5837,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5644
5837
|
/** `doc` with segment `ref` bent through document point `p` at parameter `t`. */
|
|
5645
5838
|
bent(doc, ref, t, p) {
|
|
5646
5839
|
const node = findVectorNode(doc.nodes, ref.nodeId);
|
|
5647
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
5840
|
+
if (_optionalChain([node, 'optionalAccess', _177 => _177.type]) !== "path" || node.locked || !node.subpaths[ref.subpath]) return doc;
|
|
5648
5841
|
const q = this.toLocal(ref.nodeId, p, doc);
|
|
5649
5842
|
const subpaths = node.subpaths.map((sp, i) => i === ref.subpath ? bendSegment(sp, ref.segment, t, q) : sp);
|
|
5650
5843
|
return { ...doc, nodes: mapTree(doc.nodes, (n) => n.id === ref.nodeId ? { ...node, subpaths } : n) };
|
|
@@ -5655,7 +5848,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5655
5848
|
*/
|
|
5656
5849
|
bendSegment(ref, to, t = 0.5) {
|
|
5657
5850
|
const node = this.getNode(ref.nodeId);
|
|
5658
|
-
const sp = _optionalChain([node, 'optionalAccess',
|
|
5851
|
+
const sp = _optionalChain([node, 'optionalAccess', _178 => _178.type]) === "path" ? node.subpaths[ref.subpath] : void 0;
|
|
5659
5852
|
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." };
|
|
5660
5853
|
if (node.locked) return { ok: false, message: "The path is locked." };
|
|
5661
5854
|
this.change("Bend Segment", () => {
|
|
@@ -5690,7 +5883,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5690
5883
|
/** Adds an anchor on the nearest segment of `nodeId` to document point `point` (shape unchanged). */
|
|
5691
5884
|
insertAnchorAt(nodeId, point) {
|
|
5692
5885
|
const node = this.getNode(nodeId);
|
|
5693
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
5886
|
+
if (_optionalChain([node, 'optionalAccess', _179 => _179.type]) !== "path") return null;
|
|
5694
5887
|
const hit = nearestSegment(node, this.toLocal(nodeId, point));
|
|
5695
5888
|
if (!hit) return null;
|
|
5696
5889
|
const { subpath, index } = insertAnchor(node.subpaths[hit.subpath], hit.segment, hit.t);
|
|
@@ -5734,7 +5927,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5734
5927
|
setClosed(closed, nodeId) {
|
|
5735
5928
|
const targets = nodeId ? (() => {
|
|
5736
5929
|
const n = this.getNode(nodeId);
|
|
5737
|
-
return _optionalChain([n, 'optionalAccess',
|
|
5930
|
+
return _optionalChain([n, 'optionalAccess', _180 => _180.type]) === "path" ? n.subpaths.map((_, s) => ({ nodeId, subpath: s })) : [];
|
|
5738
5931
|
})() : this.anchors.map((r) => ({ nodeId: r.nodeId, subpath: r.subpath }));
|
|
5739
5932
|
if (!targets.length) return { ok: false, message: "Select a path or points." };
|
|
5740
5933
|
this.change(closed ? "Close Path" : "Open Path", () => {
|
|
@@ -5755,7 +5948,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5755
5948
|
this.setDoc(
|
|
5756
5949
|
mapTree(
|
|
5757
5950
|
this.doc.nodes,
|
|
5758
|
-
(n) => n.type === "path" && set.has(n.id) ? { ...n, subpaths: n.subpaths.map(reverseSubpath), ..._optionalChain([n, 'access',
|
|
5951
|
+
(n) => n.type === "path" && set.has(n.id) ? { ...n, subpaths: n.subpaths.map(reverseSubpath), ..._optionalChain([n, 'access', _181 => _181.strokeWidthProfile, 'optionalAccess', _182 => _182.length]) ? { strokeWidthProfile: reverseWidthProfile(n.strokeWidthProfile) } : {} } : n
|
|
5759
5952
|
)
|
|
5760
5953
|
);
|
|
5761
5954
|
this.anchors = [];
|
|
@@ -5893,7 +6086,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5893
6086
|
*/
|
|
5894
6087
|
cutPathAt(nodeId, point) {
|
|
5895
6088
|
const node = this.getNode(nodeId);
|
|
5896
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
6089
|
+
if (_optionalChain([node, 'optionalAccess', _183 => _183.type]) !== "path" || node.locked) return null;
|
|
5897
6090
|
const local = this.toLocal(nodeId, point);
|
|
5898
6091
|
const hit = nearestSegment(node, local);
|
|
5899
6092
|
if (!hit) return null;
|
|
@@ -5943,7 +6136,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5943
6136
|
if (n.visible === false || n.locked || parent && blocked.has(parent.id)) blocked.add(n.id);
|
|
5944
6137
|
});
|
|
5945
6138
|
const visible = (p) => !blocked.has(p.id);
|
|
5946
|
-
if (_optionalChain([ids, 'optionalAccess',
|
|
6139
|
+
if (_optionalChain([ids, 'optionalAccess', _184 => _184.length]) || this.selection.length) return this.pathTargets(_nullishCoalesce(ids, () => ( this.selection))).filter(visible);
|
|
5947
6140
|
const box = polylineBounds(points.map(toPoint2), pad);
|
|
5948
6141
|
if (!box) return [];
|
|
5949
6142
|
const out = [];
|
|
@@ -5999,10 +6192,10 @@ var VectorEditorController = (_class3 = class {
|
|
|
5999
6192
|
const region = eraserRegion(pts, width);
|
|
6000
6193
|
if (!region.length) return [];
|
|
6001
6194
|
const plan = [];
|
|
6002
|
-
const rb =
|
|
6195
|
+
const rb = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, region);
|
|
6003
6196
|
const reach = rb ? [{ x: rb.minX, y: rb.minY }, { x: rb.maxX, y: rb.maxY }] : points;
|
|
6004
6197
|
for (const node of this.strokeTargets(reach, options.ids, 0)) {
|
|
6005
|
-
const local =
|
|
6198
|
+
const local = _chunkVNYRI265cjs.transformBezierPath.call(void 0, region, invertMatrix(this.worldOf(node.id)));
|
|
6006
6199
|
const live = node.subpaths.filter((sp) => sp.anchors.length > 1);
|
|
6007
6200
|
if (!live.length) continue;
|
|
6008
6201
|
if (hasPaint(node.fill) && live.every((sp) => sp.closed)) {
|
|
@@ -6029,7 +6222,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
6029
6222
|
finishPath() {
|
|
6030
6223
|
if (!this.pen) return;
|
|
6031
6224
|
const node = this.getNode(this.pen.nodeId);
|
|
6032
|
-
const sp = _optionalChain([node, 'optionalAccess',
|
|
6225
|
+
const sp = _optionalChain([node, 'optionalAccess', _185 => _185.subpaths, 'access', _186 => _186[this.pen.subpath]]);
|
|
6033
6226
|
const pen = this.pen;
|
|
6034
6227
|
this.pen = null;
|
|
6035
6228
|
this.pointer = null;
|
|
@@ -6073,7 +6266,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
6073
6266
|
if (trimmed.startsWith("{")) {
|
|
6074
6267
|
try {
|
|
6075
6268
|
const data = JSON.parse(trimmed);
|
|
6076
|
-
if (_optionalChain([data, 'optionalAccess',
|
|
6269
|
+
if (_optionalChain([data, 'optionalAccess', _187 => _187.type]) === VECTOR_CLIPBOARD_TYPE && Array.isArray(data.nodes)) nodes = data.nodes;
|
|
6077
6270
|
} catch (e3) {
|
|
6078
6271
|
nodes = null;
|
|
6079
6272
|
}
|
|
@@ -6085,7 +6278,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
6085
6278
|
}
|
|
6086
6279
|
}
|
|
6087
6280
|
} else nodes = this.clipboard;
|
|
6088
|
-
if (!_optionalChain([nodes, 'optionalAccess',
|
|
6281
|
+
if (!_optionalChain([nodes, 'optionalAccess', _188 => _188.length])) return [];
|
|
6089
6282
|
const offset = _nullishCoalesce(options.offset, () => ( (text && !text.trim().startsWith("{") ? { x: 0, y: 0 } : { x: 10, y: 10 })));
|
|
6090
6283
|
const copies = nodes.map((n) => transformVectorNode(this.freshIds(n), translateMatrix(offset.x, offset.y)));
|
|
6091
6284
|
this.change("Paste", () => {
|
|
@@ -6136,7 +6329,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
6136
6329
|
hitHandle(screen) {
|
|
6137
6330
|
for (const ref of getVisibleHandles(this.view()).reverse()) {
|
|
6138
6331
|
const a = getAnchorWorld(this.doc, ref);
|
|
6139
|
-
const h = _optionalChain([a, 'optionalAccess',
|
|
6332
|
+
const h = _optionalChain([a, 'optionalAccess', _189 => _189[ref.handle]]);
|
|
6140
6333
|
if (!h) continue;
|
|
6141
6334
|
const s = this.documentToScreen(h);
|
|
6142
6335
|
if (Math.hypot(s.x - screen.x, s.y - screen.y) <= this.hitRadius) return ref;
|
|
@@ -6250,13 +6443,19 @@ var VectorEditorController = (_class3 = class {
|
|
|
6250
6443
|
}
|
|
6251
6444
|
}
|
|
6252
6445
|
widthView() {
|
|
6253
|
-
return { document: this.doc, selection: this.selection, tool: this.tool, hover: this.hover, interaction: this.interaction,
|
|
6446
|
+
return { document: this.doc, selection: this.selection, tool: this.tool, hover: this.hover, interaction: this.interaction, selectedWidthPoints: this.widthPoints };
|
|
6254
6447
|
}
|
|
6255
6448
|
/** The width point centre or side end under `screen` (width tool). */
|
|
6256
6449
|
hitWidthHandle(screen) {
|
|
6450
|
+
const shown = this.hitWidthHandleIn(screen, this.widthView());
|
|
6451
|
+
if (shown) return shown;
|
|
6452
|
+
const spot = this.strokeSpotAt(this.screenToDocument(screen));
|
|
6453
|
+
return spot && spot.nodeId !== _optionalChain([this, 'access', _190 => _190.hover, 'optionalAccess', _191 => _191.nodeId]) ? this.hitWidthHandleIn(screen, { ...this.widthView(), hover: { nodeId: spot.nodeId } }) : null;
|
|
6454
|
+
}
|
|
6455
|
+
hitWidthHandleIn(screen, view) {
|
|
6257
6456
|
let best = null;
|
|
6258
6457
|
let bestD = Infinity;
|
|
6259
|
-
for (const h of getVectorWidthHandles(
|
|
6458
|
+
for (const h of getVectorWidthHandles(view)) {
|
|
6260
6459
|
for (const [part, q] of [["center", h], ["left", h.left], ["right", h.right]]) {
|
|
6261
6460
|
const s = this.documentToScreen(q);
|
|
6262
6461
|
const d = Math.hypot(s.x - screen.x, s.y - screen.y);
|
|
@@ -6306,14 +6505,13 @@ var VectorEditorController = (_class3 = class {
|
|
|
6306
6505
|
downWidth(screen, p, input) {
|
|
6307
6506
|
const hit = this.hitWidthHandle(screen);
|
|
6308
6507
|
const spot = hit ? null : this.strokeSpotAt(p);
|
|
6309
|
-
const nodeId = _nullishCoalesce(_optionalChain([hit, 'optionalAccess',
|
|
6508
|
+
const nodeId = _nullishCoalesce(_optionalChain([hit, 'optionalAccess', _192 => _192.ref, 'access', _193 => _193.nodeId]), () => ( _optionalChain([spot, 'optionalAccess', _194 => _194.nodeId])));
|
|
6310
6509
|
const node = nodeId ? this.getNode(nodeId) : void 0;
|
|
6311
|
-
const g = _optionalChain([node, 'optionalAccess',
|
|
6510
|
+
const g = _optionalChain([node, 'optionalAccess', _195 => _195.type]) === "path" ? vectorStrokeWidthGeometry(node) : null;
|
|
6511
|
+
if (this.widthEdit) this.widthEdit = null;
|
|
6312
6512
|
if (!node || node.type !== "path" || !g) {
|
|
6313
|
-
if (
|
|
6314
|
-
|
|
6315
|
-
this.notify();
|
|
6316
|
-
}
|
|
6513
|
+
if (!input.shift) this.widthPoints = [];
|
|
6514
|
+
this.notify();
|
|
6317
6515
|
return;
|
|
6318
6516
|
}
|
|
6319
6517
|
const before = this.snapshot();
|
|
@@ -6322,15 +6520,29 @@ var VectorEditorController = (_class3 = class {
|
|
|
6322
6520
|
let ref;
|
|
6323
6521
|
let mode = "width";
|
|
6324
6522
|
let side = "both";
|
|
6523
|
+
let group = [];
|
|
6524
|
+
let shift = false;
|
|
6325
6525
|
let t;
|
|
6326
6526
|
let subpath;
|
|
6327
6527
|
if (hit) {
|
|
6328
6528
|
profile = sanitizeWidthProfile(node.strokeWidthProfile);
|
|
6329
6529
|
ref = { nodeId: node.id, index: hit.ref.index, subpath: hit.ref.subpath };
|
|
6330
|
-
t = _nullishCoalesce(_optionalChain([profile, 'access',
|
|
6530
|
+
t = _nullishCoalesce(_optionalChain([profile, 'access', _196 => _196[ref.index], 'optionalAccess', _197 => _197.t]), () => ( 0));
|
|
6331
6531
|
subpath = hit.ref.subpath;
|
|
6332
|
-
if (hit.ref.part === "center") mode = "move";
|
|
6532
|
+
if (hit.ref.part === "center") mode = input.alt && profile.length < VECTOR_WIDTH_PROFILE_MAX_POINTS ? "copy" : "move";
|
|
6333
6533
|
else if (input.alt) side = hit.ref.part;
|
|
6534
|
+
const same = this.widthPoints.length > 0 && this.widthPoints[0].nodeId === node.id;
|
|
6535
|
+
const selected = same && this.widthPoints.some((r) => r.index === ref.index);
|
|
6536
|
+
if (input.shift && mode !== "copy") {
|
|
6537
|
+
if (selected) {
|
|
6538
|
+
this.widthPoints = this.widthPoints.filter((r) => r.index !== ref.index);
|
|
6539
|
+
this.notify();
|
|
6540
|
+
return;
|
|
6541
|
+
}
|
|
6542
|
+
this.widthPoints = same ? [...this.widthPoints, ref] : [ref];
|
|
6543
|
+
shift = true;
|
|
6544
|
+
} else if (mode === "copy" || !selected) this.widthPoints = [ref];
|
|
6545
|
+
if (mode !== "copy") group = this.widthPoints.filter((r) => r.index !== ref.index).map((r) => r.index);
|
|
6334
6546
|
} else {
|
|
6335
6547
|
const near2 = nearestStrokePosition(g.line, [local.x, local.y]);
|
|
6336
6548
|
const inserted = insertWidthPoint(strokeWidthProfileOf(node), near2.t);
|
|
@@ -6339,17 +6551,21 @@ var VectorEditorController = (_class3 = class {
|
|
|
6339
6551
|
t = near2.t;
|
|
6340
6552
|
ref = { nodeId: node.id, index: inserted.index, subpath };
|
|
6341
6553
|
if (input.alt) side = near2.side;
|
|
6554
|
+
this.widthPoints = [ref];
|
|
6342
6555
|
}
|
|
6343
6556
|
const at2 = strokePositionPoint(g.line, subpath, t);
|
|
6344
6557
|
if (!at2) return;
|
|
6345
6558
|
const base = { ...this.doc, nodes: mapTree(this.doc.nodes, (n) => n.id === node.id ? { ...n, strokeWidthProfile: profile } : n) };
|
|
6346
6559
|
this.doc = base;
|
|
6347
|
-
this.widthPoint = { nodeId: node.id, index: ref.index, subpath };
|
|
6348
6560
|
this.drag = {
|
|
6349
6561
|
kind: "width",
|
|
6350
6562
|
ref,
|
|
6351
6563
|
mode,
|
|
6352
6564
|
side,
|
|
6565
|
+
source: ref.index,
|
|
6566
|
+
group,
|
|
6567
|
+
shift,
|
|
6568
|
+
renumber: null,
|
|
6353
6569
|
origin: { x: at2.point[0], y: at2.point[1] },
|
|
6354
6570
|
normal: { x: at2.tangent[1], y: -at2.tangent[0] },
|
|
6355
6571
|
unit: g.unit,
|
|
@@ -6364,6 +6580,31 @@ var VectorEditorController = (_class3 = class {
|
|
|
6364
6580
|
this.interaction = { type: "width", ref, mode, width: (w.left + w.right) * g.unit };
|
|
6365
6581
|
this.notify(!hit);
|
|
6366
6582
|
}
|
|
6583
|
+
/**
|
|
6584
|
+
* A width-tool slide to `t` on the dragged point's subpath lands exactly on another width
|
|
6585
|
+
* point (not `skip`) within the pick distance on screen: dropping a point onto another makes
|
|
6586
|
+
* a discontinuous point (two points at one `t`, the width steps there).
|
|
6587
|
+
*/
|
|
6588
|
+
snapWidthT(drag, node, line2, t, skip) {
|
|
6589
|
+
const m = this.worldOf(node.id, drag.base);
|
|
6590
|
+
const at2 = strokePositionPoint(line2, drag.ref.subpath, t);
|
|
6591
|
+
if (!at2) return t;
|
|
6592
|
+
const here = this.documentToScreen(applyMatrix(m, { x: at2.point[0], y: at2.point[1] }));
|
|
6593
|
+
let best = t;
|
|
6594
|
+
let bestD = this.hitRadius;
|
|
6595
|
+
drag.profile.forEach((w, i) => {
|
|
6596
|
+
if (i === skip || drag.group.includes(i)) return;
|
|
6597
|
+
const q = strokePositionPoint(line2, drag.ref.subpath, w.t);
|
|
6598
|
+
if (!q) return;
|
|
6599
|
+
const s = this.documentToScreen(applyMatrix(m, { x: q.point[0], y: q.point[1] }));
|
|
6600
|
+
const d = Math.hypot(s.x - here.x, s.y - here.y);
|
|
6601
|
+
if (d <= bestD) {
|
|
6602
|
+
best = w.t;
|
|
6603
|
+
bestD = d;
|
|
6604
|
+
}
|
|
6605
|
+
});
|
|
6606
|
+
return best;
|
|
6607
|
+
}
|
|
6367
6608
|
/** The nearest outline point of any visible, unlocked path within the pick distance of document point `p`. */
|
|
6368
6609
|
nearestOutline(p) {
|
|
6369
6610
|
let best = null;
|
|
@@ -6552,7 +6793,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
6552
6793
|
}
|
|
6553
6794
|
downPen(screen, p, input) {
|
|
6554
6795
|
const before = this.snapshot();
|
|
6555
|
-
const sp = this.pen ? _optionalChain([this, 'access',
|
|
6796
|
+
const sp = this.pen ? _optionalChain([this, 'access', _198 => _198.getNode, 'call', _199 => _199(this.pen.nodeId), 'optionalAccess', _200 => _200.subpaths, 'access', _201 => _201[this.pen.subpath]]) : void 0;
|
|
6556
6797
|
if (this.pen && sp) {
|
|
6557
6798
|
const pen = this.pen;
|
|
6558
6799
|
const first = { nodeId: pen.nodeId, subpath: pen.subpath, index: 0 };
|
|
@@ -6814,7 +7055,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
6814
7055
|
}
|
|
6815
7056
|
case "shape": {
|
|
6816
7057
|
const node = this.getNode(drag.nodeId);
|
|
6817
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
7058
|
+
if (_optionalChain([node, 'optionalAccess', _202 => _202.type]) !== "path") return;
|
|
6818
7059
|
const leave = { at: drag.start, constrain: input.shift ? drag.tool === "line" ? "angle" : "square" : null, curves: false };
|
|
6819
7060
|
let end = this.snapDrawn(p, leave, input, () => drag.targets ??= this.drawingTargets(null));
|
|
6820
7061
|
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);
|
|
@@ -6848,19 +7089,35 @@ var VectorEditorController = (_class3 = class {
|
|
|
6848
7089
|
drag.moved = true;
|
|
6849
7090
|
const node = findVectorNode(drag.base.nodes, drag.ref.nodeId);
|
|
6850
7091
|
const local = this.toLocal(node.id, p, drag.base);
|
|
7092
|
+
const src = drag.profile[drag.source];
|
|
6851
7093
|
let profile;
|
|
6852
|
-
|
|
7094
|
+
let index = drag.source;
|
|
7095
|
+
if (drag.mode !== "width") {
|
|
6853
7096
|
const g = vectorStrokeWidthGeometry(node);
|
|
6854
7097
|
const near2 = g ? nearestStrokePosition(g.line, [local.x, local.y], drag.ref.subpath) : null;
|
|
6855
|
-
if (!near2) return;
|
|
6856
|
-
|
|
7098
|
+
if (!g || !near2) return;
|
|
7099
|
+
const t = drag.group.length ? near2.t : this.snapWidthT(drag, node, g.line, near2.t, drag.source);
|
|
7100
|
+
if (drag.mode === "copy") {
|
|
7101
|
+
({ points: profile, index } = insertWidthPoint(drag.profile, t, { left: src.left, right: src.right }, { step: true }));
|
|
7102
|
+
} else if (drag.group.length) {
|
|
7103
|
+
const shifted = shiftWidthPoints(drag.profile, [drag.source, ...drag.group], t - src.t);
|
|
7104
|
+
profile = shifted.points;
|
|
7105
|
+
drag.renumber = shifted.renumber;
|
|
7106
|
+
index = _nullishCoalesce(shifted.renumber.get(drag.source), () => ( drag.source));
|
|
7107
|
+
} else profile = setWidthPoint(drag.profile, drag.source, { t });
|
|
6857
7108
|
} else {
|
|
6858
7109
|
const off = ((local.x - drag.origin.x) * drag.normal.x + (local.y - drag.origin.y) * drag.normal.y) / drag.unit;
|
|
6859
7110
|
const patch = drag.side === "both" ? { left: Math.abs(off), right: Math.abs(off) } : drag.side === "left" ? { left: Math.max(0, off) } : { right: Math.max(0, -off) };
|
|
6860
|
-
profile = setWidthPoint(drag.profile, drag.
|
|
7111
|
+
profile = setWidthPoint(drag.profile, drag.source, patch);
|
|
7112
|
+
if (drag.group.length) {
|
|
7113
|
+
const dl = profile[drag.source].left - src.left;
|
|
7114
|
+
const dr = profile[drag.source].right - src.right;
|
|
7115
|
+
for (const i of drag.group) profile = setWidthPoint(profile, i, { left: Math.max(0, drag.profile[i].left + dl), right: Math.max(0, drag.profile[i].right + dr) });
|
|
7116
|
+
}
|
|
6861
7117
|
}
|
|
6862
7118
|
this.doc = { ...drag.base, nodes: mapTree(drag.base.nodes, (n) => n.id === node.id ? { ...n, strokeWidthProfile: profile } : n) };
|
|
6863
|
-
|
|
7119
|
+
drag.ref = { ...drag.ref, index };
|
|
7120
|
+
const w = profile[index];
|
|
6864
7121
|
this.interaction = { type: "width", ref: drag.ref, mode: drag.mode, width: (w.left + w.right) * drag.unit };
|
|
6865
7122
|
this.notify(true);
|
|
6866
7123
|
return;
|
|
@@ -6872,14 +7129,14 @@ var VectorEditorController = (_class3 = class {
|
|
|
6872
7129
|
for (const q of drag.lazy.push([p.x, p.y])) {
|
|
6873
7130
|
if (Math.hypot(q[0] - last[0], q[1] - last[1]) * this.viewport.zoom < 1.5) continue;
|
|
6874
7131
|
drag.points.push(q);
|
|
6875
|
-
_optionalChain([drag, 'access',
|
|
7132
|
+
_optionalChain([drag, 'access', _203 => _203.pressures, 'optionalAccess', _204 => _204.push, 'call', _205 => _205(drag.pressure)]);
|
|
6876
7133
|
moved = true;
|
|
6877
7134
|
}
|
|
6878
7135
|
const string = drag.lazy.string();
|
|
6879
7136
|
const node = this.getNode(drag.nodeId);
|
|
6880
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
7137
|
+
if (_optionalChain([node, 'optionalAccess', _206 => _206.type]) !== "path") return;
|
|
6881
7138
|
if (!moved) {
|
|
6882
|
-
if (string && _optionalChain([this, 'access',
|
|
7139
|
+
if (string && _optionalChain([this, 'access', _207 => _207.interaction, 'optionalAccess', _208 => _208.type]) === "draw") {
|
|
6883
7140
|
this.interaction = { ...this.interaction, string: [{ x: string[0][0], y: string[0][1] }, { x: string[1][0], y: string[1][1] }] };
|
|
6884
7141
|
this.notify();
|
|
6885
7142
|
}
|
|
@@ -6915,8 +7172,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
6915
7172
|
}
|
|
6916
7173
|
this.setGuides(res);
|
|
6917
7174
|
return {
|
|
6918
|
-
dx: _optionalChain([res, 'optionalAccess',
|
|
6919
|
-
dy: _optionalChain([res, 'optionalAccess',
|
|
7175
|
+
dx: _optionalChain([res, 'optionalAccess', _209 => _209.x]) ? dx + res.dx : axes.x ? this.gridValue(origin.x + dx) - origin.x : dx,
|
|
7176
|
+
dy: _optionalChain([res, 'optionalAccess', _210 => _210.y]) ? dy + res.dy : axes.y ? this.gridValue(origin.y + dy) - origin.y : dy
|
|
6920
7177
|
};
|
|
6921
7178
|
}
|
|
6922
7179
|
/** The anchor a point drag snaps by, where it started: the grabbed one, else the moving one nearest the press. */
|
|
@@ -6995,7 +7252,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
6995
7252
|
if (drag.moved) return this.commit("Corner Radius", drag.before);
|
|
6996
7253
|
if (drag.alt) {
|
|
6997
7254
|
const kind = nextVectorCornerKind(drag.widget.kind);
|
|
6998
|
-
this.doc = this.updateAnchors(drag.base, drag.refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access',
|
|
7255
|
+
this.doc = this.updateAnchors(drag.base, drag.refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access', _211 => _211.corner, 'optionalAccess', _212 => _212.radius]), () => ( 0)), kind));
|
|
6999
7256
|
return this.commit("Corner Kind", drag.before);
|
|
7000
7257
|
}
|
|
7001
7258
|
const ref = drag.widget.ref;
|
|
@@ -7006,12 +7263,23 @@ var VectorEditorController = (_class3 = class {
|
|
|
7006
7263
|
return;
|
|
7007
7264
|
}
|
|
7008
7265
|
case "width": {
|
|
7009
|
-
if (drag.moved)
|
|
7266
|
+
if (drag.moved) {
|
|
7267
|
+
const several = drag.group.length > 0;
|
|
7268
|
+
if (drag.mode === "copy") this.widthPoints = [drag.ref];
|
|
7269
|
+
else if (drag.mode === "move" && several) {
|
|
7270
|
+
this.widthPoints = [drag.source, ...drag.group].map((i) => ({ ...drag.ref, index: _nullishCoalesce(_optionalChain([drag, 'access', _213 => _213.renumber, 'optionalAccess', _214 => _214.get, 'call', _215 => _215(i)]), () => ( i)) }));
|
|
7271
|
+
} else if (!several) this.widthPoints = [drag.ref];
|
|
7272
|
+
const label = drag.mode === "copy" ? "Copy Width Point" : drag.mode === "move" ? several ? "Move Width Points" : "Move Width Point" : several ? "Width Points" : "Width Point";
|
|
7273
|
+
return this.commit(label, drag.before);
|
|
7274
|
+
}
|
|
7010
7275
|
if (drag.created) {
|
|
7011
7276
|
this.doc = drag.before.doc;
|
|
7012
|
-
this.
|
|
7277
|
+
this.widthPoints = [];
|
|
7013
7278
|
this.notify(true);
|
|
7014
|
-
} else
|
|
7279
|
+
} else {
|
|
7280
|
+
if (!drag.shift && drag.group.length) this.widthPoints = [drag.ref];
|
|
7281
|
+
this.notify();
|
|
7282
|
+
}
|
|
7015
7283
|
return;
|
|
7016
7284
|
}
|
|
7017
7285
|
case "builder":
|
|
@@ -7041,14 +7309,14 @@ var VectorEditorController = (_class3 = class {
|
|
|
7041
7309
|
}
|
|
7042
7310
|
case "pencil": {
|
|
7043
7311
|
const node = this.getNode(drag.nodeId);
|
|
7044
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
7312
|
+
if (_optionalChain([node, 'optionalAccess', _216 => _216.type]) !== "path" || drag.points.length < 2) {
|
|
7045
7313
|
this.doc = drag.before.doc;
|
|
7046
7314
|
this.notify(true);
|
|
7047
7315
|
return;
|
|
7048
7316
|
}
|
|
7049
7317
|
for (const q of drag.lazy.finish()) {
|
|
7050
7318
|
drag.points.push(q);
|
|
7051
|
-
_optionalChain([drag, 'access',
|
|
7319
|
+
_optionalChain([drag, 'access', _217 => _217.pressures, 'optionalAccess', _218 => _218.push, 'call', _219 => _219(drag.pressure)]);
|
|
7052
7320
|
}
|
|
7053
7321
|
const shape = this.editing.recognizeShapes ? recognizeInkShape(drag.points, { minSize: 6 / this.viewport.zoom }) : null;
|
|
7054
7322
|
if (shape) {
|
|
@@ -7056,7 +7324,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
7056
7324
|
this.selection = [drag.nodeId];
|
|
7057
7325
|
return this.commit(`Draw ${inkShapeLabel(shape)}`, drag.before);
|
|
7058
7326
|
}
|
|
7059
|
-
const fitted =
|
|
7327
|
+
const fitted = _chunkVNYRI265cjs.fitCubics.call(void 0, drag.points, 1.5 / this.viewport.zoom, { cornerAngleDeg: 60 });
|
|
7060
7328
|
const anchors = [];
|
|
7061
7329
|
for (const c of fitted) {
|
|
7062
7330
|
if (!anchors.length) anchors.push({ x: c.p0[0], y: c.p0[1] });
|
|
@@ -7100,7 +7368,10 @@ var VectorEditorController = (_class3 = class {
|
|
|
7100
7368
|
}
|
|
7101
7369
|
this.restore(drag.before);
|
|
7102
7370
|
}
|
|
7103
|
-
/**
|
|
7371
|
+
/**
|
|
7372
|
+
* Double click: select tool enters path editing, direct tool toggles an anchor or adds one,
|
|
7373
|
+
* width tool opens the width-point editor (`widthPointEdit`).
|
|
7374
|
+
*/
|
|
7104
7375
|
doubleClick(screen) {
|
|
7105
7376
|
const p = this.screenToDocument(screen);
|
|
7106
7377
|
if (this.tool === "select") {
|
|
@@ -7120,7 +7391,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
7120
7391
|
this.convertAnchors(a.in || a.out ? "corner" : "smooth", [anchor]);
|
|
7121
7392
|
return;
|
|
7122
7393
|
}
|
|
7123
|
-
const id = _nullishCoalesce(_optionalChain([this, 'access',
|
|
7394
|
+
const id = _nullishCoalesce(_optionalChain([this, 'access', _220 => _220.hover, 'optionalAccess', _221 => _221.segment, 'optionalAccess', _222 => _222.nodeId]), () => ( this.editingId));
|
|
7124
7395
|
if (id) {
|
|
7125
7396
|
const node = this.getNode(id);
|
|
7126
7397
|
const seg = node ? nearestSegment(node, this.toLocal(id, p)) : null;
|
|
@@ -7128,6 +7399,16 @@ var VectorEditorController = (_class3 = class {
|
|
|
7128
7399
|
}
|
|
7129
7400
|
return;
|
|
7130
7401
|
}
|
|
7402
|
+
if (this.tool === "width") {
|
|
7403
|
+
const hit = this.hitWidthHandle(screen);
|
|
7404
|
+
if (hit) {
|
|
7405
|
+
this.openWidthPointEdit(hit.ref);
|
|
7406
|
+
return;
|
|
7407
|
+
}
|
|
7408
|
+
const spot = this.strokeSpotAt(p);
|
|
7409
|
+
if (spot) this.openWidthPointEdit({ nodeId: spot.nodeId, subpath: spot.subpath, t: spot.t });
|
|
7410
|
+
return;
|
|
7411
|
+
}
|
|
7131
7412
|
if (this.tool === "pen") this.finishPath();
|
|
7132
7413
|
}
|
|
7133
7414
|
// -------------------------------------------------------------------------
|
|
@@ -7188,8 +7469,9 @@ var VectorEditorController = (_class3 = class {
|
|
|
7188
7469
|
switch (key) {
|
|
7189
7470
|
case "Escape":
|
|
7190
7471
|
if (this.drag) this.cancelDrag();
|
|
7191
|
-
else if (this.
|
|
7192
|
-
|
|
7472
|
+
else if (this.widthEdit) this.closeWidthPointEdit();
|
|
7473
|
+
else if (this.tool === "width" && this.widthPoints.length) {
|
|
7474
|
+
this.widthPoints = [];
|
|
7193
7475
|
this.notify();
|
|
7194
7476
|
} else if (this.pen) this.finishPath();
|
|
7195
7477
|
else if (this.tool === "direct" && this.anchors.length) {
|
|
@@ -7203,7 +7485,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
7203
7485
|
this.finishPath();
|
|
7204
7486
|
return true;
|
|
7205
7487
|
}
|
|
7206
|
-
if (this.tool === "select" && this.selection.length === 1 && _optionalChain([this, 'access',
|
|
7488
|
+
if (this.tool === "select" && this.selection.length === 1 && _optionalChain([this, 'access', _223 => _223.getNode, 'call', _224 => _224(this.selection[0]), 'optionalAccess', _225 => _225.type]) === "path") {
|
|
7207
7489
|
this.tool = "direct";
|
|
7208
7490
|
this.editingId = this.selection[0];
|
|
7209
7491
|
this.notify();
|
|
@@ -7212,7 +7494,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
7212
7494
|
return false;
|
|
7213
7495
|
case "Delete":
|
|
7214
7496
|
case "Backspace":
|
|
7215
|
-
if (this.tool === "width" && this.
|
|
7497
|
+
if (this.tool === "width" && this.widthPoints.length) return this.removeWidthPoints().ok;
|
|
7216
7498
|
if (this.pen) {
|
|
7217
7499
|
const node = this.getNode(this.pen.nodeId);
|
|
7218
7500
|
const sp = node.subpaths[this.pen.subpath];
|
|
@@ -7323,6 +7605,7 @@ function pencilPressureProfile(points, pressures) {
|
|
|
7323
7605
|
// src/vector/render.ts
|
|
7324
7606
|
var fmt = (n) => Math.round(n * 100) / 100;
|
|
7325
7607
|
var fmtMatrix = (m) => `matrix(${m.map((n) => Math.round(n * 1e6) / 1e6).join(" ")})`;
|
|
7608
|
+
var VECTOR_BUILDER_HATCH_GAP = 6;
|
|
7326
7609
|
function renderNode(node, defs, idPrefix) {
|
|
7327
7610
|
if (node.visible === false) return null;
|
|
7328
7611
|
if (node.type === "group") {
|
|
@@ -7345,7 +7628,7 @@ function renderNode(node, defs, idPrefix) {
|
|
|
7345
7628
|
strokeWidth: _nullishCoalesce(node.strokeWidth, () => ( 1)),
|
|
7346
7629
|
...node.strokeLinecap ? { strokeLinecap: node.strokeLinecap } : {},
|
|
7347
7630
|
...node.strokeLinejoin ? { strokeLinejoin: node.strokeLinejoin } : {},
|
|
7348
|
-
..._optionalChain([node, 'access',
|
|
7631
|
+
..._optionalChain([node, 'access', _226 => _226.strokeDasharray, 'optionalAccess', _227 => _227.length]) ? { strokeDasharray: node.strokeDasharray.join(" ") } : {},
|
|
7349
7632
|
fillRule: _nullishCoalesce(node.fillRule, () => ( "nonzero")),
|
|
7350
7633
|
opacity: _nullishCoalesce(node.opacity, () => ( 1))
|
|
7351
7634
|
};
|
|
@@ -7369,7 +7652,7 @@ function screenOutline(state, node) {
|
|
|
7369
7652
|
const v2 = state.viewport;
|
|
7370
7653
|
const view = [v2.zoom, 0, 0, v2.zoom, v2.x, v2.y];
|
|
7371
7654
|
const parent = _nullishCoalesce(vectorParentMatrix(state.document.nodes, node.id), () => ( IDENTITY_MATRIX));
|
|
7372
|
-
return collectWithMatrix(node, parent).map(({ path, parent: m }) =>
|
|
7655
|
+
return collectWithMatrix(node, parent).map(({ path, parent: m }) => _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, _chunkVNYRI265cjs.transformBezierPath.call(void 0, vectorPathWorldBezier(path, m), view), { precision: 2 })).join(" ");
|
|
7373
7656
|
}
|
|
7374
7657
|
function collectWithMatrix(node, parent) {
|
|
7375
7658
|
if (node.type === "path") return [{ path: node, parent }];
|
|
@@ -7394,9 +7677,9 @@ function getVectorOverlayRenderData(state) {
|
|
|
7394
7677
|
};
|
|
7395
7678
|
for (const id of state.selection) outline(id, true);
|
|
7396
7679
|
if (state.editingId) outline(state.editingId, true);
|
|
7397
|
-
if (_optionalChain([state, 'access',
|
|
7680
|
+
if (_optionalChain([state, 'access', _228 => _228.hover, 'optionalAccess', _229 => _229.nodeId]) && !state.interaction) outline(state.hover.nodeId, false);
|
|
7398
7681
|
let selectionBox = null;
|
|
7399
|
-
if (state.tool === "select" && state.selectionFrame && _optionalChain([state, 'access',
|
|
7682
|
+
if (state.tool === "select" && state.selectionFrame && _optionalChain([state, 'access', _230 => _230.interaction, 'optionalAccess', _231 => _231.type]) !== "marquee") {
|
|
7400
7683
|
const g = getVectorSelectionBoxGeometry(state.selectionFrame, state.viewport);
|
|
7401
7684
|
selectionBox = { ...g.box, angle: g.angle, transform: g.transform, corners: g.corners, handles: g.handles };
|
|
7402
7685
|
}
|
|
@@ -7406,9 +7689,9 @@ function getVectorOverlayRenderData(state) {
|
|
|
7406
7689
|
const a = getAnchorWorld(doc, ref);
|
|
7407
7690
|
const s = toScreen(state, a);
|
|
7408
7691
|
const closes = !!state.pen && state.pen.nodeId === ref.nodeId && state.pen.subpath === ref.subpath && ref.index === 0;
|
|
7409
|
-
return { ref, x: s.x, y: s.y, type: _nullishCoalesce(a.type, () => ( inferAnchorType(a))), selected: selected(ref), hovered: sameAnchor(_optionalChain([state, 'access',
|
|
7692
|
+
return { ref, x: s.x, y: s.y, type: _nullishCoalesce(a.type, () => ( inferAnchorType(a))), selected: selected(ref), hovered: sameAnchor(_optionalChain([state, 'access', _232 => _232.hover, 'optionalAccess', _233 => _233.anchor]), ref), closes };
|
|
7410
7693
|
});
|
|
7411
|
-
if (state.tool === "pen" && !state.pen && _optionalChain([state, 'access',
|
|
7694
|
+
if (state.tool === "pen" && !state.pen && _optionalChain([state, 'access', _234 => _234.hover, 'optionalAccess', _235 => _235.anchor])) {
|
|
7412
7695
|
const a = getAnchorWorld(doc, state.hover.anchor);
|
|
7413
7696
|
if (a) {
|
|
7414
7697
|
const s = toScreen(state, a);
|
|
@@ -7417,15 +7700,15 @@ function getVectorOverlayRenderData(state) {
|
|
|
7417
7700
|
}
|
|
7418
7701
|
const handles = getVisibleHandles(state).flatMap((ref) => {
|
|
7419
7702
|
const a = getAnchorWorld(doc, ref);
|
|
7420
|
-
const h = _optionalChain([a, 'optionalAccess',
|
|
7703
|
+
const h = _optionalChain([a, 'optionalAccess', _236 => _236[ref.handle]]);
|
|
7421
7704
|
if (!a || !h) return [];
|
|
7422
7705
|
const s = toScreen(state, h);
|
|
7423
7706
|
const sa = toScreen(state, a);
|
|
7424
|
-
const hovered = !!_optionalChain([state, 'access',
|
|
7707
|
+
const hovered = !!_optionalChain([state, 'access', _237 => _237.hover, 'optionalAccess', _238 => _238.handle]) && sameAnchor(state.hover.handle, ref) && state.hover.handle.handle === ref.handle;
|
|
7425
7708
|
return [{ ref, x: s.x, y: s.y, anchorX: sa.x, anchorY: sa.y, hovered }];
|
|
7426
7709
|
});
|
|
7427
7710
|
let marquee = null;
|
|
7428
|
-
if (_optionalChain([state, 'access',
|
|
7711
|
+
if (_optionalChain([state, 'access', _239 => _239.interaction, 'optionalAccess', _240 => _240.type]) === "marquee") {
|
|
7429
7712
|
const b = state.interaction.bounds;
|
|
7430
7713
|
const tl = toScreen(state, b);
|
|
7431
7714
|
marquee = { x: tl.x, y: tl.y, width: b.width * z, height: b.height * z };
|
|
@@ -7433,7 +7716,7 @@ function getVectorOverlayRenderData(state) {
|
|
|
7433
7716
|
let penPreview = null;
|
|
7434
7717
|
if (state.tool === "pen" && state.pen && state.pointer && !state.interaction) {
|
|
7435
7718
|
const node = findVectorNode(doc.nodes, state.pen.nodeId);
|
|
7436
|
-
const sp = _optionalChain([node, 'optionalAccess',
|
|
7719
|
+
const sp = _optionalChain([node, 'optionalAccess', _241 => _241.type]) === "path" ? node.subpaths[state.pen.subpath] : void 0;
|
|
7437
7720
|
const last = sp ? getAnchorWorld(doc, { nodeId: state.pen.nodeId, subpath: state.pen.subpath, index: sp.anchors.length - 1 }) : void 0;
|
|
7438
7721
|
if (last) {
|
|
7439
7722
|
const a = toScreen(state, last);
|
|
@@ -7446,9 +7729,9 @@ function getVectorOverlayRenderData(state) {
|
|
|
7446
7729
|
const artboard = { x: origin.x, y: origin.y, width: doc.width * z, height: doc.height * z };
|
|
7447
7730
|
let status = null;
|
|
7448
7731
|
const it = state.interaction;
|
|
7449
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
7450
|
-
else if (_optionalChain([it, 'optionalAccess',
|
|
7451
|
-
else if (_optionalChain([it, 'optionalAccess',
|
|
7732
|
+
if (_optionalChain([it, 'optionalAccess', _242 => _242.type]) === "rotate") status = `${Math.round(it.angle)}\xB0`;
|
|
7733
|
+
else if (_optionalChain([it, 'optionalAccess', _243 => _243.type]) === "move" || _optionalChain([it, 'optionalAccess', _244 => _244.type]) === "anchors") status = `\u0394 ${fmt(it.dx)}, ${fmt(it.dy)}`;
|
|
7734
|
+
else if (_optionalChain([it, 'optionalAccess', _245 => _245.type]) === "scale" || _optionalChain([it, 'optionalAccess', _246 => _246.type]) === "draw") {
|
|
7452
7735
|
const b = it.type === "draw" ? findVectorNode(doc.nodes, it.nodeId) ? vectorNodeBounds(findVectorNode(doc.nodes, it.nodeId)) : null : state.selectionFrame;
|
|
7453
7736
|
if (b) status = `W ${fmt(b.width)} \xD7 H ${fmt(b.height)}`;
|
|
7454
7737
|
}
|
|
@@ -7465,24 +7748,24 @@ function getVectorOverlayRenderData(state) {
|
|
|
7465
7748
|
}
|
|
7466
7749
|
}
|
|
7467
7750
|
let toolStroke = null;
|
|
7468
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
7751
|
+
if (_optionalChain([it, 'optionalAccess', _247 => _247.type]) === "stroke") {
|
|
7469
7752
|
const pts = it.points.map((q) => toScreen(state, q));
|
|
7470
7753
|
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)}` : "");
|
|
7471
7754
|
toolStroke = { tool: it.tool, d, width: fmt(it.width * z) };
|
|
7472
7755
|
}
|
|
7473
7756
|
let pencilString = null;
|
|
7474
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
7757
|
+
if (_optionalChain([it, 'optionalAccess', _248 => _248.type]) === "draw" && it.string) {
|
|
7475
7758
|
const a = toScreen(state, it.string[0]);
|
|
7476
7759
|
const b = toScreen(state, it.string[1]);
|
|
7477
7760
|
pencilString = { x1: fmt(a.x), y1: fmt(a.y), x2: fmt(b.x), y2: fmt(b.y) };
|
|
7478
7761
|
}
|
|
7479
|
-
const dragged = _optionalChain([it, 'optionalAccess',
|
|
7762
|
+
const dragged = _optionalChain([it, 'optionalAccess', _249 => _249.type]) === "corner" ? it.ref : null;
|
|
7480
7763
|
const cornerWidgets = getVectorCornerWidgets(state).map((w) => {
|
|
7481
7764
|
const s = toScreen(state, w);
|
|
7482
|
-
return { ref: w.ref, x: fmt(s.x), y: fmt(s.y), radius: w.radius, kind: w.kind, hovered: sameAnchor(_optionalChain([state, 'access',
|
|
7765
|
+
return { ref: w.ref, x: fmt(s.x), y: fmt(s.y), radius: w.radius, kind: w.kind, hovered: sameAnchor(_optionalChain([state, 'access', _250 => _250.hover, 'optionalAccess', _251 => _251.corner]), w.ref), active: !!dragged };
|
|
7483
7766
|
});
|
|
7484
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
7485
|
-
const cutPoint = state.tool === "scissors" && _optionalChain([state, 'access',
|
|
7767
|
+
if (_optionalChain([it, 'optionalAccess', _252 => _252.type]) === "corner") status = `R ${fmt(it.radius)}`;
|
|
7768
|
+
const cutPoint = state.tool === "scissors" && _optionalChain([state, 'access', _253 => _253.hover, 'optionalAccess', _254 => _254.segment]) && !it ? (({ x, y }) => ({ x: fmt(x), y: fmt(y) }))(toScreen(state, state.hover.segment.point)) : null;
|
|
7486
7769
|
const sc = (p) => {
|
|
7487
7770
|
const q = toScreen(state, p);
|
|
7488
7771
|
return { x: fmt(q.x), y: fmt(q.y) };
|
|
@@ -7490,21 +7773,29 @@ function getVectorOverlayRenderData(state) {
|
|
|
7490
7773
|
const sameWidth = (a, b) => !!a && a.nodeId === b.nodeId && a.index === b.index;
|
|
7491
7774
|
const widthPoints = getVectorWidthHandles(state).map((h) => {
|
|
7492
7775
|
const c = sc(h);
|
|
7493
|
-
const hw = _optionalChain([state, 'access',
|
|
7776
|
+
const hw = _optionalChain([state, 'access', _255 => _255.hover, 'optionalAccess', _256 => _256.widthPoint]);
|
|
7494
7777
|
const hovered = hw && sameWidth(hw, h.ref) && hw.subpath === h.ref.subpath ? hw.part : null;
|
|
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',
|
|
7778
|
+
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', _257 => _257.type]) === "width" && sameWidth(it.ref, h.ref) };
|
|
7496
7779
|
});
|
|
7497
|
-
const spot = state.tool === "width" && !it ? _optionalChain([state, 'access',
|
|
7780
|
+
const spot = state.tool === "width" && !it ? _optionalChain([state, 'access', _258 => _258.hover, 'optionalAccess', _259 => _259.strokeSpot]) : null;
|
|
7498
7781
|
const widthSpot = spot ? { ...sc(spot.point), left: sc(spot.left), right: sc(spot.right) } : null;
|
|
7499
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
7782
|
+
if (_optionalChain([it, 'optionalAccess', _260 => _260.type]) === "width") status = it.mode === "move" ? "Move width point" : it.mode === "copy" ? "Copy width point" : `W ${fmt(it.width)}`;
|
|
7500
7783
|
let builder = null;
|
|
7501
7784
|
if (state.builder) {
|
|
7502
7785
|
const v2 = state.viewport;
|
|
7503
7786
|
const view = [v2.zoom, 0, 0, v2.zoom, v2.x, v2.y];
|
|
7504
|
-
const
|
|
7787
|
+
const svg = (path) => _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, path, { precision: 2 });
|
|
7788
|
+
const screen = state.builder.faces.map((f) => _chunkVNYRI265cjs.transformBezierPath.call(void 0, f, view));
|
|
7789
|
+
const hatch = state.builder.mode !== "fill";
|
|
7505
7790
|
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 = {
|
|
7507
|
-
|
|
7791
|
+
builder = {
|
|
7792
|
+
mode: state.builder.mode,
|
|
7793
|
+
faces: screen.map(svg),
|
|
7794
|
+
hatches: screen.map((f) => hatch ? svg(_chunkVNYRI265cjs.hatchPath.call(void 0, f, { gap: VECTOR_BUILDER_HATCH_GAP })) : ""),
|
|
7795
|
+
lines: state.builder.lines.map((l) => svg(_chunkVNYRI265cjs.transformBezierPath.call(void 0, l, view))),
|
|
7796
|
+
trail
|
|
7797
|
+
};
|
|
7798
|
+
if (state.builder.mode !== "fill" && _optionalChain([it, 'optionalAccess', _261 => _261.type]) === "builder") {
|
|
7508
7799
|
const n = state.builder.faces.length;
|
|
7509
7800
|
status = state.builder.mode === "erase" ? `Delete ${n} ${n === 1 ? "face" : "faces"}` : `Merge ${n} ${n === 1 ? "face" : "faces"}`;
|
|
7510
7801
|
}
|
|
@@ -7530,7 +7821,9 @@ var VECTOR_OVERLAY_THEME = {
|
|
|
7530
7821
|
builderFill: "rgba(14, 165, 233, 0.22)",
|
|
7531
7822
|
/** Shape Builder faces and line pieces an Alt gesture deletes. */
|
|
7532
7823
|
builderErase: "#ef4444",
|
|
7533
|
-
builderEraseFill: "rgba(239, 68, 68, 0.22)"
|
|
7824
|
+
builderEraseFill: "rgba(239, 68, 68, 0.22)",
|
|
7825
|
+
/** Opacity of the hatch lines over Shape Builder faces (drawn in the face's outline colour). */
|
|
7826
|
+
builderHatchOpacity: 0.6
|
|
7534
7827
|
};
|
|
7535
7828
|
function vectorDiamondPath(x, y, r = VECTOR_OVERLAY_THEME.widthPointSize) {
|
|
7536
7829
|
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`;
|
|
@@ -7554,7 +7847,7 @@ function isVectorTextTarget(target) {
|
|
|
7554
7847
|
if (!el || typeof el !== "object") return false;
|
|
7555
7848
|
const tag = (_nullishCoalesce(el.tagName, () => ( ""))).toUpperCase();
|
|
7556
7849
|
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
7557
|
-
return !!el.isContentEditable || _optionalChain([el, 'access',
|
|
7850
|
+
return !!el.isContentEditable || _optionalChain([el, 'access', _262 => _262.getAttribute, 'optionalCall', _263 => _263("contenteditable")]) === "true";
|
|
7558
7851
|
}
|
|
7559
7852
|
function getVectorSelectionStyle(state) {
|
|
7560
7853
|
const paths = [];
|
|
@@ -7562,12 +7855,12 @@ function getVectorSelectionStyle(state) {
|
|
|
7562
7855
|
const node = findVectorNode(state.document.nodes, id);
|
|
7563
7856
|
if (node) paths.push(...collect(node));
|
|
7564
7857
|
}
|
|
7565
|
-
const anchorMode = state.tool === "direct" && !!_optionalChain([state, 'access',
|
|
7858
|
+
const anchorMode = state.tool === "direct" && !!_optionalChain([state, 'access', _264 => _264.selectedAnchors, 'optionalAccess', _265 => _265.length]);
|
|
7566
7859
|
if (anchorMode) {
|
|
7567
7860
|
for (const r of state.selectedAnchors) {
|
|
7568
7861
|
if (paths.some((p) => p.id === r.nodeId)) continue;
|
|
7569
7862
|
const node = findVectorNode(state.document.nodes, r.nodeId);
|
|
7570
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
7863
|
+
if (_optionalChain([node, 'optionalAccess', _266 => _266.type]) === "path") paths.push(node);
|
|
7571
7864
|
}
|
|
7572
7865
|
}
|
|
7573
7866
|
if (!paths.length) return null;
|
|
@@ -7578,7 +7871,7 @@ function getVectorSelectionStyle(state) {
|
|
|
7578
7871
|
for (const c of vectorCorners(p.subpaths)) {
|
|
7579
7872
|
if (anchorMode && !state.selectedAnchors.some((r) => r.nodeId === p.id && r.subpath === c.subpath && r.index === c.index)) continue;
|
|
7580
7873
|
const corner = p.subpaths[c.subpath].anchors[c.index].corner;
|
|
7581
|
-
corners2.push({ radius: _nullishCoalesce(_optionalChain([corner, 'optionalAccess',
|
|
7874
|
+
corners2.push({ radius: _nullishCoalesce(_optionalChain([corner, 'optionalAccess', _267 => _267.radius]), () => ( 0)), kind: _nullishCoalesce(_optionalChain([corner, 'optionalAccess', _268 => _268.kind]), () => ( "round")) });
|
|
7582
7875
|
}
|
|
7583
7876
|
}
|
|
7584
7877
|
const c0 = _nullishCoalesce(corners2[0], () => ( { radius: 0, kind: "round" }));
|
|
@@ -7726,17 +8019,17 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7726
8019
|
const base = { group, ...options.scope ? { scope: options.scope } : {} };
|
|
7727
8020
|
const hasSelection = () => controller.getState().selection.length ? true : "Nothing is selected.";
|
|
7728
8021
|
const ids = (params) => {
|
|
7729
|
-
const list2 = _nullishCoalesce(_optionalChain([params, 'optionalAccess',
|
|
8022
|
+
const list2 = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _269 => _269.ids]), () => ( controller.getState().selection));
|
|
7730
8023
|
for (const id of list2) if (!controller.getNode(id)) fail(`There is no node "${id}".`);
|
|
7731
8024
|
if (!list2.length) fail("Nothing is selected; pass ids.");
|
|
7732
8025
|
return list2;
|
|
7733
8026
|
};
|
|
7734
|
-
const enabledFor = (_, params) => _optionalChain([params, 'optionalAccess',
|
|
8027
|
+
const enabledFor = (_, params) => _optionalChain([params, 'optionalAccess', _270 => _270.ids, 'optionalAccess', _271 => _271.length]) ? true : hasSelection();
|
|
7735
8028
|
const anchorsOf = (refs) => {
|
|
7736
8029
|
if (!refs) return [...controller.getState().selectedAnchors];
|
|
7737
8030
|
for (const r of refs) {
|
|
7738
8031
|
const node = controller.getNode(r.nodeId);
|
|
7739
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
8032
|
+
if (_optionalChain([node, 'optionalAccess', _272 => _272.type]) !== "path" || !_optionalChain([node, 'access', _273 => _273.subpaths, 'access', _274 => _274[r.subpath], 'optionalAccess', _275 => _275.anchors, 'access', _276 => _276[r.index]])) fail(`There is no anchor ${r.index} on subpath ${r.subpath} of "${r.nodeId}".`);
|
|
7740
8033
|
}
|
|
7741
8034
|
return refs;
|
|
7742
8035
|
};
|
|
@@ -7827,7 +8120,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7827
8120
|
run: (_ctx, params) => {
|
|
7828
8121
|
const id = controller.addPath(params.d, { ...pickStyle(params), ...params.name ? { name: params.name } : {} });
|
|
7829
8122
|
const node = controller.getNode(id);
|
|
7830
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
8123
|
+
if (_optionalChain([node, 'optionalAccess', _277 => _277.type]) === "path" && !node.subpaths.length) {
|
|
7831
8124
|
controller.undo();
|
|
7832
8125
|
fail("The path data has no points.");
|
|
7833
8126
|
}
|
|
@@ -7859,10 +8152,10 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7859
8152
|
params: { type: "object", properties: { radius: { type: "number", minimum: 0 }, kind: { type: "string", enum: VECTOR_CORNER_KINDS }, ids: IDS, anchors: ANCHORS } },
|
|
7860
8153
|
undoable: true,
|
|
7861
8154
|
run: (_ctx, params) => {
|
|
7862
|
-
const refs = _optionalChain([params, 'optionalAccess',
|
|
7863
|
-
const target = { refs, ids: _optionalChain([params, 'optionalAccess',
|
|
7864
|
-
if (_optionalChain([params, 'optionalAccess',
|
|
7865
|
-
else if (_optionalChain([params, 'optionalAccess',
|
|
8155
|
+
const refs = _optionalChain([params, 'optionalAccess', _278 => _278.anchors]) ? anchorsOf(params.anchors) : void 0;
|
|
8156
|
+
const target = { refs, ids: _optionalChain([params, 'optionalAccess', _279 => _279.ids]) ? ids(params) : void 0 };
|
|
8157
|
+
if (_optionalChain([params, 'optionalAccess', _280 => _280.radius]) !== void 0) check(controller.setCornerRadius(params.radius, { ...target, kind: params.kind }));
|
|
8158
|
+
else if (_optionalChain([params, 'optionalAccess', _281 => _281.kind])) check(controller.setCornerKind(params.kind, target));
|
|
7866
8159
|
else fail("Pass `radius` and / or `kind`.");
|
|
7867
8160
|
return { ok: true };
|
|
7868
8161
|
}
|
|
@@ -7897,12 +8190,37 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7897
8190
|
undoable: true,
|
|
7898
8191
|
run: (_ctx, params) => {
|
|
7899
8192
|
const target = { ids: ids(params) };
|
|
7900
|
-
if (_optionalChain([params, 'optionalAccess',
|
|
7901
|
-
else if (_optionalChain([params, 'optionalAccess',
|
|
7902
|
-
else if (_optionalChain([params, 'optionalAccess',
|
|
8193
|
+
if (_optionalChain([params, 'optionalAccess', _282 => _282.preset])) check(controller.setWidthProfile(params.preset, target));
|
|
8194
|
+
else if (_optionalChain([params, 'optionalAccess', _283 => _283.points]) !== void 0) check(controller.setWidthProfile(_nullishCoalesce(params.points, () => ( null)), target));
|
|
8195
|
+
else if (_optionalChain([params, 'optionalAccess', _284 => _284.taper]) || _optionalChain([params, 'optionalAccess', _285 => _285.wave])) check(controller.setWidthProfile({ taper: params.taper, wave: params.wave }, target));
|
|
7903
8196
|
else fail("Pass `preset`, `points`, `taper` or `wave`.");
|
|
7904
8197
|
const node = controller.getNode(target.ids[0]);
|
|
7905
|
-
return { ok: true, points: _optionalChain([node, 'optionalAccess',
|
|
8198
|
+
return { ok: true, points: _optionalChain([node, 'optionalAccess', _286 => _286.type]) === "path" ? _nullishCoalesce(node.strokeWidthProfile, () => ( [])) : [] };
|
|
8199
|
+
}
|
|
8200
|
+
},
|
|
8201
|
+
{
|
|
8202
|
+
...base,
|
|
8203
|
+
id: `${prefix}setWidthPoint`,
|
|
8204
|
+
label: "Width Point\u2026",
|
|
8205
|
+
keywords: ["width point", "variable width", "stroke width at", "taper", "profile"],
|
|
8206
|
+
description: "Sets one width point of a path's stroke profile numerically: `index` names an existing point (see `vector.setWidthProfile`'s result), leave it out to add one at `t`. `left` / `right` are side widths in document units (how far the stroke reaches on each side), `t` the position along each subpath (0\u20131); a point moved onto another's `t` makes a step. Returns the profile.",
|
|
8207
|
+
params: {
|
|
8208
|
+
type: "object",
|
|
8209
|
+
properties: {
|
|
8210
|
+
id: { type: "string", description: "The path." },
|
|
8211
|
+
index: { type: "integer", minimum: 0 },
|
|
8212
|
+
t: { type: "number", minimum: 0, maximum: 1 },
|
|
8213
|
+
left: { type: "number", minimum: 0 },
|
|
8214
|
+
right: { type: "number", minimum: 0 }
|
|
8215
|
+
},
|
|
8216
|
+
required: ["id"]
|
|
8217
|
+
},
|
|
8218
|
+
undoable: true,
|
|
8219
|
+
run: (_ctx, params) => {
|
|
8220
|
+
if (!_optionalChain([params, 'optionalAccess', _287 => _287.id])) fail("Pass the path `id`.");
|
|
8221
|
+
check(controller.setWidthPoint({ nodeId: params.id, index: _nullishCoalesce(params.index, () => ( null)) }, { t: params.t, left: params.left, right: params.right }));
|
|
8222
|
+
const node = controller.getNode(params.id);
|
|
8223
|
+
return { ok: true, points: _optionalChain([node, 'optionalAccess', _288 => _288.type]) === "path" ? _nullishCoalesce(node.strokeWidthProfile, () => ( [])) : [] };
|
|
7906
8224
|
}
|
|
7907
8225
|
},
|
|
7908
8226
|
{
|
|
@@ -7915,7 +8233,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
7915
8233
|
enabled: enabledFor,
|
|
7916
8234
|
undoable: true,
|
|
7917
8235
|
run: (_ctx, params) => {
|
|
7918
|
-
const created = controller.outlineStroke({ ids: _optionalChain([params, 'optionalAccess',
|
|
8236
|
+
const created = controller.outlineStroke({ ids: _optionalChain([params, 'optionalAccess', _289 => _289.ids]) ? ids(params) : void 0 });
|
|
7919
8237
|
if (!created.length) fail("No selected path has a stroke.");
|
|
7920
8238
|
return { ids: created };
|
|
7921
8239
|
}
|
|
@@ -8006,7 +8324,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8006
8324
|
id: `${prefix}shapeBuilder`,
|
|
8007
8325
|
label: "Shape Builder",
|
|
8008
8326
|
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
|
|
8327
|
+
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, the pieces of unfilled open paths and the edges of other outlines (cut where paths meet) within `tolerance`; a deleted edge opens its path there, and edges bounding a deleted face go with it. Shapes covering those faces lose that area. Returns the counts of faces, line pieces and edges.",
|
|
8010
8328
|
params: {
|
|
8011
8329
|
type: "object",
|
|
8012
8330
|
properties: { points: POINTS, erase: { type: "boolean" }, tolerance: { type: "number", minimum: 0 }, ids: IDS },
|
|
@@ -8016,7 +8334,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8016
8334
|
run: (_ctx, params) => {
|
|
8017
8335
|
const result = controller.shapeBuilder(params.points.map(([x, y]) => ({ x, y })), { ids: ids(params), erase: params.erase, tolerance: params.tolerance });
|
|
8018
8336
|
check(result);
|
|
8019
|
-
return { merged: result.merged, faces: result.faces, lines: result.lines };
|
|
8337
|
+
return { merged: result.merged, faces: result.faces, lines: result.lines, edges: result.edges };
|
|
8020
8338
|
}
|
|
8021
8339
|
},
|
|
8022
8340
|
{
|
|
@@ -8086,7 +8404,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8086
8404
|
enabled: enabledFor,
|
|
8087
8405
|
undoable: true,
|
|
8088
8406
|
run: (_ctx, params) => {
|
|
8089
|
-
const id = controller.group({ ids: ids(params), name: _optionalChain([params, 'optionalAccess',
|
|
8407
|
+
const id = controller.group({ ids: ids(params), name: _optionalChain([params, 'optionalAccess', _290 => _290.name]) });
|
|
8090
8408
|
if (!id) fail("Only nodes that share a parent can be grouped.");
|
|
8091
8409
|
return { id };
|
|
8092
8410
|
}
|
|
@@ -8114,7 +8432,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8114
8432
|
params: { type: "object", properties: { anchors: ANCHORS, keepShape: { type: "boolean" } } },
|
|
8115
8433
|
undoable: true,
|
|
8116
8434
|
run: (_ctx, params) => {
|
|
8117
|
-
check(controller.deleteAnchors(anchorsOf(_optionalChain([params, 'optionalAccess',
|
|
8435
|
+
check(controller.deleteAnchors(anchorsOf(_optionalChain([params, 'optionalAccess', _291 => _291.anchors])), { keepShape: _optionalChain([params, 'optionalAccess', _292 => _292.keepShape]) }));
|
|
8118
8436
|
return { ok: true };
|
|
8119
8437
|
}
|
|
8120
8438
|
},
|
|
@@ -8169,7 +8487,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8169
8487
|
params: { type: "object", properties: { ids: IDS, tolerance: { type: "number", minimum: 0 } } },
|
|
8170
8488
|
undoable: true,
|
|
8171
8489
|
run: (_ctx, params) => {
|
|
8172
|
-
check(controller.joinPaths({ ids: _optionalChain([params, 'optionalAccess',
|
|
8490
|
+
check(controller.joinPaths({ ids: _optionalChain([params, 'optionalAccess', _293 => _293.ids]) ? ids(params) : void 0, tolerance: _optionalChain([params, 'optionalAccess', _294 => _294.tolerance]) }));
|
|
8173
8491
|
return { selection: controller.getState().selection };
|
|
8174
8492
|
}
|
|
8175
8493
|
},
|
|
@@ -8183,7 +8501,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8183
8501
|
params: { type: "object", properties: { axis: { type: "string", enum: ["horizontal", "vertical", "both"] }, anchors: ANCHORS } },
|
|
8184
8502
|
undoable: true,
|
|
8185
8503
|
run: (_ctx, params) => {
|
|
8186
|
-
check(controller.averageAnchors(_nullishCoalesce(_optionalChain([params, 'optionalAccess',
|
|
8504
|
+
check(controller.averageAnchors(_nullishCoalesce(_optionalChain([params, 'optionalAccess', _295 => _295.axis]), () => ( "both")), anchorsOf(_optionalChain([params, 'optionalAccess', _296 => _296.anchors]))));
|
|
8187
8505
|
return { ok: true };
|
|
8188
8506
|
}
|
|
8189
8507
|
},
|
|
@@ -8197,7 +8515,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8197
8515
|
enabled: enabledFor,
|
|
8198
8516
|
undoable: true,
|
|
8199
8517
|
run: (_ctx, params) => {
|
|
8200
|
-
check(controller.removeRedundantPoints({ ids: _optionalChain([params, 'optionalAccess',
|
|
8518
|
+
check(controller.removeRedundantPoints({ ids: _optionalChain([params, 'optionalAccess', _297 => _297.ids]) ? ids(params) : void 0, tolerance: _optionalChain([params, 'optionalAccess', _298 => _298.tolerance]) }));
|
|
8201
8519
|
return { ok: true };
|
|
8202
8520
|
}
|
|
8203
8521
|
},
|
|
@@ -8210,7 +8528,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8210
8528
|
params: { type: "object", properties: { ids: IDS, amount: { type: "number", minimum: 0, maximum: 1 }, anchors: ANCHORS } },
|
|
8211
8529
|
undoable: true,
|
|
8212
8530
|
run: (_ctx, params) => {
|
|
8213
|
-
check(controller.smoothPaths({ ids: _optionalChain([params, 'optionalAccess',
|
|
8531
|
+
check(controller.smoothPaths({ ids: _optionalChain([params, 'optionalAccess', _299 => _299.ids]) ? ids(params) : void 0, amount: _optionalChain([params, 'optionalAccess', _300 => _300.amount]), refs: _optionalChain([params, 'optionalAccess', _301 => _301.anchors]) }));
|
|
8214
8532
|
return { ok: true };
|
|
8215
8533
|
}
|
|
8216
8534
|
},
|
|
@@ -8223,14 +8541,14 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8223
8541
|
params: { type: "object", properties: { nodeId: { type: "string" }, x: { type: "number" }, y: { type: "number" }, anchors: ANCHORS } },
|
|
8224
8542
|
undoable: true,
|
|
8225
8543
|
run: (_ctx, params) => {
|
|
8226
|
-
if (_optionalChain([params, 'optionalAccess',
|
|
8544
|
+
if (_optionalChain([params, 'optionalAccess', _302 => _302.nodeId]) !== void 0) {
|
|
8227
8545
|
if (!controller.getNode(params.nodeId)) fail(`There is no node "${params.nodeId}".`);
|
|
8228
8546
|
if (params.x === void 0 || params.y === void 0) fail("Pass x and y with nodeId.");
|
|
8229
8547
|
const created = controller.cutPathAt(params.nodeId, { x: params.x, y: params.y });
|
|
8230
8548
|
if (!created) fail("Nothing to cut there (the end of an open path, or a locked path).");
|
|
8231
8549
|
return { ids: created };
|
|
8232
8550
|
}
|
|
8233
|
-
check(controller.cutAtAnchors(anchorsOf(_optionalChain([params, 'optionalAccess',
|
|
8551
|
+
check(controller.cutAtAnchors(anchorsOf(_optionalChain([params, 'optionalAccess', _303 => _303.anchors]))));
|
|
8234
8552
|
return { ids: controller.getState().selection };
|
|
8235
8553
|
}
|
|
8236
8554
|
},
|
|
@@ -8281,7 +8599,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8281
8599
|
},
|
|
8282
8600
|
run: (_ctx, params) => {
|
|
8283
8601
|
const patch = {};
|
|
8284
|
-
for (const key of ["keepShapeOnDelete", "curvatureMoves", "pencilSmoothing", "recognizeShapes", "eraserSize", "pencilPressure"]) if (_optionalChain([params, 'optionalAccess',
|
|
8602
|
+
for (const key of ["keepShapeOnDelete", "curvatureMoves", "pencilSmoothing", "recognizeShapes", "eraserSize", "pencilPressure"]) if (_optionalChain([params, 'optionalAccess', _304 => _304[key]]) !== void 0) patch[key] = params[key];
|
|
8285
8603
|
controller.setEditing(patch);
|
|
8286
8604
|
return { editing: controller.getState().editing };
|
|
8287
8605
|
}
|
|
@@ -8306,7 +8624,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8306
8624
|
keywords: ["download", "save", "markup"],
|
|
8307
8625
|
description: "Returns the document as SVG markup.",
|
|
8308
8626
|
params: { type: "object", properties: { precision: { type: "integer", minimum: 0, maximum: 8 } } },
|
|
8309
|
-
run: (_ctx, params) => ({ svg: controller.toSvg({ precision: _optionalChain([params, 'optionalAccess',
|
|
8627
|
+
run: (_ctx, params) => ({ svg: controller.toSvg({ precision: _optionalChain([params, 'optionalAccess', _305 => _305.precision]) }) })
|
|
8310
8628
|
},
|
|
8311
8629
|
{
|
|
8312
8630
|
...base,
|
|
@@ -8518,5 +8836,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8518
8836
|
|
|
8519
8837
|
|
|
8520
8838
|
|
|
8521
|
-
|
|
8839
|
+
|
|
8840
|
+
|
|
8841
|
+
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_BUILDER_HATCH_GAP = VECTOR_BUILDER_HATCH_GAP; 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.vectorBuilderErasedEdges = vectorBuilderErasedEdges; 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;
|
|
8522
8842
|
//# sourceMappingURL=index.cjs.map
|