@pixerate/editor 0.38.0 → 0.39.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 +2 -2
- 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 +281 -220
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +55 -12
- package/dist/vector/index.d.ts +55 -12
- package/dist/vector/index.js +101 -40
- 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,11 +819,11 @@ 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) {
|
|
@@ -898,16 +900,16 @@ function arrowheadPath(kind, tip, dir, hw) {
|
|
|
898
900
|
}
|
|
899
901
|
}
|
|
900
902
|
var toVec = (p) => ({ x: p[0], y: p[1] });
|
|
901
|
-
var segLen = (s) =>
|
|
903
|
+
var segLen = (s) => _chunkVNYRI265cjs.segmentLength.call(void 0, s);
|
|
902
904
|
function endOf(segs, atStart) {
|
|
903
905
|
const long = (s2) => segLen(s2) > 1e-9;
|
|
904
906
|
if (atStart) {
|
|
905
907
|
const s2 = _nullishCoalesce(segs.find(long), () => ( segs[0]));
|
|
906
|
-
const t2 =
|
|
908
|
+
const t2 = _chunkVNYRI265cjs.segmentTangent.call(void 0, s2, 0);
|
|
907
909
|
return { p: toVec(segs[0][0]), out: v(-t2[0], -t2[1]) };
|
|
908
910
|
}
|
|
909
911
|
const s = _nullishCoalesce([...segs].reverse().find(long), () => ( segs[segs.length - 1]));
|
|
910
|
-
const t =
|
|
912
|
+
const t = _chunkVNYRI265cjs.segmentTangent.call(void 0, s, 1);
|
|
911
913
|
const last = segs[segs.length - 1];
|
|
912
914
|
return { p: toVec(last[last.length - 1]), out: v(t[0], t[1]) };
|
|
913
915
|
}
|
|
@@ -918,7 +920,7 @@ function pointAlong(segs, fromStart, dist4) {
|
|
|
918
920
|
const l = segLen(s);
|
|
919
921
|
if (acc + l >= dist4) {
|
|
920
922
|
const want = fromStart ? dist4 - acc : l - (dist4 - acc);
|
|
921
|
-
const pts =
|
|
923
|
+
const pts = _chunkVNYRI265cjs.trimSegments.call(void 0, [s], 0, want);
|
|
922
924
|
const p = pts.length ? pts[0][pts[0].length - 1] : s[0];
|
|
923
925
|
return toVec(p);
|
|
924
926
|
}
|
|
@@ -928,7 +930,7 @@ function pointAlong(segs, fromStart, dist4) {
|
|
|
928
930
|
}
|
|
929
931
|
function vectorStrokeParts(path, style) {
|
|
930
932
|
const width = _nullishCoalesce(style.strokeWidth, () => ( 1));
|
|
931
|
-
const contours =
|
|
933
|
+
const contours = _chunkVNYRI265cjs.pathToContours.call(void 0, path).filter((c) => c.segments.length > 0);
|
|
932
934
|
const closedShape = contours.length > 0 && contours.every((c) => c.closed);
|
|
933
935
|
const align = effectiveStrokeAlign(style, closedShape);
|
|
934
936
|
const drawWidth = align === "center" ? width : width * 2;
|
|
@@ -968,26 +970,26 @@ function vectorStrokeParts(path, style) {
|
|
|
968
970
|
if (!s0 && !s1) return c;
|
|
969
971
|
const lengths = c.segments.map(segLen);
|
|
970
972
|
const total = lengths.reduce((a, b) => a + b, 0);
|
|
971
|
-
return { closed: false, segments: total - s1 > s0 ?
|
|
973
|
+
return { closed: false, segments: total - s1 > s0 ? _chunkVNYRI265cjs.trimSegments.call(void 0, c.segments, s0, total - s1, lengths) : [] };
|
|
972
974
|
});
|
|
973
|
-
return { align, line:
|
|
975
|
+
return { align, line: _chunkVNYRI265cjs.contoursToPath.call(void 0, trimmed), drawWidth, heads };
|
|
974
976
|
}
|
|
975
977
|
function vectorStrokeOutlinePath(path, style) {
|
|
976
978
|
const parts = vectorStrokeParts(path, style);
|
|
977
979
|
const stroke = vectorStrokeLineArea(parts, style);
|
|
978
980
|
const fill = { path, fillRule: _nullishCoalesce(style.fillRule, () => ( "nonzero")) };
|
|
979
981
|
let area = stroke;
|
|
980
|
-
if (parts.align === "inside") area =
|
|
981
|
-
else if (parts.align === "outside") area =
|
|
982
|
+
if (parts.align === "inside") area = _chunkVNYRI265cjs.pathBoolean.call(void 0, "intersection", [stroke, fill]).path;
|
|
983
|
+
else if (parts.align === "outside") area = _chunkVNYRI265cjs.pathBoolean.call(void 0, "difference", [stroke, fill]).path;
|
|
982
984
|
if (!parts.heads.length) return area;
|
|
983
|
-
return
|
|
985
|
+
return _chunkVNYRI265cjs.pathBoolean.call(void 0, "union", [area, ...parts.heads.map((h) => h.path)]).path;
|
|
984
986
|
}
|
|
985
987
|
function hitTestVectorStroke(path, p, style, tolerance = 0) {
|
|
986
988
|
const parts = vectorStrokeParts(path, style);
|
|
987
989
|
const point = [p.x, p.y];
|
|
988
990
|
const width = _nullishCoalesce(style.strokeWidth, () => ( 1));
|
|
989
991
|
for (const h of parts.heads) {
|
|
990
|
-
if (
|
|
992
|
+
if (_chunkVNYRI265cjs.pointInBezierPath.call(void 0, h.path, point) || tolerance > 0 && _chunkVNYRI265cjs.distanceToBezierPath.call(void 0, h.path, point) <= tolerance) return true;
|
|
991
993
|
}
|
|
992
994
|
if (!parts.line.length) return false;
|
|
993
995
|
const profile = strokeWidthProfileOf(style);
|
|
@@ -1005,13 +1007,13 @@ function hitTestVectorStroke(path, p, style, tolerance = 0) {
|
|
|
1005
1007
|
reach = Math.max(reach, width / 2 * (w.left + w.right) / 2);
|
|
1006
1008
|
}
|
|
1007
1009
|
} else {
|
|
1008
|
-
d =
|
|
1010
|
+
d = _chunkVNYRI265cjs.distanceToBezierPath.call(void 0, parts.line, point);
|
|
1009
1011
|
if (parts.align !== "center") reach = width;
|
|
1010
1012
|
}
|
|
1011
1013
|
if (parts.align === "center") return d <= reach + tolerance;
|
|
1012
1014
|
if (d > reach + tolerance) return false;
|
|
1013
1015
|
if (d <= tolerance) return true;
|
|
1014
|
-
const inside =
|
|
1016
|
+
const inside = _chunkVNYRI265cjs.pointInBezierPath.call(void 0, path, point, _nullishCoalesce(style.fillRule, () => ( "nonzero")));
|
|
1015
1017
|
return parts.align === "inside" ? inside : !inside;
|
|
1016
1018
|
}
|
|
1017
1019
|
function vectorStrokeReach(style) {
|
|
@@ -1087,7 +1089,7 @@ function vectorNodeToBezier(node) {
|
|
|
1087
1089
|
}
|
|
1088
1090
|
function vectorPathData(input, precision = 3) {
|
|
1089
1091
|
const subpaths = Array.isArray(input) ? input : input.subpaths;
|
|
1090
|
-
return
|
|
1092
|
+
return _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, subpathsToBezier(subpaths), { precision });
|
|
1091
1093
|
}
|
|
1092
1094
|
function inferAnchorType(a) {
|
|
1093
1095
|
if (isOnAnchor(a, a.in) || isOnAnchor(a, a.out)) return "corner";
|
|
@@ -1103,7 +1105,7 @@ function inferAnchorType(a) {
|
|
|
1103
1105
|
return Math.abs(li - lo) <= 1e-3 * Math.max(li, lo) ? "symmetric" : "smooth";
|
|
1104
1106
|
}
|
|
1105
1107
|
function bezierToSubpaths(input) {
|
|
1106
|
-
const path =
|
|
1108
|
+
const path = _chunkVNYRI265cjs.toBezierPath.call(void 0, input);
|
|
1107
1109
|
const out = [];
|
|
1108
1110
|
let current = null;
|
|
1109
1111
|
const last = () => current.anchors[current.anchors.length - 1];
|
|
@@ -1200,14 +1202,14 @@ function nodeMatrix(node) {
|
|
|
1200
1202
|
function vectorPathWorldBezier(node, parent = IDENTITY_MATRIX) {
|
|
1201
1203
|
const m = multiplyMatrices(nodeMatrix(node), parent);
|
|
1202
1204
|
const path = subpathsToBezier(node.subpaths);
|
|
1203
|
-
return isIdentityMatrix(m) ? path :
|
|
1205
|
+
return isIdentityMatrix(m) ? path : _chunkVNYRI265cjs.transformBezierPath.call(void 0, path, m);
|
|
1204
1206
|
}
|
|
1205
1207
|
function vectorNodeBounds(node, parent = IDENTITY_MATRIX) {
|
|
1206
1208
|
if (node.type === "group") {
|
|
1207
1209
|
const m = multiplyMatrices(nodeMatrix(node), parent);
|
|
1208
1210
|
return unionBounds(node.children.map((c) => vectorNodeBounds(c, m)));
|
|
1209
1211
|
}
|
|
1210
|
-
const b =
|
|
1212
|
+
const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, vectorPathWorldBezier(node, parent));
|
|
1211
1213
|
if (!b) return null;
|
|
1212
1214
|
return { x: b.minX, y: b.minY, width: b.maxX - b.minX, height: b.maxY - b.minY };
|
|
1213
1215
|
}
|
|
@@ -1241,9 +1243,9 @@ function hitTestVectorNode(node, p, tolerance = 0, parent = IDENTITY_MATRIX) {
|
|
|
1241
1243
|
const path = vectorPathWorldBezier(node, parent);
|
|
1242
1244
|
if (path.length === 0) return false;
|
|
1243
1245
|
const point = [p.x, p.y];
|
|
1244
|
-
if (hasPaint(node.fill) &&
|
|
1246
|
+
if (hasPaint(node.fill) && _chunkVNYRI265cjs.pointInBezierPath.call(void 0, path, point, _nullishCoalesce(node.fillRule, () => ( "nonzero")))) return true;
|
|
1245
1247
|
if (hasPaint(node.stroke)) return hitTestVectorStroke(path, p, node, tolerance);
|
|
1246
|
-
return
|
|
1248
|
+
return _chunkVNYRI265cjs.distanceToBezierPath.call(void 0, path, point) <= tolerance;
|
|
1247
1249
|
}
|
|
1248
1250
|
function vectorStrokeOutline(node, parent = IDENTITY_MATRIX) {
|
|
1249
1251
|
if (!hasPaint(node.stroke) || !((_nullishCoalesce(node.strokeWidth, () => ( 1))) > 0)) return [];
|
|
@@ -1263,9 +1265,9 @@ function nearestSegment(node, p) {
|
|
|
1263
1265
|
const count = subpathSegmentCount(sp);
|
|
1264
1266
|
for (let i = 0; i < count; i++) {
|
|
1265
1267
|
const seg = subpathSegment(sp, i);
|
|
1266
|
-
const hit =
|
|
1268
|
+
const hit = _chunkVNYRI265cjs.segmentNearest.call(void 0, seg, [p.x, p.y]);
|
|
1267
1269
|
if (!best || hit.distance < best.distance) {
|
|
1268
|
-
const pt2 =
|
|
1270
|
+
const pt2 = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, hit.t);
|
|
1269
1271
|
best = { subpath: s, segment: i, t: hit.t, point: { x: pt2[0], y: pt2[1] }, distance: hit.distance };
|
|
1270
1272
|
}
|
|
1271
1273
|
}
|
|
@@ -1325,7 +1327,7 @@ function bakeIntoGeometry(node, m) {
|
|
|
1325
1327
|
if (isIdentityMatrix(m)) return node;
|
|
1326
1328
|
if (node.type === "group") return { ...node, children: node.children.map((c) => transformVectorNode(c, m)) };
|
|
1327
1329
|
const path = node;
|
|
1328
|
-
const mirrored = m[0] * m[3] - m[1] * m[2] < 0 && _optionalChain([path, 'access',
|
|
1330
|
+
const mirrored = m[0] * m[3] - m[1] * m[2] < 0 && _optionalChain([path, 'access', _28 => _28.strokeWidthProfile, 'optionalAccess', _29 => _29.length]);
|
|
1329
1331
|
return {
|
|
1330
1332
|
...path,
|
|
1331
1333
|
...mirrored ? { strokeWidthProfile: mirrorWidthProfile(path.strokeWidthProfile) } : {},
|
|
@@ -1439,7 +1441,7 @@ function insertAnchor(sp, segment, t) {
|
|
|
1439
1441
|
const ia = segment;
|
|
1440
1442
|
const ib = (segment + 1) % n;
|
|
1441
1443
|
const seg = subpathSegment(sp, segment);
|
|
1442
|
-
const [left, right] =
|
|
1444
|
+
const [left, right] = _chunkVNYRI265cjs.splitSegment.call(void 0, seg, t);
|
|
1443
1445
|
const mid = left[left.length - 1];
|
|
1444
1446
|
const anchor = { x: mid[0], y: mid[1] };
|
|
1445
1447
|
if (seg.length === 4) {
|
|
@@ -1535,7 +1537,7 @@ function vectorCornersAttribute(subpaths, precision = 3) {
|
|
|
1535
1537
|
subpaths.forEach(
|
|
1536
1538
|
(sp, s) => sp.anchors.forEach((a, i) => {
|
|
1537
1539
|
if (!a.corner || !(a.corner.radius > 0)) return;
|
|
1538
|
-
out.push(`${s}.${i}:${
|
|
1540
|
+
out.push(`${s}.${i}:${_chunkVNYRI265cjs.formatNumber.call(void 0, a.corner.radius, precision)}${a.corner.kind && a.corner.kind !== "round" ? `:${a.corner.kind}` : ""}`);
|
|
1539
1541
|
})
|
|
1540
1542
|
);
|
|
1541
1543
|
return out.join(" ");
|
|
@@ -1544,7 +1546,7 @@ function applyVectorCornersAttribute(subpaths, value) {
|
|
|
1544
1546
|
for (const item of value.trim().split(/\s+/)) {
|
|
1545
1547
|
const m = /^(\d+)\.(\d+):([\d.eE+-]+)(?::([a-z]+))?$/.exec(item);
|
|
1546
1548
|
if (!m) continue;
|
|
1547
|
-
const a = _optionalChain([subpaths, 'access',
|
|
1549
|
+
const a = _optionalChain([subpaths, 'access', _30 => _30[+m[1]], 'optionalAccess', _31 => _31.anchors, 'access', _32 => _32[+m[2]]]);
|
|
1548
1550
|
const radius = parseFloat(m[3]);
|
|
1549
1551
|
if (!a || !(radius > 0)) continue;
|
|
1550
1552
|
const kind = VECTOR_CORNER_KINDS.includes(m[4]) ? m[4] : void 0;
|
|
@@ -1556,7 +1558,7 @@ var escapeAttr = (value) => value.replace(/&/g, "&").replace(/"/g, """)
|
|
|
1556
1558
|
function vectorPaintToSvg(paint, gradientId) {
|
|
1557
1559
|
if (!hasPaint(paint)) return { value: "none", gradient: null };
|
|
1558
1560
|
if (typeof paint === "string") return { value: paint, gradient: null };
|
|
1559
|
-
return { value: `url(#${gradientId})`, gradient:
|
|
1561
|
+
return { value: `url(#${gradientId})`, gradient: _chunkVNYRI265cjs.gradientToSvgDef.call(void 0, paint, gradientId) };
|
|
1560
1562
|
}
|
|
1561
1563
|
var partsCache = /* @__PURE__ */ new WeakMap();
|
|
1562
1564
|
function vectorStrokeSvgParts(node, clipId, precision = 3) {
|
|
@@ -1574,22 +1576,22 @@ function computeStrokeSvgParts(node, clipId, precision) {
|
|
|
1574
1576
|
if (parts.align === "center" && !parts.heads.length && !profiled) return void 0;
|
|
1575
1577
|
let clip = null;
|
|
1576
1578
|
if (parts.align !== "center") {
|
|
1577
|
-
const b =
|
|
1579
|
+
const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, path);
|
|
1578
1580
|
const pad = vectorStrokeReach(node) + 1;
|
|
1579
1581
|
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
1582
|
clip = { kind: parts.align === "inside" ? "clip" : "mask", id: clipId, bounds };
|
|
1581
1583
|
}
|
|
1582
1584
|
return {
|
|
1583
1585
|
align: parts.align,
|
|
1584
|
-
d:
|
|
1586
|
+
d: _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, parts.line, { precision }),
|
|
1585
1587
|
width: parts.drawWidth,
|
|
1586
|
-
...profiled && (_nullishCoalesce(node.strokeWidth, () => ( 1))) > 0 ? { outline:
|
|
1588
|
+
...profiled && (_nullishCoalesce(node.strokeWidth, () => ( 1))) > 0 ? { outline: _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, vectorStrokeLineArea(parts, node), { precision }) } : {},
|
|
1587
1589
|
clip,
|
|
1588
|
-
heads: parts.heads.map((h) =>
|
|
1590
|
+
heads: parts.heads.map((h) => _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, h.path, { precision }))
|
|
1589
1591
|
};
|
|
1590
1592
|
}
|
|
1591
1593
|
function widthProfileToAttribute(points, precision = 4) {
|
|
1592
|
-
return points.map((p) => [p.t, p.left, p.right].map((n) =>
|
|
1594
|
+
return points.map((p) => [p.t, p.left, p.right].map((n) => _chunkVNYRI265cjs.formatNumber.call(void 0, n, precision)).join(",")).join(";");
|
|
1593
1595
|
}
|
|
1594
1596
|
function widthProfileFromAttribute(value) {
|
|
1595
1597
|
if (!value) return [];
|
|
@@ -1613,11 +1615,11 @@ function vectorDocumentToSvg(doc, options = {}) {
|
|
|
1613
1615
|
const pretty = options.pretty !== false;
|
|
1614
1616
|
const defs = [];
|
|
1615
1617
|
const lines = [];
|
|
1616
|
-
const num = (n) =>
|
|
1618
|
+
const num = (n) => _chunkVNYRI265cjs.formatNumber.call(void 0, n, precision);
|
|
1617
1619
|
const indent = (depth) => pretty ? " ".repeat(depth) : "";
|
|
1618
1620
|
const common = (node) => {
|
|
1619
1621
|
let out2 = ` id="${escapeAttr(node.id)}"`;
|
|
1620
|
-
if (node.transform) out2 += ` transform="matrix(${node.transform.map((n) =>
|
|
1622
|
+
if (node.transform) out2 += ` transform="matrix(${node.transform.map((n) => _chunkVNYRI265cjs.formatNumber.call(void 0, n, 6)).join(" ")})"`;
|
|
1621
1623
|
if (node.opacity !== void 0 && node.opacity < 1) out2 += ` opacity="${num(node.opacity)}"`;
|
|
1622
1624
|
if (node.visible === false) out2 += ` display="none"`;
|
|
1623
1625
|
return out2;
|
|
@@ -1636,13 +1638,13 @@ function vectorDocumentToSvg(doc, options = {}) {
|
|
|
1636
1638
|
if (stroke.gradient) defs.push(gradientMarkup(stroke.gradient));
|
|
1637
1639
|
const d = vectorPathData(node, precision);
|
|
1638
1640
|
const corners2 = vectorCornersAttribute(node.subpaths, precision);
|
|
1639
|
-
const live = corners2 ? ` data-vector-d="${
|
|
1641
|
+
const live = corners2 ? ` data-vector-d="${_chunkVNYRI265cjs.bezierPathToSvg.call(void 0, subpathsToBezier(node.subpaths, { corners: false }), { precision })}" data-vector-corners="${corners2}"` : "";
|
|
1640
1642
|
const fillAttrs = ` fill="${escapeAttr(fill.value)}"${node.fillRule === "evenodd" ? ` fill-rule="evenodd"` : ""}`;
|
|
1641
1643
|
const lineAttrs = (width) => {
|
|
1642
1644
|
let out2 = ` stroke="${escapeAttr(stroke.value)}" stroke-width="${num(width)}"`;
|
|
1643
1645
|
if (node.strokeLinecap && node.strokeLinecap !== "butt") out2 += ` stroke-linecap="${node.strokeLinecap}"`;
|
|
1644
1646
|
if (node.strokeLinejoin && node.strokeLinejoin !== "miter") out2 += ` stroke-linejoin="${node.strokeLinejoin}"`;
|
|
1645
|
-
if (_optionalChain([node, 'access',
|
|
1647
|
+
if (_optionalChain([node, 'access', _33 => _33.strokeDasharray, 'optionalAccess', _34 => _34.length])) out2 += ` stroke-dasharray="${node.strokeDasharray.map(num).join(" ")}"`;
|
|
1646
1648
|
return out2;
|
|
1647
1649
|
};
|
|
1648
1650
|
const parts = stroke.value !== "none" ? vectorStrokeSvgParts(node, `${prefix}clip-${node.id}`, precision) : void 0;
|
|
@@ -1662,12 +1664,12 @@ function vectorDocumentToSvg(doc, options = {}) {
|
|
|
1662
1664
|
data += ` data-vector-width-profile="${widthProfileToAttribute(profile)}"`;
|
|
1663
1665
|
if (node.strokeLinecap && node.strokeLinecap !== "butt") data += ` data-vector-stroke-linecap="${node.strokeLinecap}"`;
|
|
1664
1666
|
if (node.strokeLinejoin && node.strokeLinejoin !== "miter") data += ` data-vector-stroke-linejoin="${node.strokeLinejoin}"`;
|
|
1665
|
-
if (_optionalChain([node, 'access',
|
|
1667
|
+
if (_optionalChain([node, 'access', _35 => _35.strokeDasharray, 'optionalAccess', _36 => _36.length])) data += ` data-vector-stroke-dasharray="${node.strokeDasharray.map(num).join(" ")}"`;
|
|
1666
1668
|
}
|
|
1667
1669
|
lines.push(`${indent(depth)}<g${common(node)}${data}>`);
|
|
1668
1670
|
lines.push(`${indent(depth + 1)}<path data-vector-part="fill" d="${d}"${fillAttrs}${live}/>`);
|
|
1669
1671
|
if (options.strokes === "outline") {
|
|
1670
|
-
const area =
|
|
1672
|
+
const area = _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, vectorStrokeOutlinePath(subpathsToBezier(node.subpaths), node), { precision });
|
|
1671
1673
|
lines.push(`${indent(depth + 1)}<path data-vector-part="stroke-outline" d="${area}" fill="${escapeAttr(stroke.value)}"/>`);
|
|
1672
1674
|
} else {
|
|
1673
1675
|
let clip = "";
|
|
@@ -1831,7 +1833,7 @@ function resolveGradient(id, raw, seen = /* @__PURE__ */ new Set()) {
|
|
|
1831
1833
|
seen.add(id);
|
|
1832
1834
|
let stops = readStops(el);
|
|
1833
1835
|
const href = _nullishCoalesce(el.attrs.href, () => ( el.attrs["xlink:href"]));
|
|
1834
|
-
if (!stops.length && _optionalChain([href, 'optionalAccess',
|
|
1836
|
+
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
1837
|
if (!stops.length) return null;
|
|
1836
1838
|
if (el.name === "radialGradient") {
|
|
1837
1839
|
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 +1937,7 @@ function parseVectorSvg(svg, options = {}) {
|
|
|
1935
1937
|
const part = (name) => g.children.find((c) => c.name === "path" && c.attrs["data-vector-part"] === name);
|
|
1936
1938
|
const fillEl = part("fill");
|
|
1937
1939
|
const subpaths = fillEl ? shapeOf(fillEl) : null;
|
|
1938
|
-
if (!fillEl || !_optionalChain([subpaths, 'optionalAccess',
|
|
1940
|
+
if (!fillEl || !_optionalChain([subpaths, 'optionalAccess', _41 => _41.length])) return null;
|
|
1939
1941
|
const a = g.attrs;
|
|
1940
1942
|
const fs = readStyle(fillEl, style);
|
|
1941
1943
|
const strokeEl = part("stroke");
|
|
@@ -1972,7 +1974,7 @@ function parseVectorSvg(svg, options = {}) {
|
|
|
1972
1974
|
...profile.length ? { strokeWidthProfile: profile } : {},
|
|
1973
1975
|
...keptCap ? { strokeLinecap: keptCap } : {},
|
|
1974
1976
|
...keptJoin ? { strokeLinejoin: keptJoin } : {},
|
|
1975
|
-
..._optionalChain([keptDash, 'optionalAccess',
|
|
1977
|
+
..._optionalChain([keptDash, 'optionalAccess', _42 => _42.length]) ? { strokeDasharray: keptDash } : {}
|
|
1976
1978
|
};
|
|
1977
1979
|
return placed(node, m);
|
|
1978
1980
|
};
|
|
@@ -2026,7 +2028,7 @@ function parseVectorSvg(svg, options = {}) {
|
|
|
2026
2028
|
// src/vector/snap.ts
|
|
2027
2029
|
var VECTOR_CONSTRUCTION_ANGLES = [0, 45, 90, 135];
|
|
2028
2030
|
function constrainToLeave(leave, p) {
|
|
2029
|
-
if (!_optionalChain([leave, 'optionalAccess',
|
|
2031
|
+
if (!_optionalChain([leave, 'optionalAccess', _43 => _43.constrain])) return p;
|
|
2030
2032
|
const dx = p.x - leave.at.x;
|
|
2031
2033
|
const dy = p.y - leave.at.y;
|
|
2032
2034
|
switch (leave.constrain) {
|
|
@@ -2137,7 +2139,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2137
2139
|
moving.set(r.nodeId, set);
|
|
2138
2140
|
}
|
|
2139
2141
|
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',
|
|
2142
|
+
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
2143
|
return t.index();
|
|
2142
2144
|
}
|
|
2143
2145
|
/**
|
|
@@ -2255,7 +2257,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2255
2257
|
}
|
|
2256
2258
|
const b = vectorNodeBounds(n, parent);
|
|
2257
2259
|
const f = nodeFrame(n, parent, b);
|
|
2258
|
-
if (b) self.pushRect(b, "edge", _nullishCoalesce(_optionalChain([f, 'optionalAccess',
|
|
2260
|
+
if (b) self.pushRect(b, "edge", _nullishCoalesce(_optionalChain([f, 'optionalAccess', _48 => _48.centre]), () => ( null)));
|
|
2259
2261
|
}
|
|
2260
2262
|
};
|
|
2261
2263
|
visit(doc.nodes, IDENTITY_MATRIX);
|
|
@@ -2300,7 +2302,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2300
2302
|
lines: lines2,
|
|
2301
2303
|
labels: [this.label(q, kind)]
|
|
2302
2304
|
});
|
|
2303
|
-
if (_optionalChain([leave, 'optionalAccess',
|
|
2305
|
+
if (_optionalChain([leave, 'optionalAccess', _49 => _49.constrain])) {
|
|
2304
2306
|
const q = constrainToLeave(leave, p);
|
|
2305
2307
|
const hit = this.slide(leave.at, { x: q.x - leave.at.x, y: q.y - leave.at.y }, q, tol, true);
|
|
2306
2308
|
return hit ? { point: hit.point, x: true, y: true, ...this.linedUp(hit.point, hit.from) } : none(q);
|
|
@@ -2316,7 +2318,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2316
2318
|
}
|
|
2317
2319
|
const on = this.onSegment(near2);
|
|
2318
2320
|
if (on) return at2(on, "path");
|
|
2319
|
-
if (_optionalChain([leave, 'optionalAccess',
|
|
2321
|
+
if (_optionalChain([leave, 'optionalAccess', _50 => _50.angles, 'optionalAccess', _51 => _51.length])) {
|
|
2320
2322
|
const c = construction(leave, p, tol);
|
|
2321
2323
|
if (c) {
|
|
2322
2324
|
const hit = this.slide(leave.at, c.dir, c.point, tol, false);
|
|
@@ -2392,13 +2394,13 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2392
2394
|
const pt2 = toPoint(p);
|
|
2393
2395
|
for (const s of this.segments) {
|
|
2394
2396
|
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 =
|
|
2397
|
+
const hit = _chunkVNYRI265cjs.segmentNearest.call(void 0, s.seg, pt2);
|
|
2396
2398
|
if (hit.distance <= tol) out.push({ seg: s.seg, t: hit.t, distance: hit.distance });
|
|
2397
2399
|
}
|
|
2398
2400
|
return out.sort((a, b) => a.distance - b.distance);
|
|
2399
2401
|
}
|
|
2400
2402
|
onSegment(near2) {
|
|
2401
|
-
return near2.length ? toVec2(
|
|
2403
|
+
return near2.length ? toVec2(_chunkVNYRI265cjs.segmentPoint.call(void 0, near2[0].seg, near2[0].t)) : null;
|
|
2402
2404
|
}
|
|
2403
2405
|
/** Where two of the target segments near `p` cross, the crossing nearest `p` within `tol`. */
|
|
2404
2406
|
crossing(near2, p, tol) {
|
|
@@ -2407,7 +2409,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2407
2409
|
let bestD = Infinity;
|
|
2408
2410
|
for (let i = 0; i < list.length; i++) {
|
|
2409
2411
|
for (let j = i + 1; j < list.length; j++) {
|
|
2410
|
-
for (const hit of
|
|
2412
|
+
for (const hit of _chunkVNYRI265cjs.segmentIntersections.call(void 0, list[i].seg, list[j].seg)) {
|
|
2411
2413
|
const q = toVec2(hit.point);
|
|
2412
2414
|
const d = distance(q, p);
|
|
2413
2415
|
if (d <= tol && d < bestD) {
|
|
@@ -2446,7 +2448,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2446
2448
|
* with nothing spaces the box evenly in its row or column. Returns the correction and guides.
|
|
2447
2449
|
*/
|
|
2448
2450
|
snapRect(r, tol, options = {}) {
|
|
2449
|
-
const axes = { x: _optionalChain([options, 'access',
|
|
2451
|
+
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
2452
|
const nearest = (lines, values) => {
|
|
2451
2453
|
let best = null;
|
|
2452
2454
|
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 +2456,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2454
2456
|
};
|
|
2455
2457
|
const bx = axes.x ? nearest(this.xs, [r.x, r.x + r.width / 2, r.x + r.width]) : null;
|
|
2456
2458
|
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',
|
|
2459
|
+
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
2460
|
const done = { ...r, x: r.x + out.dx, y: r.y + out.dy };
|
|
2459
2461
|
if (bx) {
|
|
2460
2462
|
const x = bx.from.x;
|
|
@@ -2577,9 +2579,9 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
|
|
|
2577
2579
|
const on = this.nearestPoint(p, tol);
|
|
2578
2580
|
const tries = [];
|
|
2579
2581
|
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',
|
|
2582
|
+
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 } });
|
|
2583
|
+
tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess', _60 => _60.v]), () => ( null)), ty: null, s: { hx, hy: null, on: null } });
|
|
2584
|
+
tries.push({ tx: null, ty: _nullishCoalesce(_optionalChain([hy, 'optionalAccess', _61 => _61.v]), () => ( null)), s: { hx: null, hy, on: null } });
|
|
2583
2585
|
for (const { tx, ty, s } of tries) {
|
|
2584
2586
|
if (tx === null && ty === null) continue;
|
|
2585
2587
|
const q = applyMatrix(toLocal, { x: _nullishCoalesce(tx, () => ( p.x)), y: _nullishCoalesce(ty, () => ( p.y)) });
|
|
@@ -2729,15 +2731,15 @@ var crossCondition = (r, d) => r[0] * d[1] - r[1] * d[0];
|
|
|
2729
2731
|
function solveOnSegment(seg, base, cond) {
|
|
2730
2732
|
const b = [base.x, base.y];
|
|
2731
2733
|
const g = (t) => {
|
|
2732
|
-
const p =
|
|
2733
|
-
return cond([p[0] - b[0], p[1] - b[1]],
|
|
2734
|
+
const p = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, t);
|
|
2735
|
+
return cond([p[0] - b[0], p[1] - b[1]], _chunkVNYRI265cjs.segmentDerivative.call(void 0, seg, t));
|
|
2734
2736
|
};
|
|
2735
2737
|
const vals = [];
|
|
2736
2738
|
let scale = 0;
|
|
2737
2739
|
for (let i = 0; i <= CURVE_SAMPLES; i++) {
|
|
2738
2740
|
const t = i / CURVE_SAMPLES;
|
|
2739
|
-
const p =
|
|
2740
|
-
const d =
|
|
2741
|
+
const p = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, t);
|
|
2742
|
+
const d = _chunkVNYRI265cjs.segmentDerivative.call(void 0, seg, t);
|
|
2741
2743
|
const r = [p[0] - b[0], p[1] - b[1]];
|
|
2742
2744
|
vals.push(cond(r, d));
|
|
2743
2745
|
scale = Math.max(scale, Math.hypot(r[0], r[1]) * Math.hypot(d[0], d[1]));
|
|
@@ -2764,8 +2766,8 @@ function solveOnSegment(seg, base, cond) {
|
|
|
2764
2766
|
} else hi = m;
|
|
2765
2767
|
}
|
|
2766
2768
|
const t = (lo + hi) / 2;
|
|
2767
|
-
const p =
|
|
2768
|
-
const dv =
|
|
2769
|
+
const p = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, t);
|
|
2770
|
+
const dv = _chunkVNYRI265cjs.segmentDerivative.call(void 0, seg, t);
|
|
2769
2771
|
const r = Math.hypot(p[0] - b[0], p[1] - b[1]);
|
|
2770
2772
|
const dl = Math.hypot(dv[0], dv[1]);
|
|
2771
2773
|
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 +2804,7 @@ function endTangent(c) {
|
|
|
2802
2804
|
return [1, 0];
|
|
2803
2805
|
}
|
|
2804
2806
|
function sample(c, n, out, withStart) {
|
|
2805
|
-
for (let i = withStart ? 0 : 1; i <= n; i++) out.push(
|
|
2807
|
+
for (let i = withStart ? 0 : 1; i <= n; i++) out.push(_chunkVNYRI265cjs.segmentPoint.call(void 0, c, i / n));
|
|
2806
2808
|
}
|
|
2807
2809
|
var onAnchor2 = (a, h) => !h || Math.abs(h.x - a.x) < EPS3 && Math.abs(h.y - a.y) < EPS3;
|
|
2808
2810
|
function tidy(a, keepType = true) {
|
|
@@ -2848,7 +2850,7 @@ function fitAcross(pts, N, t0, t1) {
|
|
|
2848
2850
|
const u = [];
|
|
2849
2851
|
for (let i = 0; i <= N; i++) u.push(k * i / N);
|
|
2850
2852
|
for (let i = 1; i <= N; i++) u.push(k + (1 - k) * i / N);
|
|
2851
|
-
return
|
|
2853
|
+
return _chunkVNYRI265cjs.fitCubicWithTangents.call(void 0, pts, u, t0, t1);
|
|
2852
2854
|
};
|
|
2853
2855
|
return goldenMin(fit, 0, 1);
|
|
2854
2856
|
}
|
|
@@ -2908,7 +2910,7 @@ function bendSegment(sp, segment, t, p) {
|
|
|
2908
2910
|
return { anchors, closed: sp.closed };
|
|
2909
2911
|
}
|
|
2910
2912
|
function subpathPointAt(sp, segment, t) {
|
|
2911
|
-
const [x, y] =
|
|
2913
|
+
const [x, y] = _chunkVNYRI265cjs.segmentPoint.call(void 0, subpathSegment(sp, segment), t);
|
|
2912
2914
|
return { x, y };
|
|
2913
2915
|
}
|
|
2914
2916
|
function curvatureMoveAnchor(sp, index, q) {
|
|
@@ -3169,12 +3171,12 @@ function removeRedundantPoints(sp, tolerance) {
|
|
|
3169
3171
|
}
|
|
3170
3172
|
|
|
3171
3173
|
// src/vector/pathCut.ts
|
|
3172
|
-
var loopArea = (l) =>
|
|
3174
|
+
var loopArea = (l) => _chunkVNYRI265cjs.contourSignedArea.call(void 0, l.segs);
|
|
3173
3175
|
function loopSample(l) {
|
|
3174
3176
|
const k = l.chord.findIndex((c) => !c);
|
|
3175
|
-
return
|
|
3177
|
+
return _chunkVNYRI265cjs.segmentPoint.call(void 0, l.segs[k >= 0 ? k : 0], 0.5);
|
|
3176
3178
|
}
|
|
3177
|
-
var contains2 = (l, p) =>
|
|
3179
|
+
var contains2 = (l, p) => _chunkVNYRI265cjs.windingNumber.call(void 0, [l.segs], p) !== 0;
|
|
3178
3180
|
function groupFaces(loops) {
|
|
3179
3181
|
const usable2 = loops.filter((l) => l.segs.length && Math.abs(loopArea(l)) > 1e-12);
|
|
3180
3182
|
if (!usable2.length) return [];
|
|
@@ -3190,12 +3192,12 @@ function groupFaces(loops) {
|
|
|
3190
3192
|
return outers.reverse().map((o) => faces.get(o));
|
|
3191
3193
|
}
|
|
3192
3194
|
function faceToPath(face) {
|
|
3193
|
-
return
|
|
3195
|
+
return _chunkVNYRI265cjs.contoursToPath.call(void 0, face.loops.map((l) => ({ segments: l.segs, closed: true })));
|
|
3194
3196
|
}
|
|
3195
3197
|
function facesOf(path, fillRule) {
|
|
3196
|
-
const normalized =
|
|
3197
|
-
const loops =
|
|
3198
|
-
const segs =
|
|
3198
|
+
const normalized = _chunkVNYRI265cjs.normalizeBezierPath.call(void 0, path, fillRule);
|
|
3199
|
+
const loops = _chunkVNYRI265cjs.pathToContours.call(void 0, normalized).map((c) => {
|
|
3200
|
+
const segs = _chunkVNYRI265cjs.closeContour.call(void 0, c, true).map((s) => s.slice());
|
|
3199
3201
|
return { segs, chord: segs.map(() => false) };
|
|
3200
3202
|
});
|
|
3201
3203
|
return groupFaces(loops);
|
|
@@ -3265,7 +3267,7 @@ function lineHits(p, q, seg) {
|
|
|
3265
3267
|
const scale = Math.sqrt(len2) * Math.max(1, ...seg.map((pt2) => Math.abs(pt2[0]) + Math.abs(pt2[1])));
|
|
3266
3268
|
const out = [];
|
|
3267
3269
|
for (const t of rootsInUnit(...coeffs, scale)) {
|
|
3268
|
-
const point =
|
|
3270
|
+
const point = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, t);
|
|
3269
3271
|
const s = ((point[0] - p[0]) * dx + (point[1] - p[1]) * dy) / len2;
|
|
3270
3272
|
if (s >= -1e-9 && s <= 1 + 1e-9) out.push({ s: Math.min(1, Math.max(0, s)), t, point });
|
|
3271
3273
|
}
|
|
@@ -3278,7 +3280,7 @@ function arc(l, a, b, eps) {
|
|
|
3278
3280
|
const segs = [];
|
|
3279
3281
|
const chord = [];
|
|
3280
3282
|
const push = (k, t0, t1) => {
|
|
3281
|
-
const piece = t0 <= 0 && t1 >= 1 ? l.segs[k].slice() :
|
|
3283
|
+
const piece = t0 <= 0 && t1 >= 1 ? l.segs[k].slice() : _chunkVNYRI265cjs.subSegment.call(void 0, l.segs[k], t0, t1);
|
|
3282
3284
|
if (!degenerate(piece, eps)) {
|
|
3283
3285
|
segs.push(piece);
|
|
3284
3286
|
chord.push(l.chord[k]);
|
|
@@ -3303,7 +3305,7 @@ function knifePath(path, fillRule, knife) {
|
|
|
3303
3305
|
if (pts.length < 2) return null;
|
|
3304
3306
|
let faces = facesOf(path, fillRule);
|
|
3305
3307
|
if (!faces.length) return null;
|
|
3306
|
-
const b =
|
|
3308
|
+
const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, path);
|
|
3307
3309
|
const size = b ? Math.max(b.maxX - b.minX, b.maxY - b.minY, 1) : 1;
|
|
3308
3310
|
const eps = size * 1e-9;
|
|
3309
3311
|
let cursor = -Infinity;
|
|
@@ -3317,7 +3319,7 @@ function knifePath(path, fillRule, knife) {
|
|
|
3317
3319
|
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
3320
|
face2.loops.forEach(
|
|
3319
3321
|
(l, li) => l.segs.forEach((seg, si) => {
|
|
3320
|
-
const sb =
|
|
3322
|
+
const sb = _chunkVNYRI265cjs.segmentBounds.call(void 0, seg);
|
|
3321
3323
|
if (sb.maxX < kb.minX - eps || sb.minX > kb.maxX + eps || sb.maxY < kb.minY - eps || sb.minY > kb.maxY + eps) return;
|
|
3322
3324
|
for (const h of lineHits(pts[m], pts[m + 1], seg)) {
|
|
3323
3325
|
const s = m + h.s;
|
|
@@ -3332,7 +3334,7 @@ function knifePath(path, fillRule, knife) {
|
|
|
3332
3334
|
const m = Math.min(pts.length - 2, Math.floor(s));
|
|
3333
3335
|
const u = s - m;
|
|
3334
3336
|
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
|
|
3337
|
+
return _chunkVNYRI265cjs.windingNumber.call(void 0, face2.loops.map((l) => l.segs), q) !== 0;
|
|
3336
3338
|
};
|
|
3337
3339
|
for (let i = 0; i < unique.length - 1; i++) {
|
|
3338
3340
|
const from2 = unique[i];
|
|
@@ -3392,33 +3394,33 @@ function eraserRegion(points, width) {
|
|
|
3392
3394
|
];
|
|
3393
3395
|
}
|
|
3394
3396
|
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
|
|
3397
|
+
return _chunkVNYRI265cjs.outlineStroke.call(void 0, line2, { width, cap: "round", join: "round" });
|
|
3396
3398
|
}
|
|
3397
3399
|
function eraseFromFill(path, fillRule, region) {
|
|
3398
|
-
const overlap =
|
|
3399
|
-
if (!
|
|
3400
|
-
const rest =
|
|
3400
|
+
const overlap = _chunkVNYRI265cjs.pathBoolean.call(void 0, "intersection", [{ path, fillRule }, { path: region }]).path;
|
|
3401
|
+
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;
|
|
3402
|
+
const rest = _chunkVNYRI265cjs.pathBoolean.call(void 0, "difference", [{ path, fillRule }, { path: region }]).path;
|
|
3401
3403
|
return splitIntoFaces(rest);
|
|
3402
3404
|
}
|
|
3403
3405
|
function eraseFromOutline(sp, region) {
|
|
3404
|
-
const regionSegs =
|
|
3406
|
+
const regionSegs = _chunkVNYRI265cjs.pathToContours.call(void 0, region).flatMap((c) => _chunkVNYRI265cjs.closeContour.call(void 0, c, true));
|
|
3405
3407
|
if (!regionSegs.length) return null;
|
|
3406
|
-
const rb =
|
|
3408
|
+
const rb = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, region);
|
|
3407
3409
|
const count = subpathSegmentCount(sp);
|
|
3408
3410
|
if (!rb || count === 0) return null;
|
|
3409
|
-
const removed = (p) =>
|
|
3411
|
+
const removed = (p) => _chunkVNYRI265cjs.pointInBezierPath.call(void 0, region, p, "nonzero");
|
|
3410
3412
|
const runs = [];
|
|
3411
3413
|
let cur = [];
|
|
3412
3414
|
let any = false;
|
|
3413
3415
|
for (let i = 0; i < count; i++) {
|
|
3414
3416
|
const seg = subpathSegment(sp, i);
|
|
3415
|
-
const sb =
|
|
3417
|
+
const sb = _chunkVNYRI265cjs.segmentBounds.call(void 0, seg);
|
|
3416
3418
|
const ts = [0, 1];
|
|
3417
3419
|
if (!(sb.maxX < rb.minX || sb.minX > rb.maxX || sb.maxY < rb.minY || sb.minY > rb.maxY)) {
|
|
3418
3420
|
for (const r of regionSegs) {
|
|
3419
|
-
const b =
|
|
3421
|
+
const b = _chunkVNYRI265cjs.segmentBounds.call(void 0, r);
|
|
3420
3422
|
if (b.maxX < sb.minX || b.minX > sb.maxX || b.maxY < sb.minY || b.minY > sb.maxY) continue;
|
|
3421
|
-
for (const hit of
|
|
3423
|
+
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
3424
|
}
|
|
3423
3425
|
}
|
|
3424
3426
|
ts.sort((a, b) => a - b);
|
|
@@ -3426,7 +3428,7 @@ function eraseFromOutline(sp, region) {
|
|
|
3426
3428
|
const t0 = ts[k];
|
|
3427
3429
|
const t1 = ts[k + 1];
|
|
3428
3430
|
if (t1 - t0 < 1e-9) continue;
|
|
3429
|
-
if (removed(
|
|
3431
|
+
if (removed(_chunkVNYRI265cjs.segmentPoint.call(void 0, seg, (t0 + t1) / 2))) {
|
|
3430
3432
|
any = true;
|
|
3431
3433
|
if (cur.length) runs.push(cur);
|
|
3432
3434
|
cur = [];
|
|
@@ -3445,7 +3447,7 @@ function eraseFromOutline(sp, region) {
|
|
|
3445
3447
|
for (const run of runs) {
|
|
3446
3448
|
const anchors = [];
|
|
3447
3449
|
for (const { seg, t0, t1 } of run) {
|
|
3448
|
-
const c =
|
|
3450
|
+
const c = _chunkVNYRI265cjs.subSegment.call(void 0, subpathSegment(sp, seg), t0, t1);
|
|
3449
3451
|
const line2 = c.length === 2;
|
|
3450
3452
|
const start = c[0];
|
|
3451
3453
|
const end = c[c.length - 1];
|
|
@@ -3753,14 +3755,14 @@ function worldOf(entry, subpaths) {
|
|
|
3753
3755
|
return vectorPathWorldBezier({ ...entry.node, subpaths }, entry.parent);
|
|
3754
3756
|
}
|
|
3755
3757
|
function subpathEnclosesArea(sp) {
|
|
3756
|
-
const contour =
|
|
3758
|
+
const contour = _chunkVNYRI265cjs.pathToContours.call(void 0, subpathsToBezier([{ ...sp, closed: true }]))[0];
|
|
3757
3759
|
if (!contour) return false;
|
|
3758
|
-
const segs =
|
|
3759
|
-
const b =
|
|
3760
|
+
const segs = _chunkVNYRI265cjs.closeContour.call(void 0, contour, true);
|
|
3761
|
+
const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, _chunkVNYRI265cjs.contoursToPath.call(void 0, [{ segments: segs, closed: true }]));
|
|
3760
3762
|
if (!b) return false;
|
|
3761
3763
|
const w = b.maxX - b.minX;
|
|
3762
3764
|
const h = b.maxY - b.minY;
|
|
3763
|
-
return Math.abs(
|
|
3765
|
+
return Math.abs(_chunkVNYRI265cjs.contourSignedArea.call(void 0, segs)) > 1e-9 * (w * w + h * h);
|
|
3764
3766
|
}
|
|
3765
3767
|
var paintKey = (paint) => typeof paint === "string" ? paint.trim().toLowerCase() : JSON.stringify(_nullishCoalesce(paint, () => ( null)));
|
|
3766
3768
|
function vectorPathfinderShape(entry, op) {
|
|
@@ -3813,31 +3815,50 @@ function vectorShapeBuilderMap(entries) {
|
|
|
3813
3815
|
lines.push(!subpaths.some((s) => s.closed));
|
|
3814
3816
|
return { path: worldOf(entry, subpaths), fillRule: _nullishCoalesce(entry.node.fillRule, () => ( "nonzero")) };
|
|
3815
3817
|
});
|
|
3816
|
-
const map =
|
|
3818
|
+
const map = _chunkVNYRI265cjs.PlanarMap.build(inputs);
|
|
3817
3819
|
if (!map) return null;
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3820
|
+
let chains = null;
|
|
3821
|
+
const runs = (line2) => (chains ??= map.chains()).filter((c) => lines[c.source] === line2 && !(line2 && c.closed)).map((c) => {
|
|
3822
|
+
const path = _chunkVNYRI265cjs.contoursToPath.call(void 0, [{ segments: c.segments, closed: c.closed }]);
|
|
3823
|
+
return { path, segments: c.segments, closed: c.closed, source: c.source, bounds: _chunkVNYRI265cjs.bezierPathBounds.call(void 0, path) };
|
|
3821
3824
|
});
|
|
3822
|
-
|
|
3825
|
+
const pieces = lines.some(Boolean) ? runs(true) : [];
|
|
3826
|
+
let edges = null;
|
|
3827
|
+
let size = 0;
|
|
3828
|
+
for (const input of inputs) {
|
|
3829
|
+
const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, input.path);
|
|
3830
|
+
if (b) size = Math.max(size, b.maxX - b.minX, b.maxY - b.minY);
|
|
3831
|
+
}
|
|
3832
|
+
return {
|
|
3833
|
+
entries: [...entries],
|
|
3834
|
+
map,
|
|
3835
|
+
lines,
|
|
3836
|
+
pieces,
|
|
3837
|
+
get edges() {
|
|
3838
|
+
return edges ??= runs(false);
|
|
3839
|
+
},
|
|
3840
|
+
tolerance: 0.2 * Math.max(size / 2e3, 0.25)
|
|
3841
|
+
};
|
|
3823
3842
|
}
|
|
3824
|
-
function
|
|
3843
|
+
function pieceNear(pieces, p, tol) {
|
|
3825
3844
|
const point = [p.x, p.y];
|
|
3845
|
+
let best = null;
|
|
3846
|
+
pieces.forEach((piece, index) => {
|
|
3847
|
+
const b = piece.bounds;
|
|
3848
|
+
if (p.x < b.minX - tol || p.x > b.maxX + tol || p.y < b.minY - tol || p.y > b.maxY + tol) return;
|
|
3849
|
+
const d = _chunkVNYRI265cjs.distanceToBezierPath.call(void 0, piece.path, point);
|
|
3850
|
+
if (d <= tol && (!best || d < best.d)) best = { index, d };
|
|
3851
|
+
});
|
|
3852
|
+
return best;
|
|
3853
|
+
}
|
|
3854
|
+
function vectorShapeBuilderHit(m, p, lineTolerance = null) {
|
|
3826
3855
|
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 };
|
|
3856
|
+
const line2 = pieceNear(m.pieces, p, lineTolerance);
|
|
3857
|
+
const edge = pieceNear(m.edges, p, lineTolerance);
|
|
3858
|
+
if (edge && (!line2 || edge.d < line2.d)) return { edge: edge.index };
|
|
3859
|
+
if (line2) return { line: line2.index };
|
|
3839
3860
|
}
|
|
3840
|
-
const face = m.map.faceAt(
|
|
3861
|
+
const face = m.map.faceAt([p.x, p.y]);
|
|
3841
3862
|
return face >= 0 ? { face } : null;
|
|
3842
3863
|
}
|
|
3843
3864
|
function samplePolyline(points, step) {
|
|
@@ -3855,25 +3876,31 @@ function samplePolyline(points, step) {
|
|
|
3855
3876
|
}
|
|
3856
3877
|
function addBuilderHit(touched, hit) {
|
|
3857
3878
|
if (!hit) return false;
|
|
3858
|
-
const [list, i] = "face" in hit ? [touched.faces, hit.face] : [touched.lines, hit.line];
|
|
3879
|
+
const [list, i] = "face" in hit ? [touched.faces, hit.face] : "line" in hit ? [touched.lines, hit.line] : [touched.edges, hit.edge];
|
|
3859
3880
|
if (list.includes(i)) return false;
|
|
3860
3881
|
list.push(i);
|
|
3861
3882
|
return true;
|
|
3862
3883
|
}
|
|
3863
3884
|
function sides(m, piece) {
|
|
3864
3885
|
const seg = piece.segments[Math.floor(piece.segments.length / 2)];
|
|
3865
|
-
const mid =
|
|
3866
|
-
const t =
|
|
3886
|
+
const mid = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, 0.5);
|
|
3887
|
+
const t = _chunkVNYRI265cjs.segmentTangent.call(void 0, seg, 0.5);
|
|
3867
3888
|
const chord = Math.hypot(seg[seg.length - 1][0] - seg[0][0], seg[seg.length - 1][1] - seg[0][1]);
|
|
3868
3889
|
const off = Math.max(1e-6, Math.min(0.05, 0.05 * chord));
|
|
3869
3890
|
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
3891
|
}
|
|
3892
|
+
function vectorBuilderErasedEdges(m, touched) {
|
|
3893
|
+
if (!touched.edges.length) return [];
|
|
3894
|
+
const faces = new Set(touched.faces);
|
|
3895
|
+
return touched.edges.filter((k) => m.edges[k] && !sides(m, m.edges[k]).some((f) => f >= 0 && faces.has(f)));
|
|
3896
|
+
}
|
|
3871
3897
|
function planShapeBuilder(m, touched, erase) {
|
|
3872
3898
|
const replace = /* @__PURE__ */ new Map();
|
|
3873
3899
|
const picked = new Set(touched.faces);
|
|
3874
3900
|
const faces = m.map.faces;
|
|
3875
3901
|
const sourcesOf = faces.map((_, i) => m.map.faceSources(i));
|
|
3876
|
-
m.
|
|
3902
|
+
const cuts = erase ? vectorBuilderErasedEdges(m, touched).map((k) => m.edges[k]) : [];
|
|
3903
|
+
m.entries.forEach((entry, i) => {
|
|
3877
3904
|
if (m.lines[i]) {
|
|
3878
3905
|
const own = m.pieces.flatMap((piece, k) => piece.source === i ? [k] : []);
|
|
3879
3906
|
const keep = own.filter((k) => !touched.lines.includes(k) && !sides(m, m.pieces[k]).every((f) => f >= 0 && picked.has(f)));
|
|
@@ -3881,10 +3908,24 @@ function planShapeBuilder(m, touched, erase) {
|
|
|
3881
3908
|
replace.set(i, keep.length ? { kind: "pieces", paths: keep.map((k) => m.pieces[k].path) } : null);
|
|
3882
3909
|
return;
|
|
3883
3910
|
}
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3911
|
+
const inUnion = touched.faces.some((f) => sourcesOf[f].includes(i));
|
|
3912
|
+
if (!inUnion && !cuts.length) return;
|
|
3913
|
+
let rest;
|
|
3914
|
+
if (inUnion) {
|
|
3915
|
+
const kept = faces.flatMap((_, f) => sourcesOf[f].includes(i) && !picked.has(f) ? [f] : []);
|
|
3916
|
+
rest = kept.length ? m.map.merge(kept) : [];
|
|
3917
|
+
} else rest = worldOf(entry, entry.node.subpaths.filter(usable));
|
|
3918
|
+
const fillCloses = hasPaint(entry.node.fill);
|
|
3919
|
+
let cut = false;
|
|
3920
|
+
for (const piece of cuts) {
|
|
3921
|
+
const r = rest.length ? _chunkVNYRI265cjs.cutOutPiece.call(void 0, rest, piece, fillCloses, m.tolerance) : null;
|
|
3922
|
+
if (r) {
|
|
3923
|
+
rest = r;
|
|
3924
|
+
cut = true;
|
|
3925
|
+
}
|
|
3926
|
+
}
|
|
3927
|
+
if (!inUnion && !cut) return;
|
|
3928
|
+
replace.set(i, rest.length ? { kind: inUnion ? "fill" : "outline", path: rest } : null);
|
|
3888
3929
|
});
|
|
3889
3930
|
let merged = null;
|
|
3890
3931
|
if (!erase && touched.faces.length) {
|
|
@@ -3898,7 +3939,7 @@ function planShapeBuilder(m, touched, erase) {
|
|
|
3898
3939
|
}
|
|
3899
3940
|
function vectorFillMap(doc, gap = 0) {
|
|
3900
3941
|
const entries = vectorPathEntries(doc, null, { locked: true });
|
|
3901
|
-
return
|
|
3942
|
+
return _chunkVNYRI265cjs.PlanarMap.build(
|
|
3902
3943
|
entries.map((e) => ({ path: worldOf(e, e.node.subpaths.filter(usable)), fills: false })),
|
|
3903
3944
|
{ gap, maxSegments: 2e4 }
|
|
3904
3945
|
);
|
|
@@ -3960,7 +4001,7 @@ function getEditablePathIds(state) {
|
|
|
3960
4001
|
}
|
|
3961
4002
|
}
|
|
3962
4003
|
}
|
|
3963
|
-
return [...ids].filter((id) => _optionalChain([findVectorNode, 'call',
|
|
4004
|
+
return [...ids].filter((id) => _optionalChain([findVectorNode, 'call', _62 => _62(state.document.nodes, id), 'optionalAccess', _63 => _63.type]) === "path");
|
|
3964
4005
|
}
|
|
3965
4006
|
function getVisibleAnchors(state) {
|
|
3966
4007
|
const out = [];
|
|
@@ -3975,7 +4016,7 @@ function getVisibleHandles(state) {
|
|
|
3975
4016
|
const seen = /* @__PURE__ */ new Set();
|
|
3976
4017
|
const push = (node, s, i, handle) => {
|
|
3977
4018
|
const sp = node.subpaths[s];
|
|
3978
|
-
const a = _optionalChain([sp, 'optionalAccess',
|
|
4019
|
+
const a = _optionalChain([sp, 'optionalAccess', _64 => _64.anchors, 'access', _65 => _65[i]]);
|
|
3979
4020
|
if (!a || !a[handle]) return;
|
|
3980
4021
|
const key = `${node.id}:${s}:${i}:${handle}`;
|
|
3981
4022
|
if (seen.has(key)) return;
|
|
@@ -3984,8 +4025,8 @@ function getVisibleHandles(state) {
|
|
|
3984
4025
|
};
|
|
3985
4026
|
if (state.tool === "pen" && state.pen) {
|
|
3986
4027
|
const node = findVectorNode(state.document.nodes, state.pen.nodeId);
|
|
3987
|
-
const sp = _optionalChain([node, 'optionalAccess',
|
|
3988
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
4028
|
+
const sp = _optionalChain([node, 'optionalAccess', _66 => _66.type]) === "path" ? node.subpaths[state.pen.subpath] : void 0;
|
|
4029
|
+
if (_optionalChain([node, 'optionalAccess', _67 => _67.type]) === "path" && sp) {
|
|
3989
4030
|
const last = sp.anchors.length - 1;
|
|
3990
4031
|
push(node, state.pen.subpath, last, "in");
|
|
3991
4032
|
push(node, state.pen.subpath, last, "out");
|
|
@@ -4023,11 +4064,11 @@ function getVectorCornerWidgets(state) {
|
|
|
4023
4064
|
const side = Math.min(c.lu, c.lv);
|
|
4024
4065
|
if (side * zoom < 3 * VECTOR_CORNER_WIDGET_INSET) continue;
|
|
4025
4066
|
const a = node.subpaths[c.subpath].anchors[c.index];
|
|
4026
|
-
const radius = _nullishCoalesce(_optionalChain([a, 'access',
|
|
4067
|
+
const radius = _nullishCoalesce(_optionalChain([a, 'access', _68 => _68.corner, 'optionalAccess', _69 => _69.radius]), () => ( 0));
|
|
4027
4068
|
const drawn = fitCornerRadius(c, radius);
|
|
4028
4069
|
const k = Math.min(Math.max(drawn / c.sin, VECTOR_CORNER_WIDGET_INSET / (zoom * Math.sqrt(1 + c.cos))), side / 2);
|
|
4029
4070
|
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',
|
|
4071
|
+
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
4072
|
}
|
|
4032
4073
|
}
|
|
4033
4074
|
return out;
|
|
@@ -4044,13 +4085,13 @@ function getVectorWidthHandles(state) {
|
|
|
4044
4085
|
const n = findVectorNode(state.document.nodes, id);
|
|
4045
4086
|
if (n) for (const p of collectPathNodes(n)) ids.add(p.id);
|
|
4046
4087
|
}
|
|
4047
|
-
if (_optionalChain([state, 'access',
|
|
4048
|
-
if (_optionalChain([state, 'access',
|
|
4088
|
+
if (_optionalChain([state, 'access', _72 => _72.hover, 'optionalAccess', _73 => _73.nodeId])) ids.add(state.hover.nodeId);
|
|
4089
|
+
if (_optionalChain([state, 'access', _74 => _74.interaction, 'optionalAccess', _75 => _75.type]) === "width") ids.add(state.interaction.ref.nodeId);
|
|
4049
4090
|
if (state.selectedWidthPoint) ids.add(state.selectedWidthPoint.nodeId);
|
|
4050
4091
|
const out = [];
|
|
4051
4092
|
for (const id of ids) {
|
|
4052
4093
|
const node = findVectorNode(state.document.nodes, id);
|
|
4053
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
4094
|
+
if (_optionalChain([node, 'optionalAccess', _76 => _76.type]) !== "path" || node.visible === false || !_optionalChain([node, 'access', _77 => _77.strokeWidthProfile, 'optionalAccess', _78 => _78.length])) continue;
|
|
4054
4095
|
const g = vectorStrokeWidthGeometry(node);
|
|
4055
4096
|
if (!g) continue;
|
|
4056
4097
|
const profile = sanitizeWidthProfile(node.strokeWidthProfile);
|
|
@@ -4084,7 +4125,7 @@ function getVectorWidthHandles(state) {
|
|
|
4084
4125
|
}
|
|
4085
4126
|
function getAnchor(doc, ref) {
|
|
4086
4127
|
const node = findVectorNode(doc.nodes, ref.nodeId);
|
|
4087
|
-
return _optionalChain([node, 'optionalAccess',
|
|
4128
|
+
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
4129
|
}
|
|
4089
4130
|
function getAnchorWorld(doc, ref) {
|
|
4090
4131
|
const a = getAnchor(doc, ref);
|
|
@@ -4383,7 +4424,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4383
4424
|
notify(docChanged = false) {
|
|
4384
4425
|
this.revision++;
|
|
4385
4426
|
this.state = this.computeState();
|
|
4386
|
-
if (docChanged) _optionalChain([this, 'access',
|
|
4427
|
+
if (docChanged) _optionalChain([this, 'access', _84 => _84.onChange, 'optionalCall', _85 => _85(this.doc)]);
|
|
4387
4428
|
const state = this.state;
|
|
4388
4429
|
this.listeners.forEach((listener) => {
|
|
4389
4430
|
try {
|
|
@@ -4413,26 +4454,26 @@ var VectorEditorController = (_class3 = class {
|
|
|
4413
4454
|
return applyMatrix(invertMatrix(this.worldOf(id, doc)), p);
|
|
4414
4455
|
}
|
|
4415
4456
|
cursorFor() {
|
|
4416
|
-
if (_optionalChain([this, 'access',
|
|
4417
|
-
if (_optionalChain([this, 'access',
|
|
4418
|
-
if (_optionalChain([this, 'access',
|
|
4457
|
+
if (_optionalChain([this, 'access', _86 => _86.drag, 'optionalAccess', _87 => _87.kind]) === "pan" || this.spaceHeld) return this.drag ? "grabbing" : "grab";
|
|
4458
|
+
if (_optionalChain([this, 'access', _88 => _88.drag, 'optionalAccess', _89 => _89.kind]) === "rotate") return "grabbing";
|
|
4459
|
+
if (_optionalChain([this, 'access', _90 => _90.drag, 'optionalAccess', _91 => _91.kind]) === "move") return "move";
|
|
4419
4460
|
const h = this.hover;
|
|
4420
4461
|
switch (this.tool) {
|
|
4421
4462
|
case "select":
|
|
4422
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
4423
|
-
return _optionalChain([h, 'optionalAccess',
|
|
4463
|
+
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)));
|
|
4464
|
+
return _optionalChain([h, 'optionalAccess', _96 => _96.nodeId]) ? "move" : "default";
|
|
4424
4465
|
case "direct":
|
|
4425
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
4426
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
4427
|
-
return _optionalChain([h, 'optionalAccess',
|
|
4466
|
+
if (_optionalChain([h, 'optionalAccess', _97 => _97.anchor]) || _optionalChain([h, 'optionalAccess', _98 => _98.handle]) || _optionalChain([h, 'optionalAccess', _99 => _99.corner])) return "pointer";
|
|
4467
|
+
if (_optionalChain([h, 'optionalAccess', _100 => _100.segment])) return "copy";
|
|
4468
|
+
return _optionalChain([h, 'optionalAccess', _101 => _101.nodeId]) ? "move" : "default";
|
|
4428
4469
|
case "pen":
|
|
4429
|
-
return _optionalChain([h, 'optionalAccess',
|
|
4470
|
+
return _optionalChain([h, 'optionalAccess', _102 => _102.anchor]) ? "pointer" : "crosshair";
|
|
4430
4471
|
case "width":
|
|
4431
|
-
if (_optionalChain([this, 'access',
|
|
4432
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
4433
|
-
return _optionalChain([h, 'optionalAccess',
|
|
4472
|
+
if (_optionalChain([this, 'access', _103 => _103.drag, 'optionalAccess', _104 => _104.kind]) === "width") return this.drag.mode === "move" ? "grabbing" : "ew-resize";
|
|
4473
|
+
if (_optionalChain([h, 'optionalAccess', _105 => _105.widthPoint])) return h.widthPoint.part === "center" ? "grab" : "ew-resize";
|
|
4474
|
+
return _optionalChain([h, 'optionalAccess', _106 => _106.strokeSpot]) ? "copy" : "default";
|
|
4434
4475
|
case "shapeBuilder":
|
|
4435
|
-
if (!_optionalChain([this, 'access',
|
|
4476
|
+
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
4477
|
return this.builderPreview.mode === "erase" ? "not-allowed" : "cell";
|
|
4437
4478
|
case "paintBucket":
|
|
4438
4479
|
return this.builderPreview ? "cell" : "crosshair";
|
|
@@ -4455,7 +4496,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4455
4496
|
this.selection = s.selection.filter((id) => this.getNode(id));
|
|
4456
4497
|
this.anchors = s.anchors.filter((r) => getAnchor(this.doc, r));
|
|
4457
4498
|
this.editingId = s.editingId && this.getNode(s.editingId) ? s.editingId : null;
|
|
4458
|
-
this.pen = s.pen && _optionalChain([this, 'access',
|
|
4499
|
+
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;
|
|
4459
4500
|
} finally {
|
|
4460
4501
|
this.applying = false;
|
|
4461
4502
|
}
|
|
@@ -4622,7 +4663,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4622
4663
|
if (res.kind) {
|
|
4623
4664
|
this.snappedToObject = true;
|
|
4624
4665
|
this.setGuides(res);
|
|
4625
|
-
return _optionalChain([leave, 'optionalAccess',
|
|
4666
|
+
return _optionalChain([leave, 'optionalAccess', _117 => _117.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
4667
|
}
|
|
4627
4668
|
}
|
|
4628
4669
|
this.setGuides(null);
|
|
@@ -4640,14 +4681,14 @@ var VectorEditorController = (_class3 = class {
|
|
|
4640
4681
|
/** Where the pointer at `p` would place a point with the pen or a shape tool (and the guides showing why). */
|
|
4641
4682
|
hoverSnap(p, input) {
|
|
4642
4683
|
if (this.tool === "pen") {
|
|
4643
|
-
const sp = this.pen ? _optionalChain([this, 'access',
|
|
4644
|
-
if (this.pen && sp && _optionalChain([this, 'access',
|
|
4684
|
+
const sp = this.pen ? _optionalChain([this, 'access', _118 => _118.getNode, 'call', _119 => _119(this.pen.nodeId), 'optionalAccess', _120 => _120.subpaths, 'access', _121 => _121[this.pen.subpath]]) : void 0;
|
|
4685
|
+
if (this.pen && sp && _optionalChain([this, 'access', _122 => _122.hover, 'optionalAccess', _123 => _123.anchor])) {
|
|
4645
4686
|
this.setGuides(null);
|
|
4646
4687
|
return p;
|
|
4647
4688
|
}
|
|
4648
4689
|
const last = this.pen && sp ? getAnchorWorld(this.doc, { nodeId: this.pen.nodeId, subpath: this.pen.subpath, index: sp.anchors.length - 1 }) : void 0;
|
|
4649
4690
|
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',
|
|
4691
|
+
return this.snapDrawn(p, leave, input, () => this.drawingTargets(_nullishCoalesce(_optionalChain([this, 'access', _124 => _124.pen, 'optionalAccess', _125 => _125.nodeId]), () => ( null))));
|
|
4651
4692
|
}
|
|
4652
4693
|
if (SHAPE_TOOLS.has(this.tool)) return this.snapDrawn(p, null, input, () => this.drawingTargets(null));
|
|
4653
4694
|
this.setGuides(null);
|
|
@@ -4795,7 +4836,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4795
4836
|
if (d.fillRule) out.fillRule = d.fillRule;
|
|
4796
4837
|
if (d.strokeAlign && d.strokeAlign !== "center") out.strokeAlign = d.strokeAlign;
|
|
4797
4838
|
for (const key of ["startArrow", "endArrow", "arrowAlign", "startArrowScale", "endArrowScale"]) if (d[key]) out[key] = d[key];
|
|
4798
|
-
if (_optionalChain([d, 'access',
|
|
4839
|
+
if (_optionalChain([d, 'access', _126 => _126.strokeWidthProfile, 'optionalAccess', _127 => _127.length])) out.strokeWidthProfile = d.strokeWidthProfile.map((p) => ({ ...p }));
|
|
4799
4840
|
return out;
|
|
4800
4841
|
}
|
|
4801
4842
|
/** Merges `patch` into a node (paths take style and geometry; groups name / visibility / opacity). */
|
|
@@ -4843,7 +4884,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4843
4884
|
/** Removes one width point of a path's profile (the width tool's Delete). */
|
|
4844
4885
|
removeWidthPoint(ref) {
|
|
4845
4886
|
const node = this.getNode(ref.nodeId);
|
|
4846
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
4887
|
+
if (_optionalChain([node, 'optionalAccess', _128 => _128.type]) !== "path" || !_optionalChain([node, 'access', _129 => _129.strokeWidthProfile, 'optionalAccess', _130 => _130[ref.index]])) return { ok: false, message: "There is no such width point." };
|
|
4847
4888
|
const rest = removeWidthPoints(sanitizeWidthProfile(node.strokeWidthProfile), [ref.index]);
|
|
4848
4889
|
this.widthPoint = null;
|
|
4849
4890
|
this.change("Delete Width Point", () => this.replaceNode(node.id, withStyle(node, { strokeWidthProfile: rest.length ? rest : null })));
|
|
@@ -4868,7 +4909,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
4868
4909
|
const refs = this.cornerTargets(options);
|
|
4869
4910
|
if (!refs.length) return { ok: false, message: "Nothing is selected." };
|
|
4870
4911
|
this.change("Corner Kind", () => {
|
|
4871
|
-
this.doc = this.updateAnchors(this.doc, refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access',
|
|
4912
|
+
this.doc = this.updateAnchors(this.doc, refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access', _131 => _131.corner, 'optionalAccess', _132 => _132.radius]), () => ( 0)), kind));
|
|
4872
4913
|
});
|
|
4873
4914
|
return { ok: true };
|
|
4874
4915
|
}
|
|
@@ -5007,10 +5048,10 @@ var VectorEditorController = (_class3 = class {
|
|
|
5007
5048
|
return this.selection.filter((id) => {
|
|
5008
5049
|
let covered = false;
|
|
5009
5050
|
const loc = locateVectorNode(this.doc.nodes, id);
|
|
5010
|
-
let parent = _nullishCoalesce(_optionalChain([loc, 'optionalAccess',
|
|
5051
|
+
let parent = _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _133 => _133.parent]), () => ( null));
|
|
5011
5052
|
while (parent) {
|
|
5012
5053
|
if (this.selection.includes(parent.id)) covered = true;
|
|
5013
|
-
parent = _nullishCoalesce(_optionalChain([locateVectorNode, 'call',
|
|
5054
|
+
parent = _nullishCoalesce(_optionalChain([locateVectorNode, 'call', _134 => _134(this.doc.nodes, parent.id), 'optionalAccess', _135 => _135.parent]), () => ( null));
|
|
5014
5055
|
}
|
|
5015
5056
|
return !covered;
|
|
5016
5057
|
});
|
|
@@ -5193,8 +5234,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
5193
5234
|
if (!ids.length) return null;
|
|
5194
5235
|
const locs = ids.map((id2) => locateVectorNode(this.doc.nodes, id2));
|
|
5195
5236
|
if (locs.some((l) => !l)) return null;
|
|
5196
|
-
const parent = _nullishCoalesce(_optionalChain([locs, 'access',
|
|
5197
|
-
if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access',
|
|
5237
|
+
const parent = _nullishCoalesce(_optionalChain([locs, 'access', _136 => _136[0], 'access', _137 => _137.parent, 'optionalAccess', _138 => _138.id]), () => ( null));
|
|
5238
|
+
if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access', _139 => _139.parent, 'optionalAccess', _140 => _140.id]), () => ( null))) !== parent)) return null;
|
|
5198
5239
|
const id = this.newId();
|
|
5199
5240
|
this.change("Group", () => {
|
|
5200
5241
|
const set = new Set(ids);
|
|
@@ -5217,7 +5258,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5217
5258
|
}
|
|
5218
5259
|
/** Replaces selected groups with their children. */
|
|
5219
5260
|
ungroup(options = {}) {
|
|
5220
|
-
const groups = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess',
|
|
5261
|
+
const groups = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess', _141 => _141.type]) === "group");
|
|
5221
5262
|
if (!groups.length) return { ok: false, message: "Select a group to ungroup." };
|
|
5222
5263
|
const set = new Set(groups.map((g) => g.id));
|
|
5223
5264
|
this.change("Ungroup", () => {
|
|
@@ -5277,7 +5318,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5277
5318
|
});
|
|
5278
5319
|
const paths = [...new Set(order)].map((id2) => this.getNode(id2));
|
|
5279
5320
|
if (paths.length < 2) return null;
|
|
5280
|
-
const result =
|
|
5321
|
+
const result = _chunkVNYRI265cjs.pathBoolean.call(void 0,
|
|
5281
5322
|
BOOLEAN_OPS[op],
|
|
5282
5323
|
paths.map((p) => ({
|
|
5283
5324
|
path: vectorPathWorldBezier(
|
|
@@ -5327,11 +5368,11 @@ var VectorEditorController = (_class3 = class {
|
|
|
5327
5368
|
/** A document-space path mapped into the parent space of node `id`. */
|
|
5328
5369
|
intoParentSpace(id, path) {
|
|
5329
5370
|
const parent = _nullishCoalesce(vectorParentMatrix(this.doc.nodes, id), () => ( IDENTITY_MATRIX));
|
|
5330
|
-
return isRoot(parent) ? path :
|
|
5371
|
+
return isRoot(parent) ? path : _chunkVNYRI265cjs.transformBezierPath.call(void 0, path, invertMatrix(parent));
|
|
5331
5372
|
}
|
|
5332
5373
|
/** Splits selected compound paths into one path per subpath. */
|
|
5333
5374
|
breakApart(options = {}) {
|
|
5334
|
-
const paths = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess',
|
|
5375
|
+
const paths = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess', _142 => _142.type]) === "path" && n.subpaths.length > 1);
|
|
5335
5376
|
if (!paths.length) return { ok: false, message: "Select a compound path to break apart." };
|
|
5336
5377
|
const created = [];
|
|
5337
5378
|
const set = new Set(paths.map((p) => p.id));
|
|
@@ -5366,7 +5407,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5366
5407
|
const entries = vectorPathEntries(this.doc, roots);
|
|
5367
5408
|
if (entries.length < (op === "divide" || op === "outline" ? 1 : 2)) return [];
|
|
5368
5409
|
const shapes = entries.map((e) => vectorPathfinderShape(e, op));
|
|
5369
|
-
const result =
|
|
5410
|
+
const result = _chunkVNYRI265cjs.pathfinder.call(void 0, op, shapes);
|
|
5370
5411
|
if (result.error || !result.pieces.length) return [];
|
|
5371
5412
|
const last = entries[entries.length - 1].node.id;
|
|
5372
5413
|
const topRoot = _nullishCoalesce([...roots].reverse().find((r) => {
|
|
@@ -5397,7 +5438,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5397
5438
|
shapeBuilderMap(ids) {
|
|
5398
5439
|
const roots = _nullishCoalesce(ids, () => ( this.selectedRoots()));
|
|
5399
5440
|
const key = roots.join("\0");
|
|
5400
|
-
if (_optionalChain([this, 'access',
|
|
5441
|
+
if (_optionalChain([this, 'access', _143 => _143.builderCache, 'optionalAccess', _144 => _144.doc]) === this.doc && this.builderCache.key === key) return this.builderCache.map;
|
|
5401
5442
|
const entries = roots.length ? vectorPathEntries(this.doc, roots) : [];
|
|
5402
5443
|
const map = entries.length ? vectorShapeBuilderMap(entries) : null;
|
|
5403
5444
|
this.builderCache = { doc: this.doc, key, map };
|
|
@@ -5411,7 +5452,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5411
5452
|
const p = m.map.faceInterior(index);
|
|
5412
5453
|
return {
|
|
5413
5454
|
index,
|
|
5414
|
-
d:
|
|
5455
|
+
d: _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, f.path, { precision: 3 }),
|
|
5415
5456
|
area: f.area,
|
|
5416
5457
|
sources: m.map.faceSources(index).map((i) => m.entries[i].node.id),
|
|
5417
5458
|
point: p ? { x: p[0], y: p[1] } : null
|
|
@@ -5426,20 +5467,23 @@ var VectorEditorController = (_class3 = class {
|
|
|
5426
5467
|
* Shape Builder gesture along `points` (document units; one point is a click) over the faces
|
|
5427
5468
|
* the selected (or given) paths make. Merges the faces touched into one shape styled like the
|
|
5428
5469
|
* top-most shape over the first face (the current fill for a face only outlines enclose);
|
|
5429
|
-
* with `erase` deletes them,
|
|
5430
|
-
*
|
|
5470
|
+
* with `erase` deletes them, the pieces of unfilled open paths and the edges of other outlines
|
|
5471
|
+
* (cut where paths meet) within `tolerance`: a deleted edge opens a closed subpath there,
|
|
5472
|
+
* splits an open one or takes a subpath it runs all the way round, and edges bounding a face
|
|
5473
|
+
* deleted in the same gesture go with the face. Every shape covering a touched face loses
|
|
5474
|
+
* that area; paths keep their own transforms. One undo step.
|
|
5431
5475
|
*/
|
|
5432
5476
|
shapeBuilder(points, options = {}) {
|
|
5433
|
-
const none = (message) => ({ ok: false, message, merged: null, faces: 0, lines: 0 });
|
|
5477
|
+
const none = (message) => ({ ok: false, message, merged: null, faces: 0, lines: 0, edges: 0 });
|
|
5434
5478
|
if (!points.length || !points.every((p) => Number.isFinite(p.x) && Number.isFinite(p.y))) return none("Give the points of the gesture.");
|
|
5435
5479
|
const m = this.shapeBuilderMap(options.ids);
|
|
5436
5480
|
if (!m) return none("Select paths that make faces.");
|
|
5437
5481
|
const erase = !!options.erase;
|
|
5438
5482
|
const tol = erase ? _nullishCoalesce(options.tolerance, () => ( this.builderLineTolerance())) : null;
|
|
5439
|
-
const touched = { faces: [], lines: [] };
|
|
5483
|
+
const touched = { faces: [], lines: [], edges: [] };
|
|
5440
5484
|
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
5485
|
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.");
|
|
5486
|
+
if (!touched.faces.length && !touched.lines.length && !touched.edges.length) return none("There is no face under the pointer.");
|
|
5443
5487
|
return this.applyShapeBuilder(m, touched, erase);
|
|
5444
5488
|
}
|
|
5445
5489
|
applyShapeBuilder(m, touched, erase) {
|
|
@@ -5450,11 +5494,12 @@ var VectorEditorController = (_class3 = class {
|
|
|
5450
5494
|
let nodes = this.doc.nodes;
|
|
5451
5495
|
m.entries.forEach((entry, i) => {
|
|
5452
5496
|
const node = entry.node;
|
|
5453
|
-
const toLocal = (path) =>
|
|
5497
|
+
const toLocal = (path) => _chunkVNYRI265cjs.transformBezierPath.call(void 0, path, invertMatrix(multiplyMatrices(nodeMatrix(node), entry.parent)));
|
|
5454
5498
|
const list = [];
|
|
5455
5499
|
const r = plan.replace.get(i);
|
|
5456
5500
|
if (r === void 0) list.push(node);
|
|
5457
|
-
else if (_optionalChain([r, 'optionalAccess',
|
|
5501
|
+
else if (_optionalChain([r, 'optionalAccess', _145 => _145.kind]) === "fill") list.push({ ...node, fillRule: "nonzero", subpaths: bezierToSubpaths(toLocal(r.path)) });
|
|
5502
|
+
else if (_optionalChain([r, 'optionalAccess', _146 => _146.kind]) === "outline") list.push({ ...node, subpaths: bezierToSubpaths(toLocal(r.path)) });
|
|
5458
5503
|
else if (_optionalChain([r, 'optionalAccess', _147 => _147.kind]) === "pieces") {
|
|
5459
5504
|
r.paths.forEach(
|
|
5460
5505
|
(path, k) => list.push({ ...node, id: k === 0 ? node.id : this.newId(), subpaths: bezierToSubpaths(toLocal(path)).map((sp) => ({ ...sp, closed: false })) })
|
|
@@ -5485,7 +5530,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5485
5530
|
this.editingId = null;
|
|
5486
5531
|
});
|
|
5487
5532
|
this.builderCache = null;
|
|
5488
|
-
return { ok: true, merged: mergedId, faces: touched.faces.length, lines: touched.lines.length };
|
|
5533
|
+
return { ok: true, merged: mergedId, faces: touched.faces.length, lines: touched.lines.length, edges: erase ? vectorBuilderErasedEdges(m, touched).length : 0 };
|
|
5489
5534
|
}
|
|
5490
5535
|
/** The paint bucket's map of the visible outlines, cached per document and gap. */
|
|
5491
5536
|
fillMap(gap) {
|
|
@@ -5531,7 +5576,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5531
5576
|
hoverBuilder(p, alt) {
|
|
5532
5577
|
if (this.tool === "paintBucket") {
|
|
5533
5578
|
const region = _nullishCoalesce(_optionalChain([this, 'access', _155 => _155.fillMap, 'call', _156 => _156(this.editing.fillGap), 'optionalAccess', _157 => _157.regionAt, 'call', _158 => _158([p.x, p.y])]), () => ( null));
|
|
5534
|
-
const key2 = region ?
|
|
5579
|
+
const key2 = region ? _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, region, { precision: 2 }) : null;
|
|
5535
5580
|
if (key2 === this.builderHoverKey) return false;
|
|
5536
5581
|
this.builderHoverKey = key2;
|
|
5537
5582
|
this.builderPreview = region ? { mode: "fill", faces: [region], lines: [], trail: null } : null;
|
|
@@ -5542,7 +5587,9 @@ var VectorEditorController = (_class3 = class {
|
|
|
5542
5587
|
const key = hit ? `${alt ? "erase" : "merge"}:${JSON.stringify(hit)}` : null;
|
|
5543
5588
|
if (key === this.builderHoverKey) return false;
|
|
5544
5589
|
this.builderHoverKey = key;
|
|
5545
|
-
|
|
5590
|
+
const touched = { faces: [], lines: [], edges: [] };
|
|
5591
|
+
addBuilderHit(touched, hit);
|
|
5592
|
+
this.builderPreview = hit && m ? this.builderPreviewOf(m, touched, alt, null) : null;
|
|
5546
5593
|
return true;
|
|
5547
5594
|
}
|
|
5548
5595
|
builderPreviewOf(m, touched, erase, trail) {
|
|
@@ -5550,7 +5597,8 @@ var VectorEditorController = (_class3 = class {
|
|
|
5550
5597
|
return {
|
|
5551
5598
|
mode: erase ? "erase" : "merge",
|
|
5552
5599
|
faces: touched.faces.map((f) => faces[f].path),
|
|
5553
|
-
|
|
5600
|
+
// Edges bounding a face touched too go with the face, so they are not shown apart.
|
|
5601
|
+
lines: [...touched.lines.map((k) => m.pieces[k].path), ...erase ? vectorBuilderErasedEdges(m, touched).map((k) => m.edges[k].path) : []],
|
|
5554
5602
|
trail
|
|
5555
5603
|
};
|
|
5556
5604
|
}
|
|
@@ -5566,7 +5614,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5566
5614
|
const m = this.selectedRoots().length ? this.shapeBuilderMap() : null;
|
|
5567
5615
|
if (!m) return;
|
|
5568
5616
|
const erase = !!input.alt;
|
|
5569
|
-
const touched = { faces: [], lines: [] };
|
|
5617
|
+
const touched = { faces: [], lines: [], edges: [] };
|
|
5570
5618
|
addBuilderHit(touched, vectorShapeBuilderHit(m, p, erase ? this.builderLineTolerance() : null));
|
|
5571
5619
|
this.drag = { kind: "builder", erase, points: [p], touched, map: m };
|
|
5572
5620
|
this.interaction = { type: "builder", mode: erase ? "erase" : "merge", points: [p] };
|
|
@@ -5586,7 +5634,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
5586
5634
|
upBuilder(drag) {
|
|
5587
5635
|
this.builderPreview = null;
|
|
5588
5636
|
this.builderHoverKey = null;
|
|
5589
|
-
if (!drag.touched.faces.length && !drag.touched.lines.length) {
|
|
5637
|
+
if (!drag.touched.faces.length && !drag.touched.lines.length && !drag.touched.edges.length) {
|
|
5590
5638
|
this.notify();
|
|
5591
5639
|
return;
|
|
5592
5640
|
}
|
|
@@ -5999,10 +6047,10 @@ var VectorEditorController = (_class3 = class {
|
|
|
5999
6047
|
const region = eraserRegion(pts, width);
|
|
6000
6048
|
if (!region.length) return [];
|
|
6001
6049
|
const plan = [];
|
|
6002
|
-
const rb =
|
|
6050
|
+
const rb = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, region);
|
|
6003
6051
|
const reach = rb ? [{ x: rb.minX, y: rb.minY }, { x: rb.maxX, y: rb.maxY }] : points;
|
|
6004
6052
|
for (const node of this.strokeTargets(reach, options.ids, 0)) {
|
|
6005
|
-
const local =
|
|
6053
|
+
const local = _chunkVNYRI265cjs.transformBezierPath.call(void 0, region, invertMatrix(this.worldOf(node.id)));
|
|
6006
6054
|
const live = node.subpaths.filter((sp) => sp.anchors.length > 1);
|
|
6007
6055
|
if (!live.length) continue;
|
|
6008
6056
|
if (hasPaint(node.fill) && live.every((sp) => sp.closed)) {
|
|
@@ -7056,7 +7104,7 @@ var VectorEditorController = (_class3 = class {
|
|
|
7056
7104
|
this.selection = [drag.nodeId];
|
|
7057
7105
|
return this.commit(`Draw ${inkShapeLabel(shape)}`, drag.before);
|
|
7058
7106
|
}
|
|
7059
|
-
const fitted =
|
|
7107
|
+
const fitted = _chunkVNYRI265cjs.fitCubics.call(void 0, drag.points, 1.5 / this.viewport.zoom, { cornerAngleDeg: 60 });
|
|
7060
7108
|
const anchors = [];
|
|
7061
7109
|
for (const c of fitted) {
|
|
7062
7110
|
if (!anchors.length) anchors.push({ x: c.p0[0], y: c.p0[1] });
|
|
@@ -7323,6 +7371,7 @@ function pencilPressureProfile(points, pressures) {
|
|
|
7323
7371
|
// src/vector/render.ts
|
|
7324
7372
|
var fmt = (n) => Math.round(n * 100) / 100;
|
|
7325
7373
|
var fmtMatrix = (m) => `matrix(${m.map((n) => Math.round(n * 1e6) / 1e6).join(" ")})`;
|
|
7374
|
+
var VECTOR_BUILDER_HATCH_GAP = 6;
|
|
7326
7375
|
function renderNode(node, defs, idPrefix) {
|
|
7327
7376
|
if (node.visible === false) return null;
|
|
7328
7377
|
if (node.type === "group") {
|
|
@@ -7369,7 +7418,7 @@ function screenOutline(state, node) {
|
|
|
7369
7418
|
const v2 = state.viewport;
|
|
7370
7419
|
const view = [v2.zoom, 0, 0, v2.zoom, v2.x, v2.y];
|
|
7371
7420
|
const parent = _nullishCoalesce(vectorParentMatrix(state.document.nodes, node.id), () => ( IDENTITY_MATRIX));
|
|
7372
|
-
return collectWithMatrix(node, parent).map(({ path, parent: m }) =>
|
|
7421
|
+
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
7422
|
}
|
|
7374
7423
|
function collectWithMatrix(node, parent) {
|
|
7375
7424
|
if (node.type === "path") return [{ path: node, parent }];
|
|
@@ -7501,9 +7550,17 @@ function getVectorOverlayRenderData(state) {
|
|
|
7501
7550
|
if (state.builder) {
|
|
7502
7551
|
const v2 = state.viewport;
|
|
7503
7552
|
const view = [v2.zoom, 0, 0, v2.zoom, v2.x, v2.y];
|
|
7504
|
-
const
|
|
7553
|
+
const svg = (path) => _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, path, { precision: 2 });
|
|
7554
|
+
const screen = state.builder.faces.map((f) => _chunkVNYRI265cjs.transformBezierPath.call(void 0, f, view));
|
|
7555
|
+
const hatch = state.builder.mode !== "fill";
|
|
7505
7556
|
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 = {
|
|
7557
|
+
builder = {
|
|
7558
|
+
mode: state.builder.mode,
|
|
7559
|
+
faces: screen.map(svg),
|
|
7560
|
+
hatches: screen.map((f) => hatch ? svg(_chunkVNYRI265cjs.hatchPath.call(void 0, f, { gap: VECTOR_BUILDER_HATCH_GAP })) : ""),
|
|
7561
|
+
lines: state.builder.lines.map((l) => svg(_chunkVNYRI265cjs.transformBezierPath.call(void 0, l, view))),
|
|
7562
|
+
trail
|
|
7563
|
+
};
|
|
7507
7564
|
if (state.builder.mode !== "fill" && _optionalChain([it, 'optionalAccess', _239 => _239.type]) === "builder") {
|
|
7508
7565
|
const n = state.builder.faces.length;
|
|
7509
7566
|
status = state.builder.mode === "erase" ? `Delete ${n} ${n === 1 ? "face" : "faces"}` : `Merge ${n} ${n === 1 ? "face" : "faces"}`;
|
|
@@ -7530,7 +7587,9 @@ var VECTOR_OVERLAY_THEME = {
|
|
|
7530
7587
|
builderFill: "rgba(14, 165, 233, 0.22)",
|
|
7531
7588
|
/** Shape Builder faces and line pieces an Alt gesture deletes. */
|
|
7532
7589
|
builderErase: "#ef4444",
|
|
7533
|
-
builderEraseFill: "rgba(239, 68, 68, 0.22)"
|
|
7590
|
+
builderEraseFill: "rgba(239, 68, 68, 0.22)",
|
|
7591
|
+
/** Opacity of the hatch lines over Shape Builder faces (drawn in the face's outline colour). */
|
|
7592
|
+
builderHatchOpacity: 0.6
|
|
7534
7593
|
};
|
|
7535
7594
|
function vectorDiamondPath(x, y, r = VECTOR_OVERLAY_THEME.widthPointSize) {
|
|
7536
7595
|
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`;
|
|
@@ -8006,7 +8065,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8006
8065
|
id: `${prefix}shapeBuilder`,
|
|
8007
8066
|
label: "Shape Builder",
|
|
8008
8067
|
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
|
|
8068
|
+
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
8069
|
params: {
|
|
8011
8070
|
type: "object",
|
|
8012
8071
|
properties: { points: POINTS, erase: { type: "boolean" }, tolerance: { type: "number", minimum: 0 }, ids: IDS },
|
|
@@ -8016,7 +8075,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8016
8075
|
run: (_ctx, params) => {
|
|
8017
8076
|
const result = controller.shapeBuilder(params.points.map(([x, y]) => ({ x, y })), { ids: ids(params), erase: params.erase, tolerance: params.tolerance });
|
|
8018
8077
|
check(result);
|
|
8019
|
-
return { merged: result.merged, faces: result.faces, lines: result.lines };
|
|
8078
|
+
return { merged: result.merged, faces: result.faces, lines: result.lines, edges: result.edges };
|
|
8020
8079
|
}
|
|
8021
8080
|
},
|
|
8022
8081
|
{
|
|
@@ -8518,5 +8577,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
8518
8577
|
|
|
8519
8578
|
|
|
8520
8579
|
|
|
8521
|
-
|
|
8580
|
+
|
|
8581
|
+
|
|
8582
|
+
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
8583
|
//# sourceMappingURL=index.cjs.map
|