@pixerate/editor 0.43.0 → 0.45.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/README.md +27 -2
- package/THIRD_PARTY_NOTICES.md +4 -0
- package/dist/agent/index.cjs +548 -45
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +47 -17
- package/dist/agent/index.d.ts +47 -17
- package/dist/agent/index.js +536 -33
- package/dist/agent/index.js.map +1 -1
- package/dist/{builtins-BLud97fC.d.cts → builtins-CZW-aYKS.d.cts} +1 -1
- package/dist/{builtins-D0BDyAgw.d.ts → builtins-DghNQbT-.d.ts} +1 -1
- package/dist/{chunk-I6BZB5ZH.cjs → chunk-EFDCLENW.cjs} +73 -6
- package/dist/chunk-EFDCLENW.cjs.map +1 -0
- package/dist/chunk-HHQ4XJWT.js +826 -0
- package/dist/chunk-HHQ4XJWT.js.map +1 -0
- package/dist/chunk-J3R2OWOE.cjs +1465 -0
- package/dist/chunk-J3R2OWOE.cjs.map +1 -0
- package/dist/chunk-K2LVZ4FA.cjs +826 -0
- package/dist/chunk-K2LVZ4FA.cjs.map +1 -0
- package/dist/{chunk-6MDQKHRH.cjs → chunk-N4MLNJPO.cjs} +21 -899
- package/dist/chunk-N4MLNJPO.cjs.map +1 -0
- package/dist/chunk-PQM5W7ZN.js +168 -0
- package/dist/chunk-PQM5W7ZN.js.map +1 -0
- package/dist/{chunk-DDADOHJW.js → chunk-Q25ZS4F7.js} +5 -883
- package/dist/chunk-Q25ZS4F7.js.map +1 -0
- package/dist/chunk-TK2XZK6Z.js +1465 -0
- package/dist/chunk-TK2XZK6Z.js.map +1 -0
- package/dist/commands/index.cjs +3 -2
- package/dist/commands/index.cjs.map +1 -1
- package/dist/commands/index.d.cts +5 -5
- package/dist/commands/index.d.ts +5 -5
- package/dist/commands/index.js +2 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/extensions/index.cjs +4 -4
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.d.cts +3 -3
- package/dist/extensions/index.d.ts +3 -3
- package/dist/extensions/index.js +12 -12
- package/dist/generation/index.cjs +2 -2
- package/dist/generation/index.d.cts +4 -4
- package/dist/generation/index.d.ts +4 -4
- package/dist/generation/index.js +1 -1
- package/dist/image-editor/index.cjs +24 -24
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +2 -2
- package/dist/image-editor/index.d.ts +2 -2
- package/dist/image-editor/index.js +24 -24
- package/dist/image-editor/index.js.map +1 -1
- package/dist/{index-C6gaQRH0.d.cts → index-CfOQf70b.d.cts} +1 -1
- package/dist/{index-DXAv_R08.d.ts → index-jwJ_onWf.d.ts} +1 -1
- package/dist/index.cjs +9 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +12 -12
- package/dist/parameters/index.d.cts +2 -2
- package/dist/parameters/index.d.ts +2 -2
- package/dist/{registry-DnzpgY27.d.cts → registry-B4l-lYts.d.cts} +1 -1
- package/dist/{registry-DhVUZioj.d.ts → registry-BfVD-vVg.d.ts} +1 -1
- package/dist/{registry-BDe-vlv3.d.ts → registry-CSlH4iUn.d.ts} +1 -1
- package/dist/{registry-D0GADKc7.d.cts → registry-vz6HOiiy.d.cts} +1 -1
- package/dist/{schema-DYDGdYL9.d.cts → schema-Di0CS6Pe.d.cts} +26 -2
- package/dist/{schema-DYDGdYL9.d.ts → schema-Di0CS6Pe.d.ts} +26 -2
- package/dist/tools/index.cjs +37 -3
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.d.cts +871 -11
- package/dist/tools/index.d.ts +871 -11
- package/dist/tools/index.js +36 -2
- package/dist/vector/index.cjs +1982 -301
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +624 -154
- package/dist/vector/index.d.ts +624 -154
- package/dist/vector/index.js +1755 -74
- package/dist/vector/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-36BLROHV.js +0 -438
- package/dist/chunk-36BLROHV.js.map +0 -1
- package/dist/chunk-5H2OPMXZ.js +0 -586
- package/dist/chunk-5H2OPMXZ.js.map +0 -1
- package/dist/chunk-6MDQKHRH.cjs.map +0 -1
- package/dist/chunk-D6S5M7HV.js +0 -101
- package/dist/chunk-D6S5M7HV.js.map +0 -1
- package/dist/chunk-DDADOHJW.js.map +0 -1
- package/dist/chunk-I6BZB5ZH.cjs.map +0 -1
- package/dist/chunk-MC2LQN5S.cjs +0 -586
- package/dist/chunk-MC2LQN5S.cjs.map +0 -1
- package/dist/chunk-V7CC7RZ6.cjs +0 -438
- package/dist/chunk-V7CC7RZ6.cjs.map +0 -1
package/dist/vector/index.cjs
CHANGED
|
@@ -37,6 +37,7 @@ var _chunkQKLRAA4Tcjs = require('../chunk-QKLRAA4T.cjs');
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
|
|
40
|
+
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
var _chunkVNYRI265cjs = require('../chunk-VNYRI265.cjs');
|
|
@@ -79,11 +80,12 @@ var VECTOR_TOOLS = [
|
|
|
79
80
|
"shapeBuilder",
|
|
80
81
|
"paintBucket",
|
|
81
82
|
"blend",
|
|
82
|
-
"gradient"
|
|
83
|
+
"gradient",
|
|
84
|
+
"envelope"
|
|
83
85
|
];
|
|
84
86
|
var VECTOR_TRANSFORM_HANDLES = ["nw", "n", "ne", "e", "se", "s", "sw", "w", "rotate"];
|
|
85
87
|
var VECTOR_PATHFINDER_OPERATIONS = ["divide", "trim", "merge", "crop", "outline", "minusBack"];
|
|
86
|
-
var VECTOR_EFFECT_TYPES = ["trim", "roundCorners", "puckerBloat", "twist", "zigzag", "wiggle", "offset", "merge", "repeater"];
|
|
88
|
+
var VECTOR_EFFECT_TYPES = ["trim", "roundCorners", "puckerBloat", "twist", "zigzag", "wiggle", "offset", "merge", "repeater", "envelope"];
|
|
87
89
|
var VECTOR_MERGE_MODES = ["merge", "add", "subtract", "intersect", "exclude"];
|
|
88
90
|
|
|
89
91
|
// src/vector/gradient.ts
|
|
@@ -482,6 +484,14 @@ function transformVectorGradient(g, m) {
|
|
|
482
484
|
const p = vectorGradientPoints(g);
|
|
483
485
|
return { ...g, start: apply(m, p.start), end: apply(m, p.end), width: apply(m, p.width), ...p.focal ? { focal: apply(m, p.focal) } : {} };
|
|
484
486
|
}
|
|
487
|
+
function mapVectorGradient(g, f) {
|
|
488
|
+
if (!hasExplicitGradientGeometry(g) || g.units !== "userSpaceOnUse") return g;
|
|
489
|
+
const p = vectorGradientPoints(g);
|
|
490
|
+
return { ...g, start: f(p.start), end: f(p.end), width: f(p.width), ...p.focal ? { focal: f(p.focal) } : {} };
|
|
491
|
+
}
|
|
492
|
+
function mapVectorPaint(paint, f) {
|
|
493
|
+
return isVectorGradient(paint) ? mapVectorGradient(paint, f) : paint;
|
|
494
|
+
}
|
|
485
495
|
function transformVectorPaint(paint, m) {
|
|
486
496
|
return isVectorGradient(paint) ? transformVectorGradient(paint, m) : paint;
|
|
487
497
|
}
|
|
@@ -1179,8 +1189,8 @@ function widthProfilePreset(id) {
|
|
|
1179
1189
|
}
|
|
1180
1190
|
function widthProfilePresetId(points) {
|
|
1181
1191
|
if (isUniformWidthProfile(points)) return "uniform";
|
|
1182
|
-
const
|
|
1183
|
-
return _nullishCoalesce(_optionalChain([VECTOR_WIDTH_PRESETS, 'access', _20 => _20.find, 'call', _21 => _21((p) => p.points.length &&
|
|
1192
|
+
const same2 = (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);
|
|
1193
|
+
return _nullishCoalesce(_optionalChain([VECTOR_WIDTH_PRESETS, 'access', _20 => _20.find, 'call', _21 => _21((p) => p.points.length && same2(points, p.points)), 'optionalAccess', _22 => _22.id]), () => ( "custom"));
|
|
1184
1194
|
}
|
|
1185
1195
|
function reverseWidthProfile(points) {
|
|
1186
1196
|
return points.map((p) => ({ t: 1 - p.t, left: p.right, right: p.left })).reverse();
|
|
@@ -1200,10 +1210,10 @@ function insertWidthPoint(points, t, sides2 = {}, options = {}) {
|
|
|
1200
1210
|
left: _nullishCoalesce(clean(sides2.left, VECTOR_WIDTH_PROFILE_MAX_SCALE), () => ( here.left)),
|
|
1201
1211
|
right: _nullishCoalesce(clean(sides2.right, VECTOR_WIDTH_PROFILE_MAX_SCALE), () => ( here.right))
|
|
1202
1212
|
};
|
|
1203
|
-
const
|
|
1204
|
-
if (
|
|
1205
|
-
pts[
|
|
1206
|
-
return { points: pts, index:
|
|
1213
|
+
const same2 = pts.findIndex((q) => Math.abs(q.t - tt) <= VECTOR_WIDTH_SAME_T);
|
|
1214
|
+
if (same2 >= 0 && !options.step) {
|
|
1215
|
+
pts[same2] = { ...p, t: pts[same2].t };
|
|
1216
|
+
return { points: pts, index: same2 };
|
|
1207
1217
|
}
|
|
1208
1218
|
let i = 0;
|
|
1209
1219
|
while (i < pts.length && pts[i].t <= tt) i++;
|
|
@@ -1743,13 +1753,13 @@ function endOf(segs, atStart) {
|
|
|
1743
1753
|
const last = segs[segs.length - 1];
|
|
1744
1754
|
return { p: toVec(last[last.length - 1]), out: v(t[0], t[1]) };
|
|
1745
1755
|
}
|
|
1746
|
-
function pointAlong(segs, fromStart,
|
|
1756
|
+
function pointAlong(segs, fromStart, dist5) {
|
|
1747
1757
|
const order = fromStart ? segs : [...segs].reverse();
|
|
1748
1758
|
let acc = 0;
|
|
1749
1759
|
for (const s of order) {
|
|
1750
1760
|
const l = segLen(s);
|
|
1751
|
-
if (acc + l >=
|
|
1752
|
-
const want = fromStart ?
|
|
1761
|
+
if (acc + l >= dist5) {
|
|
1762
|
+
const want = fromStart ? dist5 - acc : l - (dist5 - acc);
|
|
1753
1763
|
const pts = _chunkVNYRI265cjs.trimSegments.call(void 0, [s], 0, want);
|
|
1754
1764
|
const p = pts.length ? pts[0][pts[0].length - 1] : s[0];
|
|
1755
1765
|
return toVec(p);
|
|
@@ -2231,6 +2241,846 @@ function pathsCenter(paths) {
|
|
|
2231
2241
|
return b ? { x: (b.minX + b.maxX) / 2, y: (b.minY + b.maxY) / 2 } : { x: 0, y: 0 };
|
|
2232
2242
|
}
|
|
2233
2243
|
|
|
2244
|
+
// src/vector/pathMap.ts
|
|
2245
|
+
var MAX_PIECES = 1 << 20;
|
|
2246
|
+
var MAX_DEPTH = 6;
|
|
2247
|
+
var PROBES = [0.25, 0.5, 0.75];
|
|
2248
|
+
var lerp2 = (a, b, t) => ({ x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t });
|
|
2249
|
+
var dist2 = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
|
|
2250
|
+
var same = (a, b) => Math.abs(a.x - b.x) < 1e-9 && Math.abs(a.y - b.y) < 1e-9;
|
|
2251
|
+
function evalCubic(s, t) {
|
|
2252
|
+
const ab = lerp2(s[0], s[1], t);
|
|
2253
|
+
const bc = lerp2(s[1], s[2], t);
|
|
2254
|
+
const cd = lerp2(s[2], s[3], t);
|
|
2255
|
+
return lerp2(lerp2(ab, bc, t), lerp2(bc, cd, t), t);
|
|
2256
|
+
}
|
|
2257
|
+
function halves(s) {
|
|
2258
|
+
const ab = lerp2(s[0], s[1], 0.5);
|
|
2259
|
+
const bc = lerp2(s[1], s[2], 0.5);
|
|
2260
|
+
const cd = lerp2(s[2], s[3], 0.5);
|
|
2261
|
+
const abc = lerp2(ab, bc, 0.5);
|
|
2262
|
+
const bcd = lerp2(bc, cd, 0.5);
|
|
2263
|
+
const m = lerp2(abc, bcd, 0.5);
|
|
2264
|
+
return [
|
|
2265
|
+
[s[0], ab, abc, m],
|
|
2266
|
+
[m, bcd, cd, s[3]]
|
|
2267
|
+
];
|
|
2268
|
+
}
|
|
2269
|
+
function offLine(p, a, b) {
|
|
2270
|
+
const l = dist2(a, b);
|
|
2271
|
+
return l < 1e-12 ? dist2(p, a) : Math.abs((b.x - a.x) * (a.y - p.y) - (a.x - p.x) * (b.y - a.y)) / l;
|
|
2272
|
+
}
|
|
2273
|
+
var mapAnchorPoints = (a, f) => {
|
|
2274
|
+
const p = f(a);
|
|
2275
|
+
return {
|
|
2276
|
+
x: p.x,
|
|
2277
|
+
y: p.y,
|
|
2278
|
+
...a.in ? { in: f(a.in) } : {},
|
|
2279
|
+
...a.out ? { out: f(a.out) } : {},
|
|
2280
|
+
...a.type && a.type !== "corner" ? { type: a.type } : {},
|
|
2281
|
+
...a.corner ? { corner: { ...a.corner } } : {}
|
|
2282
|
+
};
|
|
2283
|
+
};
|
|
2284
|
+
function mapVectorPoints(subpaths, f) {
|
|
2285
|
+
return subpaths.map((sp) => ({ closed: sp.closed, anchors: sp.anchors.map((a) => mapAnchorPoints(a, f)) }));
|
|
2286
|
+
}
|
|
2287
|
+
function splitMapped(seg, f, tol, depth, out) {
|
|
2288
|
+
const mapped = seg.map(f);
|
|
2289
|
+
const fits = PROBES.every((t) => dist2(f(evalCubic(seg, t)), evalCubic(mapped, t)) <= tol);
|
|
2290
|
+
if (fits || depth === 0) {
|
|
2291
|
+
out.push(mapped);
|
|
2292
|
+
return;
|
|
2293
|
+
}
|
|
2294
|
+
const [a, b] = halves(seg);
|
|
2295
|
+
splitMapped(a, f, tol, depth - 1, out);
|
|
2296
|
+
splitMapped(b, f, tol, depth - 1, out);
|
|
2297
|
+
}
|
|
2298
|
+
var toPoint = (p) => [p.x, p.y];
|
|
2299
|
+
var toVec2 = (p) => ({ x: p[0], y: p[1] });
|
|
2300
|
+
function refit(seg, pieces, f, tol) {
|
|
2301
|
+
if (pieces.length < 3) return pieces;
|
|
2302
|
+
const n = pieces.length * 4;
|
|
2303
|
+
const samples = [];
|
|
2304
|
+
for (let i = 0; i <= n; i++) samples.push(toPoint(f(evalCubic(seg, i / n))));
|
|
2305
|
+
const first = pieces[0];
|
|
2306
|
+
const last = pieces[pieces.length - 1];
|
|
2307
|
+
const t0 = !same(first[1], first[0]) ? first[1] : first[2];
|
|
2308
|
+
const t1 = !same(last[2], last[3]) ? last[2] : last[1];
|
|
2309
|
+
const fitted = _chunkVNYRI265cjs.fitCubicRun.call(void 0, samples, tol / 2, [t0.x - first[0].x, t0.y - first[0].y], [last[3].x - t1.x, last[3].y - t1.y]);
|
|
2310
|
+
if (!fitted.length || fitted.length >= pieces.length) return pieces;
|
|
2311
|
+
const chain = fitted.map((c) => [c.p0, c.p1, c.p2, c.p3]);
|
|
2312
|
+
for (let i = 0; i < n; i++) {
|
|
2313
|
+
const q = toPoint(f(evalCubic(seg, (i + 0.5) / n)));
|
|
2314
|
+
let best = Infinity;
|
|
2315
|
+
for (const c of chain) best = Math.min(best, _chunkVNYRI265cjs.segmentNearest.call(void 0, c, q).distance);
|
|
2316
|
+
if (best > tol) return pieces;
|
|
2317
|
+
}
|
|
2318
|
+
return fitted.map((c) => [toVec2(c.p0), toVec2(c.p1), toVec2(c.p2), toVec2(c.p3)]);
|
|
2319
|
+
}
|
|
2320
|
+
function mapSegment(seg, f, tol, depth, fit) {
|
|
2321
|
+
if (same(seg[1], seg[0]) && same(seg[2], seg[3])) {
|
|
2322
|
+
const a = f(seg[0]);
|
|
2323
|
+
const b = f(seg[3]);
|
|
2324
|
+
if (PROBES.every((t) => offLine(f(lerp2(seg[0], seg[3], t)), a, b) <= tol)) return [[a, a, b, b]];
|
|
2325
|
+
const line2 = [seg[0], lerp2(seg[0], seg[3], 1 / 3), lerp2(seg[0], seg[3], 2 / 3), seg[3]];
|
|
2326
|
+
const out2 = [];
|
|
2327
|
+
splitMapped(line2, f, tol, depth, out2);
|
|
2328
|
+
return fit ? refit(line2, out2, f, tol) : out2;
|
|
2329
|
+
}
|
|
2330
|
+
const out = [];
|
|
2331
|
+
splitMapped(seg, f, tol, depth, out);
|
|
2332
|
+
return fit ? refit(seg, out, f, tol) : out;
|
|
2333
|
+
}
|
|
2334
|
+
function realign(a) {
|
|
2335
|
+
if (!a.in || !a.out || same(a.in, a) || same(a.out, a)) return a;
|
|
2336
|
+
const li = dist2(a.in, a);
|
|
2337
|
+
const lo = dist2(a.out, a);
|
|
2338
|
+
const dx = (a.x - a.in.x) / li + (a.out.x - a.x) / lo;
|
|
2339
|
+
const dy = (a.y - a.in.y) / li + (a.out.y - a.y) / lo;
|
|
2340
|
+
const l = Math.hypot(dx, dy);
|
|
2341
|
+
if (l < 1e-12) return a;
|
|
2342
|
+
const u = { x: dx / l, y: dy / l };
|
|
2343
|
+
const type = a.type === "symmetric" && Math.abs(li - lo) > 1e-6 * Math.max(li, lo) ? "smooth" : a.type;
|
|
2344
|
+
return { ...a, in: { x: a.x - u.x * li, y: a.y - u.y * li }, out: { x: a.x + u.x * lo, y: a.y + u.y * lo }, ...type ? { type } : {} };
|
|
2345
|
+
}
|
|
2346
|
+
var segmentOf = (sp, i) => {
|
|
2347
|
+
const a = sp.anchors[i];
|
|
2348
|
+
const b = sp.anchors[(i + 1) % sp.anchors.length];
|
|
2349
|
+
return [{ x: a.x, y: a.y }, _nullishCoalesce(a.out, () => ( { x: a.x, y: a.y })), _nullishCoalesce(b.in, () => ( { x: b.x, y: b.y })), { x: b.x, y: b.y }];
|
|
2350
|
+
};
|
|
2351
|
+
function mapSubpath(sp, f, tol, depth, fit) {
|
|
2352
|
+
const n = sp.anchors.length;
|
|
2353
|
+
const count = n < 2 ? 0 : sp.closed ? n : n - 1;
|
|
2354
|
+
if (!count) return mapVectorPoints([sp], f)[0];
|
|
2355
|
+
const pieces = [];
|
|
2356
|
+
for (let i = 0; i < count; i++) pieces.push(mapSegment(segmentOf(sp, i), f, tol, depth, fit));
|
|
2357
|
+
const anchors = [];
|
|
2358
|
+
const put = (a) => {
|
|
2359
|
+
if (a.in && same(a.in, a)) delete a.in;
|
|
2360
|
+
if (a.out && same(a.out, a)) delete a.out;
|
|
2361
|
+
anchors.push(a.type === "smooth" || a.type === "symmetric" ? realign(a) : a);
|
|
2362
|
+
};
|
|
2363
|
+
sp.anchors.forEach((k, i) => {
|
|
2364
|
+
const incoming = i > 0 ? pieces[i - 1] : sp.closed ? pieces[n - 1] : void 0;
|
|
2365
|
+
const outgoing = pieces[i];
|
|
2366
|
+
const p = f(k);
|
|
2367
|
+
const a = { x: p.x, y: p.y };
|
|
2368
|
+
const inCtrl = incoming ? incoming[incoming.length - 1][2] : k.in ? f(k.in) : null;
|
|
2369
|
+
const outCtrl = outgoing ? outgoing[0][1] : k.out ? f(k.out) : null;
|
|
2370
|
+
if (inCtrl) a.in = inCtrl;
|
|
2371
|
+
if (outCtrl) a.out = outCtrl;
|
|
2372
|
+
if (k.type && k.type !== "corner") a.type = k.type;
|
|
2373
|
+
if (k.corner) a.corner = { ...k.corner };
|
|
2374
|
+
put(a);
|
|
2375
|
+
if (outgoing) for (let w = 1; w < outgoing.length; w++) put({ x: outgoing[w][0].x, y: outgoing[w][0].y, in: outgoing[w - 1][2], out: outgoing[w][1], type: "smooth" });
|
|
2376
|
+
});
|
|
2377
|
+
return { closed: sp.closed, anchors };
|
|
2378
|
+
}
|
|
2379
|
+
function mapVectorSubpaths(subpaths, f, tolerance = 0.1, options = {}) {
|
|
2380
|
+
const tol = Number.isFinite(tolerance) && tolerance > 0 ? tolerance : 0.1;
|
|
2381
|
+
const segments = subpaths.reduce((s, sp) => s + sp.anchors.length, 0);
|
|
2382
|
+
let depth = MAX_DEPTH;
|
|
2383
|
+
while (depth > 0 && segments * 2 ** depth > MAX_PIECES) depth--;
|
|
2384
|
+
return subpaths.map((sp) => mapSubpath(sp, f, tol, depth, options.refit !== false));
|
|
2385
|
+
}
|
|
2386
|
+
function mapBezierPath(path, f, tolerance = 0.1, options = {}) {
|
|
2387
|
+
return subpathsToBezier(mapVectorSubpaths(bezierToSubpaths(path), f, tolerance, options), { corners: false });
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2390
|
+
// src/vector/warp.ts
|
|
2391
|
+
var VECTOR_WARP_STYLES = [
|
|
2392
|
+
"arc",
|
|
2393
|
+
"arcLower",
|
|
2394
|
+
"arcUpper",
|
|
2395
|
+
"arch",
|
|
2396
|
+
"bulge",
|
|
2397
|
+
"shellLower",
|
|
2398
|
+
"shellUpper",
|
|
2399
|
+
"flag",
|
|
2400
|
+
"wave",
|
|
2401
|
+
"fish",
|
|
2402
|
+
"rise",
|
|
2403
|
+
"fisheye",
|
|
2404
|
+
"inflate",
|
|
2405
|
+
"squeeze",
|
|
2406
|
+
"twist"
|
|
2407
|
+
];
|
|
2408
|
+
var VECTOR_WARP_STYLE_LABELS = {
|
|
2409
|
+
arc: "Arc",
|
|
2410
|
+
arcLower: "Arc Lower",
|
|
2411
|
+
arcUpper: "Arc Upper",
|
|
2412
|
+
arch: "Arch",
|
|
2413
|
+
bulge: "Bulge",
|
|
2414
|
+
shellLower: "Shell Lower",
|
|
2415
|
+
shellUpper: "Shell Upper",
|
|
2416
|
+
flag: "Flag",
|
|
2417
|
+
wave: "Wave",
|
|
2418
|
+
fish: "Fish",
|
|
2419
|
+
rise: "Rise",
|
|
2420
|
+
fisheye: "Fisheye",
|
|
2421
|
+
inflate: "Inflate",
|
|
2422
|
+
squeeze: "Squeeze",
|
|
2423
|
+
twist: "Twist"
|
|
2424
|
+
};
|
|
2425
|
+
function restGrid() {
|
|
2426
|
+
return [0, 1, 2, 3].map((j) => [0, 1, 2, 3].map((i) => [i / 3, j / 3]));
|
|
2427
|
+
}
|
|
2428
|
+
function edgeArc(y, b, up, h) {
|
|
2429
|
+
if (Math.abs(b) < 1e-9) return [0, 1, 2, 3].map((i) => [i / 3, y]);
|
|
2430
|
+
const th = Math.abs(b) * Math.PI;
|
|
2431
|
+
const k = 4 / 3 * Math.tan(th / 4) * 0.5 / Math.sin(th / 2);
|
|
2432
|
+
const s = b > 0 === up ? -1 : 1;
|
|
2433
|
+
const c = Math.cos(th / 2);
|
|
2434
|
+
const n = Math.sin(th / 2);
|
|
2435
|
+
const dy = s * k * n / h;
|
|
2436
|
+
return [
|
|
2437
|
+
[0, y],
|
|
2438
|
+
[k * c, y + dy],
|
|
2439
|
+
[1 - k * c, y + dy],
|
|
2440
|
+
[1, y]
|
|
2441
|
+
];
|
|
2442
|
+
}
|
|
2443
|
+
function arcGrid(b, h) {
|
|
2444
|
+
if (Math.abs(b) < 1e-9) return restGrid();
|
|
2445
|
+
const up = b > 0;
|
|
2446
|
+
const th = Math.abs(b) * Math.PI;
|
|
2447
|
+
const r = 0.5 / Math.sin(th / 2);
|
|
2448
|
+
const k = 4 / 3 * Math.tan(th / 4);
|
|
2449
|
+
const s = up ? -1 : 1;
|
|
2450
|
+
const cy = up ? h + r * Math.cos(th / 2) : -r * Math.cos(th / 2);
|
|
2451
|
+
return [0, 1, 2, 3].map((j) => {
|
|
2452
|
+
const v2 = j / 3;
|
|
2453
|
+
const big = r + h * (up ? 1 - v2 : v2);
|
|
2454
|
+
const at2 = (a) => [0.5 + big * Math.sin(a), cy + s * big * Math.cos(a)];
|
|
2455
|
+
const tangent2 = (a) => [Math.cos(a), -s * Math.sin(a)];
|
|
2456
|
+
const p0 = at2(-th / 2);
|
|
2457
|
+
const p3 = at2(th / 2);
|
|
2458
|
+
const t0 = tangent2(-th / 2);
|
|
2459
|
+
const t1 = tangent2(th / 2);
|
|
2460
|
+
const l = k * big;
|
|
2461
|
+
const pts = [p0, [p0[0] + l * t0[0], p0[1] + l * t0[1]], [p3[0] - l * t1[0], p3[1] - l * t1[1]], p3];
|
|
2462
|
+
return pts.map((p) => [p[0], p[1] / h]);
|
|
2463
|
+
});
|
|
2464
|
+
}
|
|
2465
|
+
function blendRows(top, bottom) {
|
|
2466
|
+
return [0, 1, 2, 3].map((j) => {
|
|
2467
|
+
const t = j / 3;
|
|
2468
|
+
return [0, 1, 2, 3].map((i) => [top[i][0] + (bottom[i][0] - top[i][0]) * t, top[i][1] + (bottom[i][1] - top[i][1]) * t]);
|
|
2469
|
+
});
|
|
2470
|
+
}
|
|
2471
|
+
var INNER = [
|
|
2472
|
+
[1, 1, -1, -1],
|
|
2473
|
+
[1, 2, 1, -1],
|
|
2474
|
+
[2, 1, -1, 1],
|
|
2475
|
+
[2, 2, 1, 1]
|
|
2476
|
+
];
|
|
2477
|
+
function vectorWarpPresetGrid(style, b, hd, vd, vertical, aspect) {
|
|
2478
|
+
const h = vertical ? 1 / aspect : aspect;
|
|
2479
|
+
if (vertical) [hd, vd] = [vd, hd];
|
|
2480
|
+
let g = restGrid();
|
|
2481
|
+
switch (style) {
|
|
2482
|
+
case "arc":
|
|
2483
|
+
g = arcGrid(b, h);
|
|
2484
|
+
break;
|
|
2485
|
+
case "arch":
|
|
2486
|
+
g = [0, 1, 2, 3].map((j) => edgeArc(j / 3, b, true, h));
|
|
2487
|
+
break;
|
|
2488
|
+
case "bulge":
|
|
2489
|
+
g = blendRows(edgeArc(0, b, true, h), edgeArc(1, b, false, h));
|
|
2490
|
+
break;
|
|
2491
|
+
case "arcLower":
|
|
2492
|
+
g = blendRows(g[0], edgeArc(1, b, false, h));
|
|
2493
|
+
break;
|
|
2494
|
+
case "arcUpper":
|
|
2495
|
+
g = blendRows(edgeArc(0, b, true, h), g[3]);
|
|
2496
|
+
break;
|
|
2497
|
+
// The bulging edge and the outer points of the row next to it come from Arc (bent the other
|
|
2498
|
+
// way for Shell Lower); the rest stays put.
|
|
2499
|
+
case "shellLower": {
|
|
2500
|
+
const a = arcGrid(-b, h);
|
|
2501
|
+
g[3] = a[3];
|
|
2502
|
+
g[2][0] = a[2][0];
|
|
2503
|
+
g[2][3] = a[2][3];
|
|
2504
|
+
break;
|
|
2505
|
+
}
|
|
2506
|
+
case "shellUpper": {
|
|
2507
|
+
const a = arcGrid(b, h);
|
|
2508
|
+
g[0] = a[0];
|
|
2509
|
+
g[1][0] = a[1][0];
|
|
2510
|
+
g[1][3] = a[1][3];
|
|
2511
|
+
break;
|
|
2512
|
+
}
|
|
2513
|
+
case "flag":
|
|
2514
|
+
for (const row of g) {
|
|
2515
|
+
row[1][1] -= 2 * b;
|
|
2516
|
+
row[2][1] += 2 * b;
|
|
2517
|
+
}
|
|
2518
|
+
break;
|
|
2519
|
+
case "wave":
|
|
2520
|
+
for (const row of g.slice(1, 3)) {
|
|
2521
|
+
row[1][1] += 4 / 3 * b;
|
|
2522
|
+
row[2][1] -= 4 / 3 * b;
|
|
2523
|
+
}
|
|
2524
|
+
break;
|
|
2525
|
+
case "fish":
|
|
2526
|
+
[-2, -2 / 3, 2 / 3, 2].forEach((f, j) => {
|
|
2527
|
+
g[j][1][1] += f * b;
|
|
2528
|
+
g[j][2][1] -= f * b;
|
|
2529
|
+
});
|
|
2530
|
+
break;
|
|
2531
|
+
case "rise":
|
|
2532
|
+
for (const row of g) {
|
|
2533
|
+
row[0][1] += 2 * b;
|
|
2534
|
+
row[1][1] += 2 * b;
|
|
2535
|
+
}
|
|
2536
|
+
break;
|
|
2537
|
+
case "fisheye":
|
|
2538
|
+
for (const [j, i, dx, dy] of INNER) {
|
|
2539
|
+
g[j][i][0] += dx * 2 * b / 3;
|
|
2540
|
+
g[j][i][1] += dy * 2 * b / 3;
|
|
2541
|
+
}
|
|
2542
|
+
break;
|
|
2543
|
+
// Edge midpoints move out (Inflate) or the sides in (Squeeze) by b/3, the inner points by b/9.
|
|
2544
|
+
case "inflate":
|
|
2545
|
+
case "squeeze": {
|
|
2546
|
+
const s = style === "inflate" ? 1 : -1;
|
|
2547
|
+
for (const p of g[0].slice(1, 3)) p[1] -= b / 3;
|
|
2548
|
+
for (const p of g[3].slice(1, 3)) p[1] += b / 3;
|
|
2549
|
+
for (const row of g.slice(1, 3)) {
|
|
2550
|
+
row[0][0] -= s * b / 3;
|
|
2551
|
+
row[3][0] += s * b / 3;
|
|
2552
|
+
}
|
|
2553
|
+
for (const [j, i, dx, dy] of INNER) {
|
|
2554
|
+
g[j][i][0] += s * dx * b / 9;
|
|
2555
|
+
g[j][i][1] += dy * b / 9;
|
|
2556
|
+
}
|
|
2557
|
+
break;
|
|
2558
|
+
}
|
|
2559
|
+
// The inner points turn round the centre (the other way for a negative bend).
|
|
2560
|
+
case "twist": {
|
|
2561
|
+
const a = Math.abs(b);
|
|
2562
|
+
if (b >= 0) {
|
|
2563
|
+
g[1][1][0] += a;
|
|
2564
|
+
g[1][2][1] += a;
|
|
2565
|
+
g[2][1][1] -= a;
|
|
2566
|
+
g[2][2][0] -= a;
|
|
2567
|
+
} else {
|
|
2568
|
+
g[1][1][1] += a;
|
|
2569
|
+
g[1][2][0] -= a;
|
|
2570
|
+
g[2][1][0] += a;
|
|
2571
|
+
g[2][2][1] -= a;
|
|
2572
|
+
}
|
|
2573
|
+
break;
|
|
2574
|
+
}
|
|
2575
|
+
}
|
|
2576
|
+
if (vd !== 0) {
|
|
2577
|
+
const moved = (row, s) => {
|
|
2578
|
+
const m = [(row[0][0] + row[3][0]) / 2, (row[0][1] + row[3][1]) / 2];
|
|
2579
|
+
return row.map((p) => [m[0] + (p[0] - m[0]) * s - p[0], m[1] + (p[1] - m[1]) * s - p[1]]);
|
|
2580
|
+
};
|
|
2581
|
+
const d0 = moved(g[0], 1 - vd);
|
|
2582
|
+
const d3 = moved(g[3], 1 + vd);
|
|
2583
|
+
g.forEach((row, j) => {
|
|
2584
|
+
const t = j / 3;
|
|
2585
|
+
row.forEach((p, i) => {
|
|
2586
|
+
p[0] += d0[i][0] + (d3[i][0] - d0[i][0]) * t;
|
|
2587
|
+
p[1] += d0[i][1] + (d3[i][1] - d0[i][1]) * t;
|
|
2588
|
+
});
|
|
2589
|
+
});
|
|
2590
|
+
}
|
|
2591
|
+
if (hd !== 0) {
|
|
2592
|
+
for (let i = 0; i < 4; i++) {
|
|
2593
|
+
const s = 1 + hd * (2 * i / 3 - 1);
|
|
2594
|
+
const m = [(g[0][i][0] + g[3][i][0]) / 2, (g[0][i][1] + g[3][i][1]) / 2];
|
|
2595
|
+
for (const row of g) row[i] = [m[0] + (row[i][0] - m[0]) * s, m[1] + (row[i][1] - m[1]) * s];
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2598
|
+
if (vertical) g = [0, 1, 2, 3].map((j) => [0, 1, 2, 3].map((i) => [g[i][j][1], g[i][j][0]]));
|
|
2599
|
+
return g;
|
|
2600
|
+
}
|
|
2601
|
+
function bernstein(t) {
|
|
2602
|
+
const s = 1 - t;
|
|
2603
|
+
return [s * s * s, 3 * s * s * t, 3 * s * t * t, t * t * t];
|
|
2604
|
+
}
|
|
2605
|
+
var lerp3 = (a, b, t) => ({ x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t });
|
|
2606
|
+
function splitCubic(p, t) {
|
|
2607
|
+
const a = lerp3(p[0], p[1], t);
|
|
2608
|
+
const b = lerp3(p[1], p[2], t);
|
|
2609
|
+
const c = lerp3(p[2], p[3], t);
|
|
2610
|
+
const d = lerp3(a, b, t);
|
|
2611
|
+
const e = lerp3(b, c, t);
|
|
2612
|
+
return [p[0], a, d, lerp3(d, e, t), e, c, p[3]];
|
|
2613
|
+
}
|
|
2614
|
+
var BERN_INV = [
|
|
2615
|
+
[1, 0, 0, 0],
|
|
2616
|
+
[-5 / 6, 3, -1.5, 1 / 3],
|
|
2617
|
+
[1 / 3, -1.5, 3, -5 / 6],
|
|
2618
|
+
[0, 0, 0, 1]
|
|
2619
|
+
];
|
|
2620
|
+
var pct = (v2) => typeof v2 === "number" && Number.isFinite(v2) ? Math.min(1, Math.max(-1, v2 / 100)) : 0;
|
|
2621
|
+
function vectorWarpPresetMesh(preset, bounds) {
|
|
2622
|
+
if (!VECTOR_WARP_STYLES.includes(preset.style)) return null;
|
|
2623
|
+
const { x, y, width: w, height: h } = bounds;
|
|
2624
|
+
if (!(w > 0 && h > 0)) return null;
|
|
2625
|
+
const b = pct(preset.bend);
|
|
2626
|
+
const hd = pct(preset.horizontal);
|
|
2627
|
+
const vd = pct(preset.vertical);
|
|
2628
|
+
if (b === 0 && hd === 0 && vd === 0) return null;
|
|
2629
|
+
const grid = vectorWarpPresetGrid(preset.style, b, hd, vd, preset.orientation === "vertical", h / w);
|
|
2630
|
+
return { us: [0, 1], vs: [0, 1], points: grid.flat().map((p) => ({ x: x + p[0] * w, y: y + p[1] * h })) };
|
|
2631
|
+
}
|
|
2632
|
+
var vectorMeshColumns = (m) => 3 * (m.us.length - 1) + 1;
|
|
2633
|
+
var vectorMeshRows = (m) => 3 * (m.vs.length - 1) + 1;
|
|
2634
|
+
function isValidVectorMesh(m) {
|
|
2635
|
+
if (!m || typeof m !== "object") return false;
|
|
2636
|
+
const { us, vs, points } = m;
|
|
2637
|
+
const knots = (k) => Array.isArray(k) && k.length >= 2 && k.length <= 65 && k[0] === 0 && k[k.length - 1] === 1 && k.every((v2, i) => typeof v2 === "number" && (i === 0 || v2 > k[i - 1]));
|
|
2638
|
+
if (!knots(us) || !knots(vs) || !Array.isArray(points)) return false;
|
|
2639
|
+
return points.length === (3 * (us.length - 1) + 1) * (3 * (vs.length - 1) + 1) && points.every((p) => !!p && Number.isFinite(p.x) && Number.isFinite(p.y));
|
|
2640
|
+
}
|
|
2641
|
+
function fitVectorMesh(f, us, vs) {
|
|
2642
|
+
const pc = us.length - 1;
|
|
2643
|
+
const pr = vs.length - 1;
|
|
2644
|
+
const nx = 3 * pc + 1;
|
|
2645
|
+
const points = new Array((3 * pr + 1) * nx);
|
|
2646
|
+
for (let pj = 0; pj < pr; pj++) {
|
|
2647
|
+
for (let pi = 0; pi < pc; pi++) {
|
|
2648
|
+
const s = [0, 1, 2, 3].map(
|
|
2649
|
+
(j) => [0, 1, 2, 3].map((i) => f(us[pi] + (us[pi + 1] - us[pi]) * i / 3, vs[pj] + (vs[pj + 1] - vs[pj]) * j / 3))
|
|
2650
|
+
);
|
|
2651
|
+
for (let j = 0; j < 4; j++) {
|
|
2652
|
+
for (let i = 0; i < 4; i++) {
|
|
2653
|
+
let x = 0;
|
|
2654
|
+
let y = 0;
|
|
2655
|
+
for (let a = 0; a < 4; a++) {
|
|
2656
|
+
for (let b = 0; b < 4; b++) {
|
|
2657
|
+
const k = BERN_INV[j][a] * BERN_INV[i][b];
|
|
2658
|
+
x += k * s[a][b].x;
|
|
2659
|
+
y += k * s[a][b].y;
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
points[(3 * pj + j) * nx + 3 * pi + i] = { x, y };
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
}
|
|
2667
|
+
return { us: us.slice(), vs: vs.slice(), points };
|
|
2668
|
+
}
|
|
2669
|
+
var evenKnots = (n) => Array.from({ length: n + 1 }, (_, i) => i / n);
|
|
2670
|
+
var clampCount = (n) => Math.min(64, Math.max(1, Math.round(Number.isFinite(n) ? n : 1)));
|
|
2671
|
+
function vectorIdentityMesh(bounds, columns = 1, rows = 1) {
|
|
2672
|
+
return fitVectorMesh((s, t) => ({ x: bounds.x + s * bounds.width, y: bounds.y + t * bounds.height }), evenKnots(clampCount(columns)), evenKnots(clampCount(rows)));
|
|
2673
|
+
}
|
|
2674
|
+
function locate(knots, s) {
|
|
2675
|
+
const n = knots.length - 1;
|
|
2676
|
+
let i = 0;
|
|
2677
|
+
while (i + 1 < n && s > knots[i + 1]) i++;
|
|
2678
|
+
const w = knots[i + 1] - knots[i];
|
|
2679
|
+
return [i, w > 0 ? (s - knots[i]) / w : 0];
|
|
2680
|
+
}
|
|
2681
|
+
function evalVectorMesh(m, s, t) {
|
|
2682
|
+
const [pi, a] = locate(m.us, s);
|
|
2683
|
+
const [pj, b] = locate(m.vs, t);
|
|
2684
|
+
const ba = bernstein(a);
|
|
2685
|
+
const bb = bernstein(b);
|
|
2686
|
+
const nx = vectorMeshColumns(m);
|
|
2687
|
+
let x = 0;
|
|
2688
|
+
let y = 0;
|
|
2689
|
+
for (let j = 0; j < 4; j++) {
|
|
2690
|
+
for (let i = 0; i < 4; i++) {
|
|
2691
|
+
const p = m.points[(3 * pj + j) * nx + 3 * pi + i];
|
|
2692
|
+
const k = ba[i] * bb[j];
|
|
2693
|
+
x += p.x * k;
|
|
2694
|
+
y += p.y * k;
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
return { x, y };
|
|
2698
|
+
}
|
|
2699
|
+
function transposeMesh(m) {
|
|
2700
|
+
const nx = vectorMeshColumns(m);
|
|
2701
|
+
const ny = vectorMeshRows(m);
|
|
2702
|
+
const points = new Array(nx * ny);
|
|
2703
|
+
for (let j = 0; j < ny; j++) for (let i = 0; i < nx; i++) points[i * ny + j] = m.points[j * nx + i];
|
|
2704
|
+
return { us: m.vs.slice(), vs: m.us.slice(), points };
|
|
2705
|
+
}
|
|
2706
|
+
function splitVectorMeshU(m, s) {
|
|
2707
|
+
const [pi, a] = locate(m.us, s);
|
|
2708
|
+
if (!(a >= 0.01 && a <= 0.99)) return null;
|
|
2709
|
+
const nx = vectorMeshColumns(m);
|
|
2710
|
+
const ny = vectorMeshRows(m);
|
|
2711
|
+
const points = [];
|
|
2712
|
+
for (let j = 0; j < ny; j++) {
|
|
2713
|
+
const row = m.points.slice(j * nx, (j + 1) * nx);
|
|
2714
|
+
points.push(...row.slice(0, 3 * pi), ...splitCubic(row.slice(3 * pi, 3 * pi + 4), a), ...row.slice(3 * pi + 4));
|
|
2715
|
+
}
|
|
2716
|
+
const us = m.us.slice();
|
|
2717
|
+
us.splice(pi + 1, 0, Math.min(1, Math.max(0, s)));
|
|
2718
|
+
return { us, vs: m.vs.slice(), points };
|
|
2719
|
+
}
|
|
2720
|
+
function splitVectorMeshV(m, t) {
|
|
2721
|
+
const out = splitVectorMeshU(transposeMesh(m), t);
|
|
2722
|
+
return out && transposeMesh(out);
|
|
2723
|
+
}
|
|
2724
|
+
function removeVectorMeshSplitU(m, k) {
|
|
2725
|
+
if (k <= 0 || k + 1 >= m.us.length) return null;
|
|
2726
|
+
const a = (m.us[k] - m.us[k - 1]) / (m.us[k + 1] - m.us[k - 1]);
|
|
2727
|
+
const nx = vectorMeshColumns(m);
|
|
2728
|
+
const ny = vectorMeshRows(m);
|
|
2729
|
+
const c0 = 3 * (k - 1);
|
|
2730
|
+
const points = [];
|
|
2731
|
+
for (let j = 0; j < ny; j++) {
|
|
2732
|
+
const row = m.points.slice(j * nx, (j + 1) * nx);
|
|
2733
|
+
const [p0, q1, r2, p3] = [row[c0], row[c0 + 1], row[c0 + 5], row[c0 + 6]];
|
|
2734
|
+
const p1 = { x: (q1.x - (1 - a) * p0.x) / a, y: (q1.y - (1 - a) * p0.y) / a };
|
|
2735
|
+
const p2 = { x: (r2.x - a * p3.x) / (1 - a), y: (r2.y - a * p3.y) / (1 - a) };
|
|
2736
|
+
points.push(...row.slice(0, c0), p0, p1, p2, p3, ...row.slice(c0 + 7));
|
|
2737
|
+
}
|
|
2738
|
+
const us = m.us.slice();
|
|
2739
|
+
us.splice(k, 1);
|
|
2740
|
+
return { us, vs: m.vs.slice(), points };
|
|
2741
|
+
}
|
|
2742
|
+
function removeVectorMeshSplitV(m, k) {
|
|
2743
|
+
const out = removeVectorMeshSplitU(transposeMesh(m), k);
|
|
2744
|
+
return out && transposeMesh(out);
|
|
2745
|
+
}
|
|
2746
|
+
function mapVectorMeshPoints(m, f) {
|
|
2747
|
+
return { us: m.us.slice(), vs: m.vs.slice(), points: m.points.map((p) => f(p)) };
|
|
2748
|
+
}
|
|
2749
|
+
function resizeVectorMesh(m, columns, rows) {
|
|
2750
|
+
const cols = clampCount(columns);
|
|
2751
|
+
const rws = clampCount(rows);
|
|
2752
|
+
if (m.us.length - 1 === cols && m.vs.length - 1 === rws) return m;
|
|
2753
|
+
const us = evenKnots(cols);
|
|
2754
|
+
const vs = evenKnots(rws);
|
|
2755
|
+
const has = (list, v2) => list.some((k) => Math.abs(k - v2) < 1e-12);
|
|
2756
|
+
if (m.us.every((u) => has(us, u)) && m.vs.every((v2) => has(vs, v2))) {
|
|
2757
|
+
let out = m;
|
|
2758
|
+
for (const u of us) if (!has(out.us, u)) out = _nullishCoalesce(splitVectorMeshU(out, u), () => ( out));
|
|
2759
|
+
for (const v2 of vs) if (!has(out.vs, v2)) out = _nullishCoalesce(splitVectorMeshV(out, v2), () => ( out));
|
|
2760
|
+
return out;
|
|
2761
|
+
}
|
|
2762
|
+
return fitVectorMesh((s, t) => evalVectorMesh(m, s, t), us, vs);
|
|
2763
|
+
}
|
|
2764
|
+
function vectorMeshControlBounds(m) {
|
|
2765
|
+
let minX = Infinity;
|
|
2766
|
+
let minY = Infinity;
|
|
2767
|
+
let maxX = -Infinity;
|
|
2768
|
+
let maxY = -Infinity;
|
|
2769
|
+
for (const p of m.points) {
|
|
2770
|
+
minX = Math.min(minX, p.x);
|
|
2771
|
+
minY = Math.min(minY, p.y);
|
|
2772
|
+
maxX = Math.max(maxX, p.x);
|
|
2773
|
+
maxY = Math.max(maxY, p.y);
|
|
2774
|
+
}
|
|
2775
|
+
return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
|
|
2776
|
+
}
|
|
2777
|
+
function vectorMeshParamAt(m, p) {
|
|
2778
|
+
const n = 48;
|
|
2779
|
+
let best = { s: 0.5, t: 0.5, d: Infinity };
|
|
2780
|
+
for (let j = 0; j <= n; j++) {
|
|
2781
|
+
for (let i = 0; i <= n; i++) {
|
|
2782
|
+
const q2 = evalVectorMesh(m, i / n, j / n);
|
|
2783
|
+
const d = (q2.x - p.x) ** 2 + (q2.y - p.y) ** 2;
|
|
2784
|
+
if (d < best.d) best = { s: i / n, t: j / n, d };
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2787
|
+
let { s, t } = best;
|
|
2788
|
+
for (let k = 0; k < 12; k++) {
|
|
2789
|
+
const h = 1e-5;
|
|
2790
|
+
const q2 = evalVectorMesh(m, s, t);
|
|
2791
|
+
const qs = evalVectorMesh(m, s + h, t);
|
|
2792
|
+
const qt = evalVectorMesh(m, s, t + h);
|
|
2793
|
+
const a = (qs.x - q2.x) / h;
|
|
2794
|
+
const b = (qt.x - q2.x) / h;
|
|
2795
|
+
const c = (qs.y - q2.y) / h;
|
|
2796
|
+
const d = (qt.y - q2.y) / h;
|
|
2797
|
+
const det = a * d - b * c;
|
|
2798
|
+
if (Math.abs(det) < 1e-12) break;
|
|
2799
|
+
const ex = p.x - q2.x;
|
|
2800
|
+
const ey = p.y - q2.y;
|
|
2801
|
+
s = Math.min(1, Math.max(0, s + (d * ex - b * ey) / det));
|
|
2802
|
+
t = Math.min(1, Math.max(0, t + (a * ey - c * ex) / det));
|
|
2803
|
+
}
|
|
2804
|
+
const q = evalVectorMesh(m, s, t);
|
|
2805
|
+
return { s, t, distance: Math.hypot(q.x - p.x, q.y - p.y) };
|
|
2806
|
+
}
|
|
2807
|
+
function smoothLines(m, i0, i1, j0, j1) {
|
|
2808
|
+
const nx = vectorMeshColumns(m);
|
|
2809
|
+
i1 = Math.min(i1, nx);
|
|
2810
|
+
j1 = Math.min(j1, vectorMeshRows(m));
|
|
2811
|
+
const triples = [];
|
|
2812
|
+
for (let a = 1; a < m.us.length - 1; a++) {
|
|
2813
|
+
if (3 * a >= i0 && 3 * a < i1)
|
|
2814
|
+
for (let j = j0; j < j1; j++) triples.push([j * nx + 3 * a - 1, j * nx + 3 * a, j * nx + 3 * a + 1, m.us[a] - m.us[a - 1], m.us[a + 1] - m.us[a]]);
|
|
2815
|
+
}
|
|
2816
|
+
for (let b = 1; b < m.vs.length - 1; b++) {
|
|
2817
|
+
if (3 * b >= j0 && 3 * b < j1)
|
|
2818
|
+
for (let i = i0; i < i1; i++) triples.push([(3 * b - 1) * nx + i, 3 * b * nx + i, (3 * b + 1) * nx + i, m.vs[b] - m.vs[b - 1], m.vs[b + 1] - m.vs[b]]);
|
|
2819
|
+
}
|
|
2820
|
+
for (const [l, c, r, hl, hr] of triples) {
|
|
2821
|
+
const pl = m.points[l];
|
|
2822
|
+
const pc = m.points[c];
|
|
2823
|
+
const pr = m.points[r];
|
|
2824
|
+
const tx = ((pc.x - pl.x) / hl + (pr.x - pc.x) / hr) / 2;
|
|
2825
|
+
const ty = ((pc.y - pl.y) / hl + (pr.y - pc.y) / hr) / 2;
|
|
2826
|
+
m.points[l] = { x: pc.x - tx * hl, y: pc.y - ty * hl };
|
|
2827
|
+
m.points[r] = { x: pc.x + tx * hr, y: pc.y + ty * hr };
|
|
2828
|
+
}
|
|
2829
|
+
}
|
|
2830
|
+
function dragVectorMeshPoint(base, index, d) {
|
|
2831
|
+
if (index < 0 || index >= base.points.length || !Number.isFinite(d.x) || !Number.isFinite(d.y)) return base;
|
|
2832
|
+
const out = { us: base.us.slice(), vs: base.vs.slice(), points: base.points.slice() };
|
|
2833
|
+
const nx = vectorMeshColumns(base);
|
|
2834
|
+
const ny = vectorMeshRows(base);
|
|
2835
|
+
const i = index % nx;
|
|
2836
|
+
const j = Math.floor(index / nx);
|
|
2837
|
+
const shift = (ii, jj, v2) => {
|
|
2838
|
+
if (ii < 0 || jj < 0 || ii >= nx || jj >= ny) return;
|
|
2839
|
+
const p = out.points[jj * nx + ii];
|
|
2840
|
+
out.points[jj * nx + ii] = { x: p.x + v2.x, y: p.y + v2.y };
|
|
2841
|
+
};
|
|
2842
|
+
const span = (knots, k) => k > 0 && k + 1 < knots.length ? [knots[k] - knots[k - 1], knots[k + 1] - knots[k]] : null;
|
|
2843
|
+
const ri = i % 3;
|
|
2844
|
+
const rj = j % 3;
|
|
2845
|
+
if (ri === 0 && rj === 0) {
|
|
2846
|
+
for (let dj = -1; dj <= 1; dj++) for (let di = -1; di <= 1; di++) shift(i + di, j + dj, d);
|
|
2847
|
+
} else if (ri === 0) {
|
|
2848
|
+
for (let di = -1; di <= 1; di++) shift(i + di, j, d);
|
|
2849
|
+
const sp = span(base.vs, Math.floor(j / 3) + (rj === 2 ? 1 : 0));
|
|
2850
|
+
if (sp) {
|
|
2851
|
+
const [other, k] = rj === 1 ? [j - 2, sp[0] / sp[1]] : [j + 2, sp[1] / sp[0]];
|
|
2852
|
+
for (let di = -1; di <= 1; di++) shift(i + di, other, { x: -d.x * k, y: -d.y * k });
|
|
2853
|
+
}
|
|
2854
|
+
} else if (rj === 0) {
|
|
2855
|
+
for (let dj = -1; dj <= 1; dj++) shift(i, j + dj, d);
|
|
2856
|
+
const sp = span(base.us, Math.floor(i / 3) + (ri === 2 ? 1 : 0));
|
|
2857
|
+
if (sp) {
|
|
2858
|
+
const [other, k] = ri === 1 ? [i - 2, sp[0] / sp[1]] : [i + 2, sp[1] / sp[0]];
|
|
2859
|
+
for (let dj = -1; dj <= 1; dj++) shift(other, j + dj, { x: -d.x * k, y: -d.y * k });
|
|
2860
|
+
}
|
|
2861
|
+
} else shift(i, j, d);
|
|
2862
|
+
return out;
|
|
2863
|
+
}
|
|
2864
|
+
function pullVectorMesh(base, s, t, d) {
|
|
2865
|
+
const BORDER_ZONE = 0.12;
|
|
2866
|
+
const REACH = 1.8;
|
|
2867
|
+
if (!Number.isFinite(d.x) || !Number.isFinite(d.y)) return base;
|
|
2868
|
+
const m = { us: base.us.slice(), vs: base.vs.slice(), points: base.points.slice() };
|
|
2869
|
+
const cols = m.us.length - 1;
|
|
2870
|
+
const rows = m.vs.length - 1;
|
|
2871
|
+
const [pi, a] = locate(m.us, s);
|
|
2872
|
+
const [pj, b] = locate(m.vs, t);
|
|
2873
|
+
const ba = bernstein(a);
|
|
2874
|
+
const bb = bernstein(b);
|
|
2875
|
+
const nx = vectorMeshColumns(m);
|
|
2876
|
+
const ny = vectorMeshRows(m);
|
|
2877
|
+
const anchor = (ai, aj) => _nullishCoalesce(base.points[3 * aj * nx + 3 * ai], () => ( { x: 0, y: 0 }));
|
|
2878
|
+
const at0 = evalVectorMesh(base, s, t);
|
|
2879
|
+
const target = { x: at0.x + d.x, y: at0.y + d.y };
|
|
2880
|
+
let size = 1;
|
|
2881
|
+
for (const k of ["x", "y"]) {
|
|
2882
|
+
const vals = [anchor(pi, pj)[k], anchor(pi + 1, pj)[k], anchor(pi, pj + 1)[k], anchor(pi + 1, pj + 1)[k]];
|
|
2883
|
+
size = Math.max(size, Math.max(...vals) - Math.min(...vals));
|
|
2884
|
+
}
|
|
2885
|
+
const radius = REACH * size;
|
|
2886
|
+
const innerW = (ba[1] + ba[2]) * (bb[1] + bb[2]);
|
|
2887
|
+
const interior = Math.min(1, Math.max(0, innerW / 0.5625));
|
|
2888
|
+
const toBorder = Math.min(s, 1 - s, t, 1 - t);
|
|
2889
|
+
const nearBorder = Math.min(1, Math.max(0, 1 - toBorder / BORDER_ZONE));
|
|
2890
|
+
const meshCorner = (ai, aj) => (ai === 0 || ai === cols) && (aj === 0 || aj === rows);
|
|
2891
|
+
const onBorder = (ai, aj) => ai === 0 || ai === cols || aj === 0 || aj === rows;
|
|
2892
|
+
const reach = (ai, aj, wa, wb) => meshCorner(ai, aj) ? 0 : wa * wb * (onBorder(ai, aj) ? nearBorder : 1);
|
|
2893
|
+
const corner = [
|
|
2894
|
+
[pi, pj, reach(pi, pj, ba[0] + ba[1], bb[0] + bb[1])],
|
|
2895
|
+
[pi + 1, pj, reach(pi + 1, pj, ba[2] + ba[3], bb[0] + bb[1])],
|
|
2896
|
+
[pi, pj + 1, reach(pi, pj + 1, ba[0] + ba[1], bb[2] + bb[3])],
|
|
2897
|
+
[pi + 1, pj + 1, reach(pi + 1, pj + 1, ba[2] + ba[3], bb[2] + bb[3])]
|
|
2898
|
+
];
|
|
2899
|
+
const share = new Array((cols + 1) * (rows + 1)).fill(0);
|
|
2900
|
+
for (let aj = 0; aj <= rows; aj++) {
|
|
2901
|
+
for (let ai = 0; ai <= cols; ai++) {
|
|
2902
|
+
const p = anchor(ai, aj);
|
|
2903
|
+
const x = Math.min(1, Math.max(0, Math.hypot(p.x - at0.x, p.y - at0.y) / radius));
|
|
2904
|
+
const fall = 0.5 * (1 + Math.cos(Math.PI * x));
|
|
2905
|
+
const edge = meshCorner(ai, aj) ? 0 : onBorder(ai, aj) ? nearBorder : 1;
|
|
2906
|
+
share[aj * (cols + 1) + ai] = fall * edge;
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
for (const [ai, aj, w] of corner) share[aj * (cols + 1) + ai] = Math.max(share[aj * (cols + 1) + ai], (1 - interior) * w);
|
|
2910
|
+
const move = (idx, k, v2) => {
|
|
2911
|
+
const p = m.points[idx];
|
|
2912
|
+
m.points[idx] = { x: p.x + v2.x * k, y: p.y + v2.y * k };
|
|
2913
|
+
};
|
|
2914
|
+
for (let j = 0; j < ny; j++) {
|
|
2915
|
+
for (let i = 0; i < nx; i++) {
|
|
2916
|
+
const ai = Math.min(cols, Math.floor((i + 1) / 3));
|
|
2917
|
+
const aj = Math.min(rows, Math.floor((j + 1) / 3));
|
|
2918
|
+
move(j * nx + i, share[aj * (cols + 1) + ai], d);
|
|
2919
|
+
}
|
|
2920
|
+
}
|
|
2921
|
+
let norm = 0;
|
|
2922
|
+
for (const j of [1, 2]) for (const i of [1, 2]) norm += (ba[i] * bb[j]) ** 2;
|
|
2923
|
+
const cornerNorm = corner.reduce((acc, c) => acc + c[2] * c[2], 0);
|
|
2924
|
+
const innerPart = cornerNorm > 1e-12 ? Math.min(1, innerW / 0.15) : 1;
|
|
2925
|
+
const edgeHandles = [];
|
|
2926
|
+
for (const k of [1, 2]) {
|
|
2927
|
+
if (pi === 0) edgeHandles.push([(3 * pj + k) * nx + 3 * pi, ba[0] * bb[k]]);
|
|
2928
|
+
if (pi + 1 === cols) edgeHandles.push([(3 * pj + k) * nx + 3 * pi + 3, ba[3] * bb[k]]);
|
|
2929
|
+
if (pj === 0) edgeHandles.push([3 * pj * nx + 3 * pi + k, ba[k] * bb[0]]);
|
|
2930
|
+
if (pj + 1 === rows) edgeHandles.push([(3 * pj + 3) * nx + 3 * pi + k, ba[k] * bb[3]]);
|
|
2931
|
+
}
|
|
2932
|
+
const edgeNorm = edgeHandles.reduce((acc, e) => acc + e[1] * e[1], 0);
|
|
2933
|
+
const edgePart = edgeNorm > 1e-12 ? nearBorder : 0;
|
|
2934
|
+
const innerShare = (1 - edgePart) * innerPart;
|
|
2935
|
+
const cornerShare = (1 - edgePart) * (1 - innerPart);
|
|
2936
|
+
for (let iter = 0; iter < 60; iter++) {
|
|
2937
|
+
const now = evalVectorMesh(m, s, t);
|
|
2938
|
+
const rem = { x: target.x - now.x, y: target.y - now.y };
|
|
2939
|
+
if (Math.hypot(rem.x, rem.y) < 1e-9) break;
|
|
2940
|
+
if (innerShare > 0 && norm > 0) for (const j of [1, 2]) for (const i of [1, 2]) move((3 * pj + j) * nx + 3 * pi + i, ba[i] * bb[j] / norm * innerShare, rem);
|
|
2941
|
+
if (edgePart > 0) for (const [idx, w] of edgeHandles) move(idx, w / edgeNorm * edgePart, rem);
|
|
2942
|
+
if (cornerShare > 0 && cornerNorm > 0) {
|
|
2943
|
+
for (const [ai, aj, w] of corner) {
|
|
2944
|
+
const k = w / cornerNorm * cornerShare;
|
|
2945
|
+
for (let dj = -1; dj <= 1; dj++) {
|
|
2946
|
+
for (let di = -1; di <= 1; di++) {
|
|
2947
|
+
const i = 3 * ai + di;
|
|
2948
|
+
const j = 3 * aj + dj;
|
|
2949
|
+
if (i >= 0 && j >= 0 && i < nx && j < ny) move(j * nx + i, k, rem);
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2952
|
+
}
|
|
2953
|
+
}
|
|
2954
|
+
for (let k = 0; k < 3; k++) smoothLines(m, Math.max(0, 3 * pi - 3), 3 * pi + 7, Math.max(0, 3 * pj - 3), 3 * pj + 7);
|
|
2955
|
+
}
|
|
2956
|
+
return m;
|
|
2957
|
+
}
|
|
2958
|
+
function polylineAt(pts) {
|
|
2959
|
+
const acc = [0];
|
|
2960
|
+
for (let i = 1; i < pts.length; i++) acc.push(acc[i - 1] + Math.hypot(pts[i].x - pts[i - 1].x, pts[i].y - pts[i - 1].y));
|
|
2961
|
+
const total = acc[acc.length - 1];
|
|
2962
|
+
return (u) => {
|
|
2963
|
+
if (!(total > 0)) return pts[0];
|
|
2964
|
+
const L = Math.min(1, Math.max(0, u)) * total;
|
|
2965
|
+
let i = 1;
|
|
2966
|
+
while (i < acc.length - 1 && acc[i] < L) i++;
|
|
2967
|
+
const seg = acc[i] - acc[i - 1];
|
|
2968
|
+
return lerp3(pts[i - 1], pts[i], seg > 0 ? (L - acc[i - 1]) / seg : 0);
|
|
2969
|
+
};
|
|
2970
|
+
}
|
|
2971
|
+
function sampleSubpath(sp, per = 24) {
|
|
2972
|
+
const n = sp.anchors.length;
|
|
2973
|
+
const out = [];
|
|
2974
|
+
for (let i = 0; i < n; i++) {
|
|
2975
|
+
const a = sp.anchors[i];
|
|
2976
|
+
const b = sp.anchors[(i + 1) % n];
|
|
2977
|
+
const c = [{ x: a.x, y: a.y }, _nullishCoalesce(a.out, () => ( a)), _nullishCoalesce(b.in, () => ( b)), { x: b.x, y: b.y }];
|
|
2978
|
+
for (let k = 0; k < per; k++) {
|
|
2979
|
+
const t = k / per;
|
|
2980
|
+
const ab = lerp3(c[0], c[1], t);
|
|
2981
|
+
const bc = lerp3(c[1], c[2], t);
|
|
2982
|
+
const cd = lerp3(c[2], c[3], t);
|
|
2983
|
+
out.push(lerp3(lerp3(ab, bc, t), lerp3(bc, cd, t), t));
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
return out;
|
|
2987
|
+
}
|
|
2988
|
+
function vectorMeshFromOutline(sp, columns = 4, rows = 4) {
|
|
2989
|
+
if (!sp.closed || sp.anchors.length < 2) return null;
|
|
2990
|
+
let ring = sampleSubpath(sp);
|
|
2991
|
+
const xs = ring.map((p) => p.x);
|
|
2992
|
+
const ys = ring.map((p) => p.y);
|
|
2993
|
+
const box = { x0: Math.min(...xs), y0: Math.min(...ys), x1: Math.max(...xs), y1: Math.max(...ys) };
|
|
2994
|
+
if (!(box.x1 - box.x0 > 1e-9 && box.y1 - box.y0 > 1e-9)) return null;
|
|
2995
|
+
const nearest = (c2) => {
|
|
2996
|
+
let best = 0;
|
|
2997
|
+
for (let i = 1; i < ring.length; i++) if (Math.hypot(ring[i].x - c2.x, ring[i].y - c2.y) < Math.hypot(ring[best].x - c2.x, ring[best].y - c2.y)) best = i;
|
|
2998
|
+
return best;
|
|
2999
|
+
};
|
|
3000
|
+
const cornersOf = () => [
|
|
3001
|
+
{ x: box.x0, y: box.y0 },
|
|
3002
|
+
{ x: box.x1, y: box.y0 },
|
|
3003
|
+
{ x: box.x1, y: box.y1 },
|
|
3004
|
+
{ x: box.x0, y: box.y1 }
|
|
3005
|
+
].map(nearest);
|
|
3006
|
+
let c = cornersOf();
|
|
3007
|
+
const n = ring.length;
|
|
3008
|
+
const fwd = (from, to) => (to - from + n) % n;
|
|
3009
|
+
if (!(fwd(c[0], c[1]) < fwd(c[0], c[2]) && fwd(c[0], c[2]) < fwd(c[0], c[3]))) {
|
|
3010
|
+
ring = ring.slice().reverse();
|
|
3011
|
+
c = cornersOf();
|
|
3012
|
+
if (!(fwd(c[0], c[1]) < fwd(c[0], c[2]) && fwd(c[0], c[2]) < fwd(c[0], c[3]))) return null;
|
|
3013
|
+
}
|
|
3014
|
+
if (new Set(c).size < 4) return null;
|
|
3015
|
+
const walk = (from, to) => {
|
|
3016
|
+
const out = [];
|
|
3017
|
+
for (let i = from; ; i = (i + 1) % n) {
|
|
3018
|
+
out.push(ring[i]);
|
|
3019
|
+
if (i === to) break;
|
|
3020
|
+
}
|
|
3021
|
+
return out;
|
|
3022
|
+
};
|
|
3023
|
+
const top = polylineAt(walk(c[0], c[1]));
|
|
3024
|
+
const right = polylineAt(walk(c[1], c[2]));
|
|
3025
|
+
const bottomLR = polylineAt(walk(c[2], c[3]).reverse());
|
|
3026
|
+
const leftTB = polylineAt(walk(c[3], c[0]).reverse());
|
|
3027
|
+
const p00 = top(0);
|
|
3028
|
+
const p10 = top(1);
|
|
3029
|
+
const p01 = bottomLR(0);
|
|
3030
|
+
const p11 = bottomLR(1);
|
|
3031
|
+
const coons = (s, t) => {
|
|
3032
|
+
const T = top(s);
|
|
3033
|
+
const B = bottomLR(s);
|
|
3034
|
+
const L = leftTB(t);
|
|
3035
|
+
const R = right(t);
|
|
3036
|
+
return {
|
|
3037
|
+
x: (1 - t) * T.x + t * B.x + (1 - s) * L.x + s * R.x - ((1 - s) * (1 - t) * p00.x + s * (1 - t) * p10.x + (1 - s) * t * p01.x + s * t * p11.x),
|
|
3038
|
+
y: (1 - t) * T.y + t * B.y + (1 - s) * L.y + s * R.y - ((1 - s) * (1 - t) * p00.y + s * (1 - t) * p10.y + (1 - s) * t * p01.y + s * t * p11.y)
|
|
3039
|
+
};
|
|
3040
|
+
};
|
|
3041
|
+
return fitVectorMesh(coons, evenKnots(clampCount(columns)), evenKnots(clampCount(rows)));
|
|
3042
|
+
}
|
|
3043
|
+
function vectorMeshOutline(m) {
|
|
3044
|
+
const nx = vectorMeshColumns(m);
|
|
3045
|
+
const ny = vectorMeshRows(m);
|
|
3046
|
+
const pt2 = (i, j) => m.points[j * nx + i];
|
|
3047
|
+
const runs = [];
|
|
3048
|
+
for (let i = 0; i + 3 < nx; i += 3) runs.push([pt2(i, 0), pt2(i + 1, 0), pt2(i + 2, 0), pt2(i + 3, 0)]);
|
|
3049
|
+
for (let j = 0; j + 3 < ny; j += 3) runs.push([pt2(nx - 1, j), pt2(nx - 1, j + 1), pt2(nx - 1, j + 2), pt2(nx - 1, j + 3)]);
|
|
3050
|
+
for (let i = nx - 1; i - 3 >= 0; i -= 3) runs.push([pt2(i, ny - 1), pt2(i - 1, ny - 1), pt2(i - 2, ny - 1), pt2(i - 3, ny - 1)]);
|
|
3051
|
+
for (let j = ny - 1; j - 3 >= 0; j -= 3) runs.push([pt2(0, j), pt2(0, j - 1), pt2(0, j - 2), pt2(0, j - 3)]);
|
|
3052
|
+
const anchors = runs.map((r, k) => {
|
|
3053
|
+
const prev = runs[(k + runs.length - 1) % runs.length];
|
|
3054
|
+
return { x: r[0].x, y: r[0].y, in: { ...prev[2] }, out: { ...r[1] } };
|
|
3055
|
+
});
|
|
3056
|
+
return { closed: true, anchors };
|
|
3057
|
+
}
|
|
3058
|
+
function vectorMeshEditPoints(m) {
|
|
3059
|
+
const nx = vectorMeshColumns(m);
|
|
3060
|
+
const ny = vectorMeshRows(m);
|
|
3061
|
+
const anchors = [];
|
|
3062
|
+
const handles = [];
|
|
3063
|
+
for (let j = 0; j < ny; j++) {
|
|
3064
|
+
for (let i = 0; i < nx; i++) {
|
|
3065
|
+
const ri = i % 3;
|
|
3066
|
+
const rj = j % 3;
|
|
3067
|
+
if (ri === 0 && rj === 0) anchors.push(j * nx + i);
|
|
3068
|
+
else if (ri === 0) handles.push({ index: j * nx + i, anchor: (rj === 1 ? j - 1 : j + 1) * nx + i });
|
|
3069
|
+
else if (rj === 0) handles.push({ index: j * nx + i, anchor: j * nx + (ri === 1 ? i - 1 : i + 1) });
|
|
3070
|
+
}
|
|
3071
|
+
}
|
|
3072
|
+
return { anchors, handles };
|
|
3073
|
+
}
|
|
3074
|
+
function vectorMeshGridCurves(m) {
|
|
3075
|
+
const nx = vectorMeshColumns(m);
|
|
3076
|
+
const ny = vectorMeshRows(m);
|
|
3077
|
+
const pt2 = (i, j) => m.points[j * nx + i];
|
|
3078
|
+
const out = [];
|
|
3079
|
+
for (let j = 0; j < ny; j += 3) for (let i = 0; i + 3 < nx; i += 3) out.push([pt2(i, j), pt2(i + 1, j), pt2(i + 2, j), pt2(i + 3, j)]);
|
|
3080
|
+
for (let i = 0; i < nx; i += 3) for (let j = 0; j + 3 < ny; j += 3) out.push([pt2(i, j), pt2(i, j + 1), pt2(i, j + 2), pt2(i, j + 3)]);
|
|
3081
|
+
return out;
|
|
3082
|
+
}
|
|
3083
|
+
|
|
2234
3084
|
// src/vector/appearance.ts
|
|
2235
3085
|
var VECTOR_EFFECT_DEFAULTS = {
|
|
2236
3086
|
trim: { start: 0, end: 50, offset: 0, mode: "simultaneous" },
|
|
@@ -2251,7 +3101,8 @@ var VECTOR_EFFECT_DEFAULTS = {
|
|
|
2251
3101
|
startOpacity: 100,
|
|
2252
3102
|
endOpacity: 100,
|
|
2253
3103
|
composite: "below"
|
|
2254
|
-
}
|
|
3104
|
+
},
|
|
3105
|
+
envelope: { style: "arc", bend: 50, horizontal: 0, vertical: 0, orientation: "horizontal", rows: 2, columns: 2, mesh: null }
|
|
2255
3106
|
};
|
|
2256
3107
|
var VECTOR_EFFECT_LABELS = {
|
|
2257
3108
|
trim: "Trim Paths",
|
|
@@ -2262,7 +3113,8 @@ var VECTOR_EFFECT_LABELS = {
|
|
|
2262
3113
|
wiggle: "Wiggle Paths",
|
|
2263
3114
|
offset: "Offset Paths",
|
|
2264
3115
|
merge: "Merge Paths",
|
|
2265
|
-
repeater: "Repeater"
|
|
3116
|
+
repeater: "Repeater",
|
|
3117
|
+
envelope: "Envelope"
|
|
2266
3118
|
};
|
|
2267
3119
|
var VECTOR_EFFECT_PARAM_SPECS = {
|
|
2268
3120
|
trim: [
|
|
@@ -2348,8 +3200,65 @@ var VECTOR_EFFECT_PARAM_SPECS = {
|
|
|
2348
3200
|
{ value: "above", label: "Above" }
|
|
2349
3201
|
]
|
|
2350
3202
|
}
|
|
3203
|
+
],
|
|
3204
|
+
envelope: [
|
|
3205
|
+
{
|
|
3206
|
+
key: "style",
|
|
3207
|
+
label: "Warp",
|
|
3208
|
+
kind: "select",
|
|
3209
|
+
options: [...VECTOR_WARP_STYLES.map((value) => ({ value, label: VECTOR_WARP_STYLE_LABELS[value] })), { value: "mesh", label: "Mesh" }]
|
|
3210
|
+
},
|
|
3211
|
+
{ key: "bend", label: "Bend %", kind: "number", min: -100, max: 100, step: 1, slider: true },
|
|
3212
|
+
{ key: "horizontal", label: "Horizontal distortion %", kind: "number", min: -100, max: 100, step: 1, slider: true },
|
|
3213
|
+
{ key: "vertical", label: "Vertical distortion %", kind: "number", min: -100, max: 100, step: 1, slider: true },
|
|
3214
|
+
{
|
|
3215
|
+
key: "orientation",
|
|
3216
|
+
label: "Orientation",
|
|
3217
|
+
kind: "select",
|
|
3218
|
+
options: [
|
|
3219
|
+
{ value: "horizontal", label: "Horizontal" },
|
|
3220
|
+
{ value: "vertical", label: "Vertical" }
|
|
3221
|
+
]
|
|
3222
|
+
},
|
|
3223
|
+
{ key: "rows", label: "Mesh rows", kind: "number", min: 1, max: 16, step: 1 },
|
|
3224
|
+
{ key: "columns", label: "Mesh columns", kind: "number", min: 1, max: 16, step: 1 }
|
|
2351
3225
|
]
|
|
2352
3226
|
};
|
|
3227
|
+
var cloneMesh = (m) => ({ us: m.us.slice(), vs: m.vs.slice(), points: m.points.map((p) => ({ x: p.x, y: p.y })) });
|
|
3228
|
+
function vectorEnvelopeMesh(params, bounds) {
|
|
3229
|
+
if (params.style === "mesh") return _nullishCoalesce(params.mesh, () => ( vectorIdentityMesh(bounds, params.columns, params.rows)));
|
|
3230
|
+
const preset = vectorWarpPresetMesh({ style: params.style, bend: params.bend, horizontal: params.horizontal, vertical: params.vertical, orientation: params.orientation }, bounds);
|
|
3231
|
+
return preset ? resizeVectorMesh(preset, params.columns, params.rows) : vectorIdentityMesh(bounds, params.columns, params.rows);
|
|
3232
|
+
}
|
|
3233
|
+
function vectorEnvelopeMap(params, bounds) {
|
|
3234
|
+
if (!bounds || !(bounds.width > 0 && bounds.height > 0)) return null;
|
|
3235
|
+
const mesh = params.style === "mesh" ? params.mesh : vectorWarpPresetMesh({ style: params.style, bend: params.bend, horizontal: params.horizontal, vertical: params.vertical, orientation: params.orientation }, bounds);
|
|
3236
|
+
if (!mesh) return null;
|
|
3237
|
+
const { x, y, width, height } = bounds;
|
|
3238
|
+
return (p) => evalVectorMesh(mesh, (p.x - x) / width, (p.y - y) / height);
|
|
3239
|
+
}
|
|
3240
|
+
function pathsBounds(paths) {
|
|
3241
|
+
let minX = Infinity;
|
|
3242
|
+
let minY = Infinity;
|
|
3243
|
+
let maxX = -Infinity;
|
|
3244
|
+
let maxY = -Infinity;
|
|
3245
|
+
for (const p of paths) {
|
|
3246
|
+
const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, p);
|
|
3247
|
+
if (!b) continue;
|
|
3248
|
+
minX = Math.min(minX, b.minX);
|
|
3249
|
+
minY = Math.min(minY, b.minY);
|
|
3250
|
+
maxX = Math.max(maxX, b.maxX);
|
|
3251
|
+
maxY = Math.max(maxY, b.maxY);
|
|
3252
|
+
}
|
|
3253
|
+
return minX <= maxX ? { x: minX, y: minY, width: maxX - minX, height: maxY - minY } : null;
|
|
3254
|
+
}
|
|
3255
|
+
function envelopePaths(paths, params) {
|
|
3256
|
+
const bounds = pathsBounds(paths);
|
|
3257
|
+
const f = vectorEnvelopeMap(params, bounds);
|
|
3258
|
+
if (!f || !bounds) return paths;
|
|
3259
|
+
const tol = Math.min(0.25, Math.max(0.01, Math.hypot(bounds.width, bounds.height) / 2e3));
|
|
3260
|
+
return paths.map((p) => p.length ? mapBezierPath(p, f, tol) : p);
|
|
3261
|
+
}
|
|
2353
3262
|
var isVec2 = (v2) => !!v2 && typeof v2 === "object" && Number.isFinite(v2.x) && Number.isFinite(v2.y);
|
|
2354
3263
|
function normalizeVectorEffectParams(type, params, base) {
|
|
2355
3264
|
const defaults = VECTOR_EFFECT_DEFAULTS[type];
|
|
@@ -2363,6 +3272,19 @@ function normalizeVectorEffectParams(type, params, base) {
|
|
|
2363
3272
|
else if (spec.kind === "vec2" && isVec2(v2)) out[spec.key] = { x: v2.x, y: v2.y };
|
|
2364
3273
|
else if (spec.kind === "select" && spec.options.some((o) => o.value === v2)) out[spec.key] = v2;
|
|
2365
3274
|
}
|
|
3275
|
+
if (type === "envelope") {
|
|
3276
|
+
const o = out;
|
|
3277
|
+
o.rows = Math.round(o.rows);
|
|
3278
|
+
o.columns = Math.round(o.columns);
|
|
3279
|
+
const given = _optionalChain([params, 'optionalAccess', _52 => _52.mesh]);
|
|
3280
|
+
let mesh = given !== void 0 ? isValidVectorMesh(given) ? cloneMesh(given) : null : o.mesh;
|
|
3281
|
+
if (o.style !== "mesh") mesh = null;
|
|
3282
|
+
if (mesh && given !== void 0) {
|
|
3283
|
+
o.columns = mesh.us.length - 1;
|
|
3284
|
+
o.rows = mesh.vs.length - 1;
|
|
3285
|
+
} else if (mesh) mesh = resizeVectorMesh(mesh, o.columns, o.rows);
|
|
3286
|
+
o.mesh = mesh;
|
|
3287
|
+
}
|
|
2366
3288
|
return out;
|
|
2367
3289
|
}
|
|
2368
3290
|
function createVectorEffect(type, id, params) {
|
|
@@ -2371,10 +3293,10 @@ function createVectorEffect(type, id, params) {
|
|
|
2371
3293
|
}
|
|
2372
3294
|
var isEnabled = (e) => e.enabled !== false && !!VECTOR_EFFECT_DEFAULTS[e.type];
|
|
2373
3295
|
function activeVectorEffects(node) {
|
|
2374
|
-
return _nullishCoalesce(_optionalChain([node, 'access',
|
|
3296
|
+
return _nullishCoalesce(_optionalChain([node, 'access', _53 => _53.effects, 'optionalAccess', _54 => _54.filter, 'call', _55 => _55(isEnabled)]), () => ( []));
|
|
2375
3297
|
}
|
|
2376
3298
|
function hasOwnVectorAppearance(node) {
|
|
2377
|
-
return node.type === "group" && !!node.liveBoolean || !!_optionalChain([node, 'access',
|
|
3299
|
+
return node.type === "group" && !!node.liveBoolean || !!_optionalChain([node, 'access', _56 => _56.effects, 'optionalAccess', _57 => _57.some, 'call', _58 => _58(isEnabled)]);
|
|
2378
3300
|
}
|
|
2379
3301
|
var liveCache = /* @__PURE__ */ new WeakMap();
|
|
2380
3302
|
function hasVectorAppearance(node) {
|
|
@@ -2386,7 +3308,7 @@ function hasVectorAppearance(node) {
|
|
|
2386
3308
|
return v2;
|
|
2387
3309
|
}
|
|
2388
3310
|
function isVectorLiveBoolean(node) {
|
|
2389
|
-
return _optionalChain([node, 'optionalAccess',
|
|
3311
|
+
return _optionalChain([node, 'optionalAccess', _59 => _59.type]) === "group" && !!node.liveBoolean;
|
|
2390
3312
|
}
|
|
2391
3313
|
function vectorOperandOperation(group, child) {
|
|
2392
3314
|
return _nullishCoalesce(_nullishCoalesce(child.booleanOperation, () => ( group.liveBoolean)), () => ( "union"));
|
|
@@ -2503,7 +3425,7 @@ var compareOrder = (a, b) => {
|
|
|
2503
3425
|
for (let i = 0; i < n; i++) if (a[i] !== b[i]) return a[i] - b[i];
|
|
2504
3426
|
return a.length - b.length;
|
|
2505
3427
|
};
|
|
2506
|
-
var add3 = (a, b) => ({ x: a.x + (_nullishCoalesce(_optionalChain([b, 'optionalAccess',
|
|
3428
|
+
var add3 = (a, b) => ({ x: a.x + (_nullishCoalesce(_optionalChain([b, 'optionalAccess', _60 => _60.x]), () => ( 0))), y: a.y + (_nullishCoalesce(_optionalChain([b, 'optionalAccess', _61 => _61.y]), () => ( 0))) });
|
|
2507
3429
|
var mapPaths = (shapes, fn) => {
|
|
2508
3430
|
const out = fn(shapes.map((s) => s.path));
|
|
2509
3431
|
return shapes.map((s, i) => ({ ...s, path: _nullishCoalesce(out[i], () => ( [])) }));
|
|
@@ -2543,6 +3465,11 @@ function applyVectorEffects(shapes, effects) {
|
|
|
2543
3465
|
list = [{ ...first, path: mergePaths(list.map((s) => s.path), e.params.mode) }];
|
|
2544
3466
|
break;
|
|
2545
3467
|
}
|
|
3468
|
+
case "envelope": {
|
|
3469
|
+
const params = e.params;
|
|
3470
|
+
list = mapPaths(list, (p) => envelopePaths(p, params));
|
|
3471
|
+
break;
|
|
3472
|
+
}
|
|
2546
3473
|
case "repeater": {
|
|
2547
3474
|
const r = e.params;
|
|
2548
3475
|
const copies = repeatPaths(
|
|
@@ -2589,14 +3516,35 @@ function liveBooleanShapes(group) {
|
|
|
2589
3516
|
return [{ source, path: foldVectorBooleanOperands(operands), opacity: 1, order: [0] }];
|
|
2590
3517
|
}
|
|
2591
3518
|
var shapeCache = /* @__PURE__ */ new WeakMap();
|
|
3519
|
+
function baseShapes(node) {
|
|
3520
|
+
if (node.type === "path") return [{ source: node, path: subpathsToBezier(node.subpaths), opacity: 1, order: [] }];
|
|
3521
|
+
if (node.liveBoolean) return liveBooleanShapes(node);
|
|
3522
|
+
return node.children.flatMap((c, i) => childShapes(c, i));
|
|
3523
|
+
}
|
|
3524
|
+
function vectorEffectInputPaths(node, effectId) {
|
|
3525
|
+
const list = _nullishCoalesce(node.effects, () => ( []));
|
|
3526
|
+
const i = list.findIndex((e) => e.id === effectId);
|
|
3527
|
+
if (i < 0) return null;
|
|
3528
|
+
return applyVectorEffects(baseShapes(node), list.slice(0, i)).map((s) => s.path);
|
|
3529
|
+
}
|
|
3530
|
+
function vectorEffectInputBounds(node, effectId) {
|
|
3531
|
+
const paths = vectorEffectInputPaths(node, effectId);
|
|
3532
|
+
return paths ? pathsBounds(paths) : null;
|
|
3533
|
+
}
|
|
3534
|
+
function vectorNodeEnvelope(node) {
|
|
3535
|
+
return _nullishCoalesce(_optionalChain([node, 'optionalAccess', _62 => _62.effects, 'optionalAccess', _63 => _63.find, 'call', _64 => _64((e) => e.type === "envelope" && e.enabled !== false)]), () => ( null));
|
|
3536
|
+
}
|
|
3537
|
+
function vectorEnvelopeFrame(node, effectId) {
|
|
3538
|
+
const e = effectId ? _optionalChain([node, 'access', _65 => _65.effects, 'optionalAccess', _66 => _66.find, 'call', _67 => _67((x) => x.id === effectId)]) : vectorNodeEnvelope(node);
|
|
3539
|
+
if (!e || e.type !== "envelope") return null;
|
|
3540
|
+
const bounds = vectorEffectInputBounds(node, e.id);
|
|
3541
|
+
if (!bounds || !(bounds.width > 0 && bounds.height > 0)) return null;
|
|
3542
|
+
return { effectId: e.id, bounds, mesh: vectorEnvelopeMesh(e.params, bounds) };
|
|
3543
|
+
}
|
|
2592
3544
|
function vectorAppearanceShapes(node) {
|
|
2593
3545
|
const hit = shapeCache.get(node);
|
|
2594
3546
|
if (hit) return hit;
|
|
2595
|
-
|
|
2596
|
-
if (node.type === "path") base = [{ source: node, path: subpathsToBezier(node.subpaths), opacity: 1, order: [] }];
|
|
2597
|
-
else if (node.liveBoolean) base = liveBooleanShapes(node);
|
|
2598
|
-
else base = node.children.flatMap((c, i) => childShapes(c, i));
|
|
2599
|
-
const out = applyVectorEffects(base, node.effects).sort((a, b) => compareOrder(a.order, b.order));
|
|
3547
|
+
const out = applyVectorEffects(baseShapes(node), node.effects).sort((a, b) => compareOrder(a.order, b.order));
|
|
2600
3548
|
shapeCache.set(node, out);
|
|
2601
3549
|
return out;
|
|
2602
3550
|
}
|
|
@@ -2693,10 +3641,19 @@ function sanitizeVectorEffects(value) {
|
|
|
2693
3641
|
}
|
|
2694
3642
|
return out;
|
|
2695
3643
|
}
|
|
2696
|
-
function transformVectorEffects(effects, m) {
|
|
3644
|
+
function transformVectorEffects(effects, m, node) {
|
|
2697
3645
|
const lin = (v2) => ({ x: m[0] * v2.x + m[2] * v2.y, y: m[1] * v2.x + m[3] * v2.y });
|
|
3646
|
+
const full = (v2) => ({ x: m[0] * v2.x + m[2] * v2.y + m[4], y: m[1] * v2.x + m[3] * v2.y + m[5] });
|
|
2698
3647
|
const mirror = m[0] * m[3] - m[1] * m[2] < 0 ? -1 : 1;
|
|
3648
|
+
const axisScale = Math.abs(m[1]) < 1e-12 && Math.abs(m[2]) < 1e-12 && m[0] > 0 && m[3] > 0;
|
|
2699
3649
|
return effects.map((e) => {
|
|
3650
|
+
if (e.type === "envelope") {
|
|
3651
|
+
if (e.params.style === "mesh") return e.params.mesh ? { ...e, params: { ...e.params, mesh: mapVectorMeshPoints(e.params.mesh, full) } } : e;
|
|
3652
|
+
if (axisScale || !node) return e;
|
|
3653
|
+
const bounds = vectorEffectInputBounds(node, e.id);
|
|
3654
|
+
if (!bounds || !vectorEnvelopeMap(e.params, bounds)) return e;
|
|
3655
|
+
return { ...e, params: { ...e.params, style: "mesh", mesh: mapVectorMeshPoints(vectorEnvelopeMesh(e.params, bounds), full) } };
|
|
3656
|
+
}
|
|
2700
3657
|
if (e.type === "twist") return { ...e, params: { ...e.params, center: lin(e.params.center), angle: e.params.angle * mirror } };
|
|
2701
3658
|
if (e.type === "repeater")
|
|
2702
3659
|
return { ...e, params: { ...e.params, position: lin(e.params.position), anchor: lin(e.params.anchor), rotation: e.params.rotation * mirror } };
|
|
@@ -2931,7 +3888,7 @@ function boundsFromPoints(a, b) {
|
|
|
2931
3888
|
}
|
|
2932
3889
|
function hitTestVectorNode(node, p, tolerance = 0, parent = IDENTITY_MATRIX, options = {}) {
|
|
2933
3890
|
if (node.visible === false) return false;
|
|
2934
|
-
if (!(node.type === "group" && (!hasOwnVectorAppearance(node) || _optionalChain([options, 'access',
|
|
3891
|
+
if (!(node.type === "group" && (!hasOwnVectorAppearance(node) || _optionalChain([options, 'access', _68 => _68.entered, 'optionalAccess', _69 => _69.has, 'call', _70 => _70(node.id)])))) node = expandVectorAppearance(node);
|
|
2935
3892
|
if (node.type === "group") {
|
|
2936
3893
|
const m = multiplyMatrices(nodeMatrix(node), parent);
|
|
2937
3894
|
return node.children.some((c) => hitTestVectorNode(c, p, tolerance, m, options));
|
|
@@ -3030,17 +3987,17 @@ function mapAnchor(a, m) {
|
|
|
3030
3987
|
}
|
|
3031
3988
|
function bakeIntoGeometry(node, m) {
|
|
3032
3989
|
if (isIdentityMatrix(m)) return node;
|
|
3033
|
-
if (_optionalChain([node, 'access',
|
|
3990
|
+
if (_optionalChain([node, 'access', _71 => _71.effects, 'optionalAccess', _72 => _72.length])) node = { ...node, effects: transformVectorEffects(node.effects, m, node) };
|
|
3034
3991
|
if (node.type === "group") {
|
|
3035
3992
|
const group = node;
|
|
3036
3993
|
const children = group.children.map((c) => transformVectorNode(c, m));
|
|
3037
|
-
const spine = _optionalChain([group, 'access',
|
|
3994
|
+
const spine = _optionalChain([group, 'access', _73 => _73.blend, 'optionalAccess', _74 => _74.spine]);
|
|
3038
3995
|
if (!spine) return { ...group, children };
|
|
3039
3996
|
const moved = { closed: spine.closed, anchors: spine.anchors.map((a) => mapAnchor(a, m)) };
|
|
3040
3997
|
return { ...group, children, blend: { ...group.blend, spine: moved } };
|
|
3041
3998
|
}
|
|
3042
3999
|
const path = node;
|
|
3043
|
-
const mirrored = m[0] * m[3] - m[1] * m[2] < 0 && _optionalChain([path, 'access',
|
|
4000
|
+
const mirrored = m[0] * m[3] - m[1] * m[2] < 0 && _optionalChain([path, 'access', _75 => _75.strokeWidthProfile, 'optionalAccess', _76 => _76.length]);
|
|
3044
4001
|
return {
|
|
3045
4002
|
...path,
|
|
3046
4003
|
...mirrored ? { strokeWidthProfile: mirrorWidthProfile(path.strokeWidthProfile) } : {},
|
|
@@ -3414,7 +4371,7 @@ function applyVectorCornersAttribute(subpaths, value) {
|
|
|
3414
4371
|
for (const item of value.trim().split(/\s+/)) {
|
|
3415
4372
|
const m = /^(\d+)\.(\d+):([\d.eE+-]+)(?::([a-z]+))?$/.exec(item);
|
|
3416
4373
|
if (!m) continue;
|
|
3417
|
-
const a = _optionalChain([subpaths, 'access',
|
|
4374
|
+
const a = _optionalChain([subpaths, 'access', _77 => _77[+m[1]], 'optionalAccess', _78 => _78.anchors, 'access', _79 => _79[+m[2]]]);
|
|
3418
4375
|
const radius = parseFloat(m[3]);
|
|
3419
4376
|
if (!a || !(radius > 0)) continue;
|
|
3420
4377
|
const kind = VECTOR_CORNER_KINDS.includes(m[4]) ? m[4] : void 0;
|
|
@@ -3436,7 +4393,7 @@ function vectorPaintToSvg(paint, gradientId, options = {}) {
|
|
|
3436
4393
|
const precision = _nullishCoalesce(options.precision, () => ( 3));
|
|
3437
4394
|
const key = `${gradientId}|${role}|${precision}`;
|
|
3438
4395
|
const owner = _nullishCoalesce(options.node, () => ( paint));
|
|
3439
|
-
const cached = _optionalChain([paintCache, 'access',
|
|
4396
|
+
const cached = _optionalChain([paintCache, 'access', _80 => _80.get, 'call', _81 => _81(owner), 'optionalAccess', _82 => _82.get, 'call', _83 => _83(key)]);
|
|
3440
4397
|
if (cached && (!options.node || (role === "fill" ? options.node.fill : options.node.stroke) === paint)) return { value: `url(#${gradientId})`, defs: cached };
|
|
3441
4398
|
const node = options.node;
|
|
3442
4399
|
const bounds = node ? vectorPathLocalBounds(node) : null;
|
|
@@ -3555,7 +4512,7 @@ function vectorDocumentToSvg(doc, options = {}) {
|
|
|
3555
4512
|
if (hasOwnVectorAppearance(node)) {
|
|
3556
4513
|
const live2 = {
|
|
3557
4514
|
kind: node.type,
|
|
3558
|
-
..._optionalChain([node, 'access',
|
|
4515
|
+
..._optionalChain([node, 'access', _84 => _84.effects, 'optionalAccess', _85 => _85.length]) ? { effects: node.effects } : {},
|
|
3559
4516
|
...node.type === "group" && node.liveBoolean ? { liveBoolean: node.liveBoolean } : {}
|
|
3560
4517
|
};
|
|
3561
4518
|
lines.push(`${indent(depth)}<g${common(node)} data-vector-live="${escapeAttr(JSON.stringify(live2))}">`);
|
|
@@ -3588,7 +4545,7 @@ function vectorDocumentToSvg(doc, options = {}) {
|
|
|
3588
4545
|
let out2 = ` stroke="${escapeAttr(stroke.value)}" stroke-width="${num2(width)}"`;
|
|
3589
4546
|
if (node.strokeLinecap && node.strokeLinecap !== "butt") out2 += ` stroke-linecap="${node.strokeLinecap}"`;
|
|
3590
4547
|
if (node.strokeLinejoin && node.strokeLinejoin !== "miter") out2 += ` stroke-linejoin="${node.strokeLinejoin}"`;
|
|
3591
|
-
if (_optionalChain([node, 'access',
|
|
4548
|
+
if (_optionalChain([node, 'access', _86 => _86.strokeDasharray, 'optionalAccess', _87 => _87.length])) out2 += ` stroke-dasharray="${node.strokeDasharray.map(num2).join(" ")}"`;
|
|
3592
4549
|
return out2;
|
|
3593
4550
|
};
|
|
3594
4551
|
const parts = stroke.value !== "none" ? vectorStrokeSvgParts(node, `${prefix}clip-${node.id}`, precision) : void 0;
|
|
@@ -3608,7 +4565,7 @@ function vectorDocumentToSvg(doc, options = {}) {
|
|
|
3608
4565
|
data += ` data-vector-width-profile="${widthProfileToAttribute(profile)}"`;
|
|
3609
4566
|
if (node.strokeLinecap && node.strokeLinecap !== "butt") data += ` data-vector-stroke-linecap="${node.strokeLinecap}"`;
|
|
3610
4567
|
if (node.strokeLinejoin && node.strokeLinejoin !== "miter") data += ` data-vector-stroke-linejoin="${node.strokeLinejoin}"`;
|
|
3611
|
-
if (_optionalChain([node, 'access',
|
|
4568
|
+
if (_optionalChain([node, 'access', _88 => _88.strokeDasharray, 'optionalAccess', _89 => _89.length])) data += ` data-vector-stroke-dasharray="${node.strokeDasharray.map(num2).join(" ")}"`;
|
|
3612
4569
|
}
|
|
3613
4570
|
lines.push(`${indent(depth)}<g${common(node)}${data}>`);
|
|
3614
4571
|
lines.push(`${indent(depth + 1)}<path data-vector-part="fill" d="${d}"${fillAttrs}${live}/>`);
|
|
@@ -3791,9 +4748,9 @@ function resolveGradient(id, raw) {
|
|
|
3791
4748
|
for (let el = first; el && !chain.includes(el) && chain.length < 32; ) {
|
|
3792
4749
|
chain.push(el);
|
|
3793
4750
|
const href = _nullishCoalesce(el.attrs.href, () => ( el.attrs["xlink:href"]));
|
|
3794
|
-
el = _optionalChain([href, 'optionalAccess',
|
|
4751
|
+
el = _optionalChain([href, 'optionalAccess', _90 => _90.startsWith, 'call', _91 => _91("#")]) ? raw.get(href.slice(1)) : void 0;
|
|
3795
4752
|
}
|
|
3796
|
-
const attr = (name) => _optionalChain([chain, 'access',
|
|
4753
|
+
const attr = (name) => _optionalChain([chain, 'access', _92 => _92.find, 'call', _93 => _93((el) => el.attrs[name] !== void 0), 'optionalAccess', _94 => _94.attrs, 'access', _95 => _95[name]]);
|
|
3797
4754
|
const stops = _nullishCoalesce(chain.map(readStops).find((s) => s.length), () => ( []));
|
|
3798
4755
|
if (!stops.length) return null;
|
|
3799
4756
|
const user = attr("gradientUnits") === "userSpaceOnUse";
|
|
@@ -3835,8 +4792,8 @@ function resolveGradient(id, raw) {
|
|
|
3835
4792
|
const len2 = Math.hypot(x2 - x1, y2 - y1);
|
|
3836
4793
|
const d = len2 > 0 ? { x: (x2 - x1) / len2, y: (y2 - y1) / len2 } : { x: 0, y: 1 };
|
|
3837
4794
|
const along2 = (x, y) => x * d.x + y * d.y;
|
|
3838
|
-
const
|
|
3839
|
-
if (
|
|
4795
|
+
const same2 = len2 > 0 && Math.abs((c.x2 - c.x1) * d.y - (c.y2 - c.y1) * d.x) < 1e-3 && Math.abs(along2(c.x1, c.y1) - along2(x1, y1)) < 1e-3 && Math.abs(along2(c.x2, c.y2) - along2(x2, y2)) < 1e-3;
|
|
4796
|
+
if (same2) return { type: "linear", angle, stops, ...spread };
|
|
3840
4797
|
}
|
|
3841
4798
|
const start = { x: x1, y: y1 };
|
|
3842
4799
|
const end = { x: x2, y: y2 };
|
|
@@ -3943,7 +4900,7 @@ function parseVectorSvg(svg, options = {}) {
|
|
|
3943
4900
|
const part = (name) => g.children.find((c) => c.name === "path" && c.attrs["data-vector-part"] === name);
|
|
3944
4901
|
const fillEl = part("fill");
|
|
3945
4902
|
const subpaths = fillEl ? shapeOf(fillEl) : null;
|
|
3946
|
-
if (!fillEl || !_optionalChain([subpaths, 'optionalAccess',
|
|
4903
|
+
if (!fillEl || !_optionalChain([subpaths, 'optionalAccess', _96 => _96.length])) return null;
|
|
3947
4904
|
const a = g.attrs;
|
|
3948
4905
|
const fs = readStyle(fillEl, style);
|
|
3949
4906
|
const strokeEl = part("stroke");
|
|
@@ -3980,7 +4937,7 @@ function parseVectorSvg(svg, options = {}) {
|
|
|
3980
4937
|
...profile.length ? { strokeWidthProfile: profile } : {},
|
|
3981
4938
|
...keptCap ? { strokeLinecap: keptCap } : {},
|
|
3982
4939
|
...keptJoin ? { strokeLinejoin: keptJoin } : {},
|
|
3983
|
-
..._optionalChain([keptDash, 'optionalAccess',
|
|
4940
|
+
..._optionalChain([keptDash, 'optionalAccess', _97 => _97.length]) ? { strokeDasharray: keptDash } : {}
|
|
3984
4941
|
};
|
|
3985
4942
|
return placed(node, m);
|
|
3986
4943
|
};
|
|
@@ -4653,7 +5610,7 @@ function interpolateVectorPaint(a, b, t) {
|
|
|
4653
5610
|
return t < 0.5 ? a : b;
|
|
4654
5611
|
}
|
|
4655
5612
|
function interpolateWidthProfiles(a, b, t) {
|
|
4656
|
-
if (!_optionalChain([a, 'optionalAccess',
|
|
5613
|
+
if (!_optionalChain([a, 'optionalAccess', _98 => _98.length]) && !_optionalChain([b, 'optionalAccess', _99 => _99.length])) return null;
|
|
4657
5614
|
const at2 = [..._nullishCoalesce(a, () => ( [])), ..._nullishCoalesce(b, () => ( [])), { t: 0 }, { t: 1 }].map((p) => p.t).sort((x, y) => x - y);
|
|
4658
5615
|
const ts = at2.filter((v2, i) => i === 0 || v2 - at2[i - 1] > 1e-6);
|
|
4659
5616
|
return ts.map((pos) => {
|
|
@@ -4663,7 +5620,7 @@ function interpolateWidthProfiles(a, b, t) {
|
|
|
4663
5620
|
});
|
|
4664
5621
|
}
|
|
4665
5622
|
function lerpDashes(a, b, t) {
|
|
4666
|
-
const dashed = (d) => !!_optionalChain([d, 'optionalAccess',
|
|
5623
|
+
const dashed = (d) => !!_optionalChain([d, 'optionalAccess', _100 => _100.length]) && d.some((v2) => v2 > 0);
|
|
4667
5624
|
if (!dashed(a) && !dashed(b)) return t < 0.5 ? a : b;
|
|
4668
5625
|
const even = (p) => p.length % 2 ? [...p, ...p] : p;
|
|
4669
5626
|
const solid = (p) => {
|
|
@@ -4690,7 +5647,7 @@ function interpolateVectorStyle(a, b, t) {
|
|
|
4690
5647
|
for (const key of ["startArrowScale", "endArrowScale"])
|
|
4691
5648
|
if (a[key] !== void 0 || b[key] !== void 0) out[key] = lerpN(_nullishCoalesce(a[key], () => ( 1)), _nullishCoalesce(b[key], () => ( 1)), t);
|
|
4692
5649
|
const dash = lerpDashes(a.strokeDasharray, b.strokeDasharray, t);
|
|
4693
|
-
if (_optionalChain([dash, 'optionalAccess',
|
|
5650
|
+
if (_optionalChain([dash, 'optionalAccess', _101 => _101.length])) out.strokeDasharray = dash;
|
|
4694
5651
|
const profile = interpolateWidthProfiles(a.strokeWidthProfile, b.strokeWidthProfile, t);
|
|
4695
5652
|
if (profile) out.strokeWidthProfile = profile;
|
|
4696
5653
|
return out;
|
|
@@ -4701,7 +5658,7 @@ function reversedStyle(s) {
|
|
|
4701
5658
|
out.endArrow = s.startArrow;
|
|
4702
5659
|
out.startArrowScale = s.endArrowScale;
|
|
4703
5660
|
out.endArrowScale = s.startArrowScale;
|
|
4704
|
-
if (_optionalChain([s, 'access',
|
|
5661
|
+
if (_optionalChain([s, 'access', _102 => _102.strokeWidthProfile, 'optionalAccess', _103 => _103.length])) out.strokeWidthProfile = reverseWidthProfile(s.strokeWidthProfile);
|
|
4705
5662
|
for (const k of ["startArrow", "endArrow", "startArrowScale", "endArrowScale"]) if (out[k] === void 0) delete out[k];
|
|
4706
5663
|
return out;
|
|
4707
5664
|
}
|
|
@@ -4847,11 +5804,11 @@ function vectorBlendKeys(group) {
|
|
|
4847
5804
|
}
|
|
4848
5805
|
function resolveVectorBlendOptions(options) {
|
|
4849
5806
|
return {
|
|
4850
|
-
spacing: _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
4851
|
-
steps: _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
4852
|
-
distance: _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
4853
|
-
orientToSpine: _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
4854
|
-
linear: _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
5807
|
+
spacing: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _104 => _104.spacing]), () => ( "steps")),
|
|
5808
|
+
steps: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _105 => _105.steps]), () => ( DEFAULT_VECTOR_BLEND_STEPS)),
|
|
5809
|
+
distance: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _106 => _106.distance]), () => ( DEFAULT_VECTOR_BLEND_DISTANCE)),
|
|
5810
|
+
orientToSpine: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _107 => _107.orientToSpine]), () => ( false)),
|
|
5811
|
+
linear: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _108 => _108.linear]), () => ( false))
|
|
4855
5812
|
};
|
|
4856
5813
|
}
|
|
4857
5814
|
function paintColors(p) {
|
|
@@ -4893,8 +5850,8 @@ function vectorBlendStepCount(a, b, options, length2) {
|
|
|
4893
5850
|
if (cd > 1 / 255) return Math.min(VECTOR_BLEND_MAX_SMOOTH_STEPS, Math.max(1, Math.ceil(cd * 255 / 2)));
|
|
4894
5851
|
const ba = vectorNodeBounds(a);
|
|
4895
5852
|
const bb = vectorNodeBounds(b);
|
|
4896
|
-
const
|
|
4897
|
-
return Math.min(VECTOR_BLEND_MAX_SMOOTH_STEPS, Math.max(1, Math.ceil(
|
|
5853
|
+
const dist5 = ba && bb ? Math.max(Math.abs(ba.x - bb.x), Math.abs(ba.y - bb.y), Math.abs(ba.x + ba.width - bb.x - bb.width), Math.abs(ba.y + ba.height - bb.y - bb.height)) : length2;
|
|
5854
|
+
return Math.min(VECTOR_BLEND_MAX_SMOOTH_STEPS, Math.max(1, Math.ceil(dist5 / 2)));
|
|
4898
5855
|
}
|
|
4899
5856
|
return Math.min(VECTOR_BLEND_MAX_STEPS, Math.max(1, Math.round(Number.isFinite(o.steps) ? o.steps : DEFAULT_VECTOR_BLEND_STEPS)));
|
|
4900
5857
|
}
|
|
@@ -4939,7 +5896,7 @@ function vectorBlendRailAt(rail, s) {
|
|
|
4939
5896
|
function vectorBlendSpine(group) {
|
|
4940
5897
|
const keys = vectorBlendKeys(group);
|
|
4941
5898
|
if (keys.length < 2) return null;
|
|
4942
|
-
const stored = _optionalChain([group, 'access',
|
|
5899
|
+
const stored = _optionalChain([group, 'access', _109 => _109.blend, 'optionalAccess', _110 => _110.spine]);
|
|
4943
5900
|
if (stored && stored.anchors.length >= 2) {
|
|
4944
5901
|
const rail2 = vectorBlendRail(stored);
|
|
4945
5902
|
if (rail2) {
|
|
@@ -4960,7 +5917,7 @@ function vectorBlendKeyTargets(group) {
|
|
|
4960
5917
|
}
|
|
4961
5918
|
var morphCache = /* @__PURE__ */ new WeakMap();
|
|
4962
5919
|
function morphFor(a, b, blend) {
|
|
4963
|
-
const starts = [_nullishCoalesce(_optionalChain([blend, 'access',
|
|
5920
|
+
const starts = [_nullishCoalesce(_optionalChain([blend, 'access', _111 => _111.starts, 'optionalAccess', _112 => _112[a.id]]), () => ( null)), _nullishCoalesce(_optionalChain([blend, 'access', _113 => _113.starts, 'optionalAccess', _114 => _114[b.id]]), () => ( null))];
|
|
4964
5921
|
const key = JSON.stringify([!!blend.linear, starts]);
|
|
4965
5922
|
let inner = morphCache.get(a);
|
|
4966
5923
|
if (!inner) morphCache.set(a, inner = /* @__PURE__ */ new WeakMap());
|
|
@@ -5059,16 +6016,179 @@ function releaseVectorBlend(group, newId) {
|
|
|
5059
6016
|
const m = nodeMatrix(group);
|
|
5060
6017
|
const opacity = group.opacity;
|
|
5061
6018
|
const keys = vectorBlendKeys(group).map((c) => group.transform ? transformVectorNode(c, m) : c).map((c) => opacity !== void 0 && opacity < 1 ? { ...c, opacity: (_nullishCoalesce(c.opacity, () => ( 1))) * opacity } : c);
|
|
5062
|
-
const spine = _optionalChain([group, 'access',
|
|
6019
|
+
const spine = _optionalChain([group, 'access', _115 => _115.blend, 'optionalAccess', _116 => _116.spine]);
|
|
5063
6020
|
if (!spine || spine.anchors.length < 2) return keys;
|
|
5064
6021
|
const path = { id: newId(), type: "path", name: "Spine", fill: null, stroke: null, subpaths: [{ closed: spine.closed, anchors: spine.anchors.map((a) => ({ ...a })) }] };
|
|
5065
6022
|
return [...keys, group.transform ? transformVectorNode(path, m) : path];
|
|
5066
6023
|
}
|
|
5067
6024
|
|
|
6025
|
+
// src/vector/perspective.ts
|
|
6026
|
+
function solve8(rows) {
|
|
6027
|
+
const m = rows.map((r) => r.slice());
|
|
6028
|
+
for (let col = 0; col < 8; col++) {
|
|
6029
|
+
let pivot = col;
|
|
6030
|
+
for (let r = col + 1; r < 8; r++) if (Math.abs(m[r][col]) > Math.abs(m[pivot][col])) pivot = r;
|
|
6031
|
+
if (!(Math.abs(m[pivot][col]) >= 1e-12)) return null;
|
|
6032
|
+
[m[col], m[pivot]] = [m[pivot], m[col]];
|
|
6033
|
+
const p = m[col];
|
|
6034
|
+
for (let r = 0; r < 8; r++) {
|
|
6035
|
+
if (r === col) continue;
|
|
6036
|
+
const f = m[r][col] / p[col];
|
|
6037
|
+
if (f !== 0) for (let k = 0; k < 9; k++) m[r][k] -= f * p[k];
|
|
6038
|
+
}
|
|
6039
|
+
}
|
|
6040
|
+
const out = [];
|
|
6041
|
+
for (let i = 0; i < 8; i++) {
|
|
6042
|
+
const v2 = m[i][8] / m[i][i];
|
|
6043
|
+
if (!Number.isFinite(v2)) return null;
|
|
6044
|
+
out.push(v2);
|
|
6045
|
+
}
|
|
6046
|
+
return out;
|
|
6047
|
+
}
|
|
6048
|
+
function applyVectorHomography(h, p) {
|
|
6049
|
+
const w = h[6] * p.x + h[7] * p.y + h[8];
|
|
6050
|
+
if (!Number.isFinite(w) || Math.abs(w) < 1e-12) return null;
|
|
6051
|
+
const x = (h[0] * p.x + h[1] * p.y + h[2]) / w;
|
|
6052
|
+
const y = (h[3] * p.x + h[4] * p.y + h[5]) / w;
|
|
6053
|
+
return Number.isFinite(x) && Number.isFinite(y) ? { x, y } : null;
|
|
6054
|
+
}
|
|
6055
|
+
var finite = (p) => Number.isFinite(p.x) && Number.isFinite(p.y);
|
|
6056
|
+
function vectorHomography(from, to) {
|
|
6057
|
+
if (from.length !== 4 || to.length !== 4 || ![...from, ...to].every(finite)) return null;
|
|
6058
|
+
const rows = [];
|
|
6059
|
+
for (let i = 0; i < 4; i++) {
|
|
6060
|
+
const { x, y } = from[i];
|
|
6061
|
+
const { x: u, y: v2 } = to[i];
|
|
6062
|
+
rows.push([x, y, 1, 0, 0, 0, -u * x, -u * y, u]);
|
|
6063
|
+
rows.push([0, 0, 0, x, y, 1, -v2 * x, -v2 * y, v2]);
|
|
6064
|
+
}
|
|
6065
|
+
const h = solve8(rows);
|
|
6066
|
+
if (!h) return null;
|
|
6067
|
+
const out = [h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], 1];
|
|
6068
|
+
for (let i = 0; i < 4; i++) {
|
|
6069
|
+
const r = applyVectorHomography(out, from[i]);
|
|
6070
|
+
const q = to[i];
|
|
6071
|
+
const scale3 = 1 + Math.max(Math.abs(q.x), Math.abs(q.y));
|
|
6072
|
+
if (!r || Math.abs(r.x - q.x) > 1e-6 * scale3 || Math.abs(r.y - q.y) > 1e-6 * scale3) return null;
|
|
6073
|
+
}
|
|
6074
|
+
return out;
|
|
6075
|
+
}
|
|
6076
|
+
function vectorHomographyKeepsQuad(h, quad) {
|
|
6077
|
+
const ws = quad.map((p) => h[6] * p.x + h[7] * p.y + h[8]);
|
|
6078
|
+
return ws.every((w) => w > 1e-9) || ws.every((w) => w < -1e-9);
|
|
6079
|
+
}
|
|
6080
|
+
function orderVectorQuad(points) {
|
|
6081
|
+
if (points.length !== 4 || !points.every(finite)) return null;
|
|
6082
|
+
const cx = points.reduce((s, p) => s + p.x, 0) / 4;
|
|
6083
|
+
const cy = points.reduce((s, p) => s + p.y, 0) / 4;
|
|
6084
|
+
const q = points.slice().sort((a, b) => Math.atan2(a.y - cy, a.x - cx) - Math.atan2(b.y - cy, b.x - cx));
|
|
6085
|
+
let first = 0;
|
|
6086
|
+
for (let i = 1; i < 4; i++) if (q[i].x + q[i].y < q[first].x + q[first].y) first = i;
|
|
6087
|
+
const ordered = [...q.slice(first), ...q.slice(0, first)];
|
|
6088
|
+
const cross2 = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
|
|
6089
|
+
const turns = ordered.map((_, i) => cross2(ordered[i], ordered[(i + 1) % 4], ordered[(i + 2) % 4]));
|
|
6090
|
+
const area = turns.reduce((s, t) => s + t, 0) / 2;
|
|
6091
|
+
const xs = ordered.map((p) => p.x);
|
|
6092
|
+
const ys = ordered.map((p) => p.y);
|
|
6093
|
+
const size = Math.max(Math.max(...xs) - Math.min(...xs), Math.max(...ys) - Math.min(...ys));
|
|
6094
|
+
const convex = turns.every((t) => t > 1e-9 * size * size);
|
|
6095
|
+
return convex && area > 1e-6 * size * size ? ordered : null;
|
|
6096
|
+
}
|
|
6097
|
+
|
|
6098
|
+
// src/vector/distort.ts
|
|
6099
|
+
var VECTOR_DISTORT_TOLERANCE = 0.05;
|
|
6100
|
+
var CORNER_INDEX = { nw: 0, ne: 1, se: 2, sw: 3 };
|
|
6101
|
+
var SIDE_CORNERS = { n: [0, 1], e: [1, 2], s: [2, 3], w: [3, 0] };
|
|
6102
|
+
var vectorBoxCorners = (b) => [
|
|
6103
|
+
{ x: b.x, y: b.y },
|
|
6104
|
+
{ x: b.x + b.width, y: b.y },
|
|
6105
|
+
{ x: b.x + b.width, y: b.y + b.height },
|
|
6106
|
+
{ x: b.x, y: b.y + b.height }
|
|
6107
|
+
];
|
|
6108
|
+
function vectorDistortQuad(b, handle, d, mode = "distort") {
|
|
6109
|
+
const q = vectorBoxCorners(b);
|
|
6110
|
+
const i = CORNER_INDEX[handle];
|
|
6111
|
+
if (i !== void 0) {
|
|
6112
|
+
if (mode === "perspective") {
|
|
6113
|
+
if (Math.abs(d.x) >= Math.abs(d.y)) {
|
|
6114
|
+
const partner = [1, 0, 3, 2][i];
|
|
6115
|
+
q[i].x += d.x;
|
|
6116
|
+
q[partner].x -= d.x;
|
|
6117
|
+
} else {
|
|
6118
|
+
const partner = [3, 2, 1, 0][i];
|
|
6119
|
+
q[i].y += d.y;
|
|
6120
|
+
q[partner].y -= d.y;
|
|
6121
|
+
}
|
|
6122
|
+
} else {
|
|
6123
|
+
q[i].x += d.x;
|
|
6124
|
+
q[i].y += d.y;
|
|
6125
|
+
}
|
|
6126
|
+
return q;
|
|
6127
|
+
}
|
|
6128
|
+
const side = SIDE_CORNERS[handle];
|
|
6129
|
+
if (side) for (const k of side) q[k] = { x: q[k].x + d.x, y: q[k].y + d.y };
|
|
6130
|
+
return q;
|
|
6131
|
+
}
|
|
6132
|
+
var about = (o, m) => multiplyMatrices(multiplyMatrices([1, 0, 0, 1, -o.x, -o.y], m), [1, 0, 0, 1, o.x, o.y]);
|
|
6133
|
+
function vectorShearForSide(b, handle, d, fromCenter = false) {
|
|
6134
|
+
const center = { x: b.x + b.width / 2, y: b.y + b.height / 2 };
|
|
6135
|
+
if (handle === "n" || handle === "s") {
|
|
6136
|
+
const o = fromCenter ? center : { x: center.x, y: handle === "n" ? b.y + b.height : b.y };
|
|
6137
|
+
const lever = (handle === "n" ? b.y : b.y + b.height) - o.y;
|
|
6138
|
+
return about(o, [1, 0, Math.abs(lever) > 1e-9 ? d.x / lever : 0, 1, 0, 0]);
|
|
6139
|
+
}
|
|
6140
|
+
if (handle === "e" || handle === "w") {
|
|
6141
|
+
const o = fromCenter ? center : { x: handle === "w" ? b.x + b.width : b.x, y: center.y };
|
|
6142
|
+
const lever = (handle === "w" ? b.x : b.x + b.width) - o.x;
|
|
6143
|
+
return about(o, [1, Math.abs(lever) > 1e-9 ? d.y / lever : 0, 0, 1, 0, 0]);
|
|
6144
|
+
}
|
|
6145
|
+
return [1, 0, 0, 1, 0, 0];
|
|
6146
|
+
}
|
|
6147
|
+
function vectorSkewMatrix(ax, ay, origin = { x: 0, y: 0 }) {
|
|
6148
|
+
const tx = Math.tan(ax * Math.PI / 180);
|
|
6149
|
+
const ty = Math.tan(ay * Math.PI / 180);
|
|
6150
|
+
return about(origin, [1, ty, tx, 1, 0, 0]);
|
|
6151
|
+
}
|
|
6152
|
+
function mapEffects(node, f) {
|
|
6153
|
+
if (!_optionalChain([node, 'access', _117 => _117.effects, 'optionalAccess', _118 => _118.length])) return void 0;
|
|
6154
|
+
return node.effects.map((e) => {
|
|
6155
|
+
if (e.type !== "envelope") return e;
|
|
6156
|
+
if (e.params.style === "mesh") return e.params.mesh ? { ...e, params: { ...e.params, mesh: mapVectorMeshPoints(e.params.mesh, f) } } : e;
|
|
6157
|
+
const bounds = vectorEffectInputBounds(node, e.id);
|
|
6158
|
+
if (!bounds || !vectorEnvelopeMap(e.params, bounds)) return e;
|
|
6159
|
+
return { ...e, params: { ...e.params, style: "mesh", mesh: mapVectorMeshPoints(vectorEnvelopeMesh(e.params, bounds), f) } };
|
|
6160
|
+
});
|
|
6161
|
+
}
|
|
6162
|
+
function distortVectorNode(node, parentToDoc, f, tolerance = VECTOR_DISTORT_TOLERANCE) {
|
|
6163
|
+
const toDoc = multiplyMatrices(nodeMatrix(node), parentToDoc);
|
|
6164
|
+
const inv = invertMatrix(toDoc);
|
|
6165
|
+
const local = (p) => applyMatrix(inv, f(applyMatrix(toDoc, p)));
|
|
6166
|
+
const effects = mapEffects(node, local);
|
|
6167
|
+
if (node.type === "group") {
|
|
6168
|
+
const group = node;
|
|
6169
|
+
const children = group.children.map((c) => distortVectorNode(c, toDoc, f, tolerance));
|
|
6170
|
+
const spine = _optionalChain([group, 'access', _119 => _119.blend, 'optionalAccess', _120 => _120.spine]);
|
|
6171
|
+
return {
|
|
6172
|
+
...group,
|
|
6173
|
+
children,
|
|
6174
|
+
...effects ? { effects } : {},
|
|
6175
|
+
...spine ? { blend: { ...group.blend, spine: mapVectorSubpaths([spine], local, tolerance)[0] } } : {}
|
|
6176
|
+
};
|
|
6177
|
+
}
|
|
6178
|
+
const path = node;
|
|
6179
|
+
return {
|
|
6180
|
+
...path,
|
|
6181
|
+
...effects ? { effects } : {},
|
|
6182
|
+
...path.fill !== void 0 ? { fill: mapVectorPaint(path.fill, local) } : {},
|
|
6183
|
+
...path.stroke !== void 0 ? { stroke: mapVectorPaint(path.stroke, local) } : {},
|
|
6184
|
+
subpaths: mapVectorSubpaths(path.subpaths, local, tolerance)
|
|
6185
|
+
};
|
|
6186
|
+
}
|
|
6187
|
+
|
|
5068
6188
|
// src/vector/snap.ts
|
|
5069
6189
|
var VECTOR_CONSTRUCTION_ANGLES = [0, 45, 90, 135];
|
|
5070
6190
|
function constrainToLeave(leave, p) {
|
|
5071
|
-
if (!_optionalChain([leave, 'optionalAccess',
|
|
6191
|
+
if (!_optionalChain([leave, 'optionalAccess', _121 => _121.constrain])) return p;
|
|
5072
6192
|
const dx = p.x - leave.at.x;
|
|
5073
6193
|
const dy = p.y - leave.at.y;
|
|
5074
6194
|
switch (leave.constrain) {
|
|
@@ -5106,8 +6226,8 @@ function within(sorted, key, v2, tol) {
|
|
|
5106
6226
|
}
|
|
5107
6227
|
var linesNear = (lines, v2, tol) => within(lines, (l) => l.v, v2, tol);
|
|
5108
6228
|
var distance = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
|
|
5109
|
-
var
|
|
5110
|
-
var
|
|
6229
|
+
var toPoint2 = (p) => [p.x, p.y];
|
|
6230
|
+
var toVec3 = (p) => ({ x: p[0], y: p[1] });
|
|
5111
6231
|
var LABELS = {
|
|
5112
6232
|
anchor: "anchor",
|
|
5113
6233
|
centre: "centre",
|
|
@@ -5179,7 +6299,7 @@ var VectorSnapTargets = (_class3 = class _VectorSnapTargets {
|
|
|
5179
6299
|
moving.set(r.nodeId, set);
|
|
5180
6300
|
}
|
|
5181
6301
|
const t = _VectorSnapTargets.collect(doc, new Set(moving.keys()), "segments", false);
|
|
5182
|
-
t.pushPaths(doc, new Set(moving.keys()), (id, s, i) => !!_optionalChain([moving, 'access',
|
|
6302
|
+
t.pushPaths(doc, new Set(moving.keys()), (id, s, i) => !!_optionalChain([moving, 'access', _122 => _122.get, 'call', _123 => _123(id), 'optionalAccess', _124 => _124.has, 'call', _125 => _125(`${s}:${i}`)]), true);
|
|
5183
6303
|
return t.index();
|
|
5184
6304
|
}
|
|
5185
6305
|
/**
|
|
@@ -5225,7 +6345,7 @@ var VectorSnapTargets = (_class3 = class _VectorSnapTargets {
|
|
|
5225
6345
|
const count = subpathSegmentCount(sp);
|
|
5226
6346
|
for (let i = 0; i < count && budget > 0; i++) {
|
|
5227
6347
|
if (moving(i) || moving((i + 1) % n)) continue;
|
|
5228
|
-
const seg = subpathSegment(sp, i).map((q) =>
|
|
6348
|
+
const seg = subpathSegment(sp, i).map((q) => toPoint2(applyMatrix(m, toVec3(q))));
|
|
5229
6349
|
let minX = Infinity;
|
|
5230
6350
|
let minY = Infinity;
|
|
5231
6351
|
let maxX = -Infinity;
|
|
@@ -5298,7 +6418,7 @@ var VectorSnapTargets = (_class3 = class _VectorSnapTargets {
|
|
|
5298
6418
|
}
|
|
5299
6419
|
const b = vectorNodeBounds(n, parent);
|
|
5300
6420
|
const f = nodeFrame(n, parent, b);
|
|
5301
|
-
if (b) self.pushRect(b, "edge", _nullishCoalesce(_optionalChain([f, 'optionalAccess',
|
|
6421
|
+
if (b) self.pushRect(b, "edge", _nullishCoalesce(_optionalChain([f, 'optionalAccess', _126 => _126.centre]), () => ( null)));
|
|
5302
6422
|
}
|
|
5303
6423
|
};
|
|
5304
6424
|
visit(doc.nodes, IDENTITY_MATRIX);
|
|
@@ -5343,7 +6463,7 @@ var VectorSnapTargets = (_class3 = class _VectorSnapTargets {
|
|
|
5343
6463
|
lines: lines2,
|
|
5344
6464
|
labels: [this.label(q, kind)]
|
|
5345
6465
|
});
|
|
5346
|
-
if (_optionalChain([leave, 'optionalAccess',
|
|
6466
|
+
if (_optionalChain([leave, 'optionalAccess', _127 => _127.constrain])) {
|
|
5347
6467
|
const q = constrainToLeave(leave, p);
|
|
5348
6468
|
const hit = this.slide(leave.at, { x: q.x - leave.at.x, y: q.y - leave.at.y }, q, tol, true);
|
|
5349
6469
|
return hit ? { point: hit.point, x: true, y: true, ...this.linedUp(hit.point, hit.from) } : none(q);
|
|
@@ -5359,7 +6479,7 @@ var VectorSnapTargets = (_class3 = class _VectorSnapTargets {
|
|
|
5359
6479
|
}
|
|
5360
6480
|
const on = this.onSegment(near2);
|
|
5361
6481
|
if (on) return at2(on, "path");
|
|
5362
|
-
if (_optionalChain([leave, 'optionalAccess',
|
|
6482
|
+
if (_optionalChain([leave, 'optionalAccess', _128 => _128.angles, 'optionalAccess', _129 => _129.length])) {
|
|
5363
6483
|
const c = construction(leave, p, tol);
|
|
5364
6484
|
if (c) {
|
|
5365
6485
|
const hit = this.slide(leave.at, c.dir, c.point, tol, false);
|
|
@@ -5432,7 +6552,7 @@ var VectorSnapTargets = (_class3 = class _VectorSnapTargets {
|
|
|
5432
6552
|
/** Target segments whose control box reaches `p` and which pass within `tol` of it, nearest first. */
|
|
5433
6553
|
segmentsNear(p, tol) {
|
|
5434
6554
|
const out = [];
|
|
5435
|
-
const pt2 =
|
|
6555
|
+
const pt2 = toPoint2(p);
|
|
5436
6556
|
for (const s of this.segments) {
|
|
5437
6557
|
if (p.x < s.minX - tol || p.x > s.maxX + tol || p.y < s.minY - tol || p.y > s.maxY + tol) continue;
|
|
5438
6558
|
const hit = _chunkVNYRI265cjs.segmentNearest.call(void 0, s.seg, pt2);
|
|
@@ -5441,7 +6561,7 @@ var VectorSnapTargets = (_class3 = class _VectorSnapTargets {
|
|
|
5441
6561
|
return out.sort((a, b) => a.distance - b.distance);
|
|
5442
6562
|
}
|
|
5443
6563
|
onSegment(near2) {
|
|
5444
|
-
return near2.length ?
|
|
6564
|
+
return near2.length ? toVec3(_chunkVNYRI265cjs.segmentPoint.call(void 0, near2[0].seg, near2[0].t)) : null;
|
|
5445
6565
|
}
|
|
5446
6566
|
/** Where two of the target segments near `p` cross, the crossing nearest `p` within `tol`. */
|
|
5447
6567
|
crossing(near2, p, tol) {
|
|
@@ -5451,7 +6571,7 @@ var VectorSnapTargets = (_class3 = class _VectorSnapTargets {
|
|
|
5451
6571
|
for (let i = 0; i < list.length; i++) {
|
|
5452
6572
|
for (let j = i + 1; j < list.length; j++) {
|
|
5453
6573
|
for (const hit of _chunkVNYRI265cjs.segmentIntersections.call(void 0, list[i].seg, list[j].seg)) {
|
|
5454
|
-
const q =
|
|
6574
|
+
const q = toVec3(hit.point);
|
|
5455
6575
|
const d = distance(q, p);
|
|
5456
6576
|
if (d <= tol && d < bestD) {
|
|
5457
6577
|
best = q;
|
|
@@ -5489,7 +6609,7 @@ var VectorSnapTargets = (_class3 = class _VectorSnapTargets {
|
|
|
5489
6609
|
* with nothing spaces the box evenly in its row or column. Returns the correction and guides.
|
|
5490
6610
|
*/
|
|
5491
6611
|
snapRect(r, tol, options = {}) {
|
|
5492
|
-
const axes = { x: _optionalChain([options, 'access',
|
|
6612
|
+
const axes = { x: _optionalChain([options, 'access', _130 => _130.axes, 'optionalAccess', _131 => _131.x]) !== false, y: _optionalChain([options, 'access', _132 => _132.axes, 'optionalAccess', _133 => _133.y]) !== false };
|
|
5493
6613
|
const nearest = (lines, values) => {
|
|
5494
6614
|
let best = null;
|
|
5495
6615
|
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 };
|
|
@@ -5497,7 +6617,7 @@ var VectorSnapTargets = (_class3 = class _VectorSnapTargets {
|
|
|
5497
6617
|
};
|
|
5498
6618
|
const bx = axes.x ? nearest(this.xs, [r.x, r.x + r.width / 2, r.x + r.width]) : null;
|
|
5499
6619
|
const by = axes.y ? nearest(this.ys, [r.y, r.y + r.height / 2, r.y + r.height]) : null;
|
|
5500
|
-
const out = { dx: _nullishCoalesce(_optionalChain([bx, 'optionalAccess',
|
|
6620
|
+
const out = { dx: _nullishCoalesce(_optionalChain([bx, 'optionalAccess', _134 => _134.d]), () => ( 0)), dy: _nullishCoalesce(_optionalChain([by, 'optionalAccess', _135 => _135.d]), () => ( 0)), x: !!bx, y: !!by, lines: [], labels: [] };
|
|
5501
6621
|
const done = { ...r, x: r.x + out.dx, y: r.y + out.dy };
|
|
5502
6622
|
if (bx) {
|
|
5503
6623
|
const x = bx.from.x;
|
|
@@ -5620,9 +6740,9 @@ var VectorSnapTargets = (_class3 = class _VectorSnapTargets {
|
|
|
5620
6740
|
const on = this.nearestPoint(p, tol);
|
|
5621
6741
|
const tries = [];
|
|
5622
6742
|
if (on) tries.push({ tx: on.p.x, ty: on.p.y, s: { hx: null, hy: null, on } });
|
|
5623
|
-
tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess',
|
|
5624
|
-
tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess',
|
|
5625
|
-
tries.push({ tx: null, ty: _nullishCoalesce(_optionalChain([hy, 'optionalAccess',
|
|
6743
|
+
tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess', _136 => _136.v]), () => ( null)), ty: _nullishCoalesce(_optionalChain([hy, 'optionalAccess', _137 => _137.v]), () => ( null)), s: { hx, hy, on: null } });
|
|
6744
|
+
tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess', _138 => _138.v]), () => ( null)), ty: null, s: { hx, hy: null, on: null } });
|
|
6745
|
+
tries.push({ tx: null, ty: _nullishCoalesce(_optionalChain([hy, 'optionalAccess', _139 => _139.v]), () => ( null)), s: { hx: null, hy, on: null } });
|
|
5626
6746
|
for (const { tx, ty, s } of tries) {
|
|
5627
6747
|
if (tx === null && ty === null) continue;
|
|
5628
6748
|
const q = applyMatrix(toLocal, { x: _nullishCoalesce(tx, () => ( p.x)), y: _nullishCoalesce(ty, () => ( p.y)) });
|
|
@@ -6030,7 +7150,7 @@ function splitSubpathAt(sp, segment, t, endTolerance = 1e-6) {
|
|
|
6030
7150
|
return cutSubpathAt(subpath, [index]);
|
|
6031
7151
|
}
|
|
6032
7152
|
var endOf2 = (sp, last) => sp.anchors[last ? sp.anchors.length - 1 : 0];
|
|
6033
|
-
var
|
|
7153
|
+
var dist3 = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
|
|
6034
7154
|
function reverse(sp) {
|
|
6035
7155
|
return {
|
|
6036
7156
|
closed: sp.closed,
|
|
@@ -6057,7 +7177,7 @@ function joinSubpaths(subpaths, tolerance) {
|
|
|
6057
7177
|
const sp = open[0];
|
|
6058
7178
|
const first = sp.anchors[0];
|
|
6059
7179
|
const last = sp.anchors[sp.anchors.length - 1];
|
|
6060
|
-
if (sp.anchors.length > 2 &&
|
|
7180
|
+
if (sp.anchors.length > 2 && dist3(first, last) <= tolerance) {
|
|
6061
7181
|
sp.anchors.pop();
|
|
6062
7182
|
sp.anchors[0] = tidy({ ...first, in: _nullishCoalesce(last.in, () => ( null)) }, false);
|
|
6063
7183
|
} else {
|
|
@@ -6073,7 +7193,7 @@ function joinSubpaths(subpaths, tolerance) {
|
|
|
6073
7193
|
for (let j = i + 1; j < open.length; j++) {
|
|
6074
7194
|
for (const ei of [false, true]) {
|
|
6075
7195
|
for (const ej of [false, true]) {
|
|
6076
|
-
const d =
|
|
7196
|
+
const d = dist3(endOf2(open[i], ei), endOf2(open[j], ej));
|
|
6077
7197
|
if (d < best.d) best = { d, i, j, ei, ej };
|
|
6078
7198
|
}
|
|
6079
7199
|
}
|
|
@@ -6113,8 +7233,8 @@ function smoothSubpath(sp, amount = 1, only) {
|
|
|
6113
7233
|
const p = orig[i];
|
|
6114
7234
|
const dir = unit4(next.x - prev.x, next.y - prev.y);
|
|
6115
7235
|
if (!dir) continue;
|
|
6116
|
-
const li =
|
|
6117
|
-
const lo =
|
|
7236
|
+
const li = dist3(p, prev) / 3;
|
|
7237
|
+
const lo = dist3(p, next) / 3;
|
|
6118
7238
|
const hin = _nullishCoalesce(p.in, () => ( p));
|
|
6119
7239
|
const hout = _nullishCoalesce(p.out, () => ( p));
|
|
6120
7240
|
const target = (h, x, y) => ({ x: h.x + (x - h.x) * t, y: h.y + (y - h.y) * t });
|
|
@@ -6605,7 +7725,7 @@ function vectorInkShapeName(shape) {
|
|
|
6605
7725
|
return shape.points.length === 3 ? "triangle" : "polygon";
|
|
6606
7726
|
}
|
|
6607
7727
|
}
|
|
6608
|
-
var
|
|
7728
|
+
var dist4 = (a, b) => Math.hypot(b[0] - a[0], b[1] - a[1]);
|
|
6609
7729
|
function bbox(pts) {
|
|
6610
7730
|
if (!pts.length) return [0, 0, 0, 0];
|
|
6611
7731
|
let [x0, y0] = pts[0];
|
|
@@ -6623,7 +7743,7 @@ function segDistance(a, b, p) {
|
|
|
6623
7743
|
const dy = b[1] - a[1];
|
|
6624
7744
|
const len2 = dx * dx + dy * dy;
|
|
6625
7745
|
const t = len2 > 0 ? Math.min(1, Math.max(0, ((p[0] - a[0]) * dx + (p[1] - a[1]) * dy) / len2)) : 0;
|
|
6626
|
-
return
|
|
7746
|
+
return dist4([a[0] + t * dx, a[1] + t * dy], p);
|
|
6627
7747
|
}
|
|
6628
7748
|
function polygonDistance(c, p) {
|
|
6629
7749
|
let best = Infinity;
|
|
@@ -6685,7 +7805,7 @@ function corners(p, diag) {
|
|
|
6685
7805
|
let far = 0;
|
|
6686
7806
|
let farD = 0;
|
|
6687
7807
|
p.forEach((q, i) => {
|
|
6688
|
-
const d =
|
|
7808
|
+
const d = dist4(start, q);
|
|
6689
7809
|
if (d > farD) {
|
|
6690
7810
|
farD = d;
|
|
6691
7811
|
far = i;
|
|
@@ -6712,7 +7832,7 @@ function corners(p, diag) {
|
|
|
6712
7832
|
}
|
|
6713
7833
|
let short = -1;
|
|
6714
7834
|
for (let j = 0; j < n; j++) {
|
|
6715
|
-
if (
|
|
7835
|
+
if (dist4(ring[j], ring[(j + 1) % n]) < 0.1 * diag) {
|
|
6716
7836
|
short = j;
|
|
6717
7837
|
break;
|
|
6718
7838
|
}
|
|
@@ -6752,8 +7872,8 @@ function recognizeInkShape(points, options = {}) {
|
|
|
6752
7872
|
const diag = Math.hypot(w, h);
|
|
6753
7873
|
if (size < minSize) return null;
|
|
6754
7874
|
let length2 = 0;
|
|
6755
|
-
for (let i = 1; i < p.length; i++) length2 +=
|
|
6756
|
-
const gap =
|
|
7875
|
+
for (let i = 1; i < p.length; i++) length2 += dist4(p[i - 1], p[i]);
|
|
7876
|
+
const gap = dist4(first, last);
|
|
6757
7877
|
if (gap > 0.85 * length2 && gap >= minSize) {
|
|
6758
7878
|
const off = Math.max(...p.map((q) => segDistance(first, last, q)));
|
|
6759
7879
|
if (off <= Math.max(0.06 * gap, 1.5 * minSize / 6)) return { kind: "line", a: first, b: last };
|
|
@@ -7052,7 +8172,7 @@ function getEditablePathIds(state) {
|
|
|
7052
8172
|
}
|
|
7053
8173
|
}
|
|
7054
8174
|
}
|
|
7055
|
-
return [...ids].filter((id) => _optionalChain([findVectorNode, 'call',
|
|
8175
|
+
return [...ids].filter((id) => _optionalChain([findVectorNode, 'call', _140 => _140(state.document.nodes, id), 'optionalAccess', _141 => _141.type]) === "path");
|
|
7056
8176
|
}
|
|
7057
8177
|
function getVisibleAnchors(state) {
|
|
7058
8178
|
const out = [];
|
|
@@ -7067,7 +8187,7 @@ function getVisibleHandles(state) {
|
|
|
7067
8187
|
const seen = /* @__PURE__ */ new Set();
|
|
7068
8188
|
const push = (node, s, i, handle) => {
|
|
7069
8189
|
const sp = node.subpaths[s];
|
|
7070
|
-
const a = _optionalChain([sp, 'optionalAccess',
|
|
8190
|
+
const a = _optionalChain([sp, 'optionalAccess', _142 => _142.anchors, 'access', _143 => _143[i]]);
|
|
7071
8191
|
if (!a || !a[handle]) return;
|
|
7072
8192
|
const key = `${node.id}:${s}:${i}:${handle}`;
|
|
7073
8193
|
if (seen.has(key)) return;
|
|
@@ -7076,8 +8196,8 @@ function getVisibleHandles(state) {
|
|
|
7076
8196
|
};
|
|
7077
8197
|
if (state.tool === "pen" && state.pen) {
|
|
7078
8198
|
const node = findVectorNode(state.document.nodes, state.pen.nodeId);
|
|
7079
|
-
const sp = _optionalChain([node, 'optionalAccess',
|
|
7080
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
8199
|
+
const sp = _optionalChain([node, 'optionalAccess', _144 => _144.type]) === "path" ? node.subpaths[state.pen.subpath] : void 0;
|
|
8200
|
+
if (_optionalChain([node, 'optionalAccess', _145 => _145.type]) === "path" && sp) {
|
|
7081
8201
|
const last = sp.anchors.length - 1;
|
|
7082
8202
|
push(node, state.pen.subpath, last, "in");
|
|
7083
8203
|
push(node, state.pen.subpath, last, "out");
|
|
@@ -7115,11 +8235,11 @@ function getVectorCornerWidgets(state) {
|
|
|
7115
8235
|
const side = Math.min(c.lu, c.lv);
|
|
7116
8236
|
if (side * zoom < 3 * VECTOR_CORNER_WIDGET_INSET) continue;
|
|
7117
8237
|
const a = node.subpaths[c.subpath].anchors[c.index];
|
|
7118
|
-
const radius = _nullishCoalesce(_optionalChain([a, 'access',
|
|
8238
|
+
const radius = _nullishCoalesce(_optionalChain([a, 'access', _146 => _146.corner, 'optionalAccess', _147 => _147.radius]), () => ( 0));
|
|
7119
8239
|
const drawn = fitCornerRadius(c, radius);
|
|
7120
8240
|
const k = Math.min(Math.max(drawn / c.sin, VECTOR_CORNER_WIDGET_INSET / (zoom * Math.sqrt(1 + c.cos))), side / 2);
|
|
7121
8241
|
const p = applyMatrix(m, cornerBisectorPoint(c, k));
|
|
7122
|
-
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',
|
|
8242
|
+
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', _148 => _148.corner, 'optionalAccess', _149 => _149.kind]), () => ( "round")), corner: c });
|
|
7123
8243
|
}
|
|
7124
8244
|
}
|
|
7125
8245
|
return out;
|
|
@@ -7142,13 +8262,13 @@ function getVectorWidthHandles(state) {
|
|
|
7142
8262
|
const n = findVectorNode(state.document.nodes, id);
|
|
7143
8263
|
if (n) for (const p of collectPathNodes(n)) ids.add(p.id);
|
|
7144
8264
|
}
|
|
7145
|
-
if (_optionalChain([state, 'access',
|
|
7146
|
-
if (_optionalChain([state, 'access',
|
|
8265
|
+
if (_optionalChain([state, 'access', _150 => _150.hover, 'optionalAccess', _151 => _151.nodeId])) ids.add(state.hover.nodeId);
|
|
8266
|
+
if (_optionalChain([state, 'access', _152 => _152.interaction, 'optionalAccess', _153 => _153.type]) === "width") ids.add(state.interaction.ref.nodeId);
|
|
7147
8267
|
for (const r of state.selectedWidthPoints) ids.add(r.nodeId);
|
|
7148
8268
|
const out = [];
|
|
7149
8269
|
for (const id of ids) {
|
|
7150
8270
|
const node = findVectorNode(state.document.nodes, id);
|
|
7151
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
8271
|
+
if (_optionalChain([node, 'optionalAccess', _154 => _154.type]) !== "path" || node.visible === false || !_optionalChain([node, 'access', _155 => _155.strokeWidthProfile, 'optionalAccess', _156 => _156.length])) continue;
|
|
7152
8272
|
const g = vectorStrokeWidthGeometry(node);
|
|
7153
8273
|
if (!g) continue;
|
|
7154
8274
|
const profile = sanitizeWidthProfile(node.strokeWidthProfile);
|
|
@@ -7181,7 +8301,7 @@ function getVectorWidthHandles(state) {
|
|
|
7181
8301
|
}
|
|
7182
8302
|
function getAnchor(doc, ref) {
|
|
7183
8303
|
const node = findVectorNode(doc.nodes, ref.nodeId);
|
|
7184
|
-
return _optionalChain([node, 'optionalAccess',
|
|
8304
|
+
return _optionalChain([node, 'optionalAccess', _157 => _157.type]) === "path" ? _optionalChain([node, 'access', _158 => _158.subpaths, 'access', _159 => _159[ref.subpath], 'optionalAccess', _160 => _160.anchors, 'access', _161 => _161[ref.index]]) : void 0;
|
|
7185
8305
|
}
|
|
7186
8306
|
function getAnchorWorld(doc, ref) {
|
|
7187
8307
|
const a = getAnchor(doc, ref);
|
|
@@ -7194,8 +8314,8 @@ function getVectorSelectionFrame(doc, ids) {
|
|
|
7194
8314
|
const nodes = ids.map((id) => ({ node: findVectorNode(doc.nodes, id), parent: _nullishCoalesce(vectorParentMatrix(doc.nodes, id), () => ( IDENTITY_MATRIX)) })).filter((n) => n.node);
|
|
7195
8315
|
if (!nodes.length) return null;
|
|
7196
8316
|
const angles = nodes.map((n) => matrixRotation(multiplyMatrices(nodeMatrix(n.node), n.parent)));
|
|
7197
|
-
const
|
|
7198
|
-
const angle =
|
|
8317
|
+
const same2 = angles.every((a) => Math.abs(normalizeAngle(a - angles[0])) < 1e-6);
|
|
8318
|
+
const angle = same2 ? angles[0] : 0;
|
|
7199
8319
|
const unrotate = rotateMatrix(-angle);
|
|
7200
8320
|
const b = unionBounds(nodes.map((n) => vectorNodeBounds(n.node, multiplyMatrices(n.parent, unrotate))));
|
|
7201
8321
|
return b ? { ...b, angle } : null;
|
|
@@ -7230,6 +8350,13 @@ function getVectorSelectionBoxGeometry(frame2, viewport) {
|
|
|
7230
8350
|
const r = (n) => Math.round(n * 1e3) / 1e3;
|
|
7231
8351
|
return { box, angle: frame2.angle, transform: frame2.angle ? `rotate(${r(frame2.angle)} ${r(viewport.x)} ${r(viewport.y)})` : "", handles, corners: corners2 };
|
|
7232
8352
|
}
|
|
8353
|
+
function getVectorEnvelopeTarget(doc, selection) {
|
|
8354
|
+
if (selection.length !== 1) return null;
|
|
8355
|
+
const node = findVectorNode(doc.nodes, selection[0]);
|
|
8356
|
+
if (!node || !vectorNodeEnvelope(node)) return null;
|
|
8357
|
+
const frame2 = vectorEnvelopeFrame(node);
|
|
8358
|
+
return frame2 ? { node, frame: frame2, world: _nullishCoalesce(vectorWorldMatrix(doc.nodes, node.id), () => ( IDENTITY_MATRIX)) } : null;
|
|
8359
|
+
}
|
|
7233
8360
|
var RESIZE_CURSOR_ORDER = ["ew-resize", "nwse-resize", "ns-resize", "nesw-resize"];
|
|
7234
8361
|
var HANDLE_ANGLES = { e: 0, se: 45, s: 90, sw: 135, w: 180, nw: 225, n: 270, ne: 315 };
|
|
7235
8362
|
function vectorResizeCursor(handle, angle = 0) {
|
|
@@ -7254,7 +8381,8 @@ var TOOL_LABELS = {
|
|
|
7254
8381
|
shapeBuilder: "Shape Builder",
|
|
7255
8382
|
paintBucket: "Paint Bucket",
|
|
7256
8383
|
blend: "Blend",
|
|
7257
|
-
gradient: "Gradient"
|
|
8384
|
+
gradient: "Gradient",
|
|
8385
|
+
envelope: "Envelope Mesh"
|
|
7258
8386
|
};
|
|
7259
8387
|
var TOOL_KEYS = {
|
|
7260
8388
|
v: "select",
|
|
@@ -7273,7 +8401,8 @@ var TOOL_KEYS = {
|
|
|
7273
8401
|
m: "shapeBuilder",
|
|
7274
8402
|
b: "paintBucket",
|
|
7275
8403
|
j: "blend",
|
|
7276
|
-
g: "gradient"
|
|
8404
|
+
g: "gradient",
|
|
8405
|
+
u: "envelope"
|
|
7277
8406
|
};
|
|
7278
8407
|
function vectorToolLabel(tool) {
|
|
7279
8408
|
return TOOL_LABELS[tool];
|
|
@@ -7295,7 +8424,8 @@ var VECTOR_TOOL_SHORTCUTS = {
|
|
|
7295
8424
|
shapeBuilder: "M",
|
|
7296
8425
|
paintBucket: "B",
|
|
7297
8426
|
blend: "J",
|
|
7298
|
-
gradient: "G"
|
|
8427
|
+
gradient: "G",
|
|
8428
|
+
envelope: "U"
|
|
7299
8429
|
};
|
|
7300
8430
|
var VECTOR_TOOL_GLYPHS = {
|
|
7301
8431
|
select: "\u2196",
|
|
@@ -7314,7 +8444,8 @@ var VECTOR_TOOL_GLYPHS = {
|
|
|
7314
8444
|
shapeBuilder: "\u2295",
|
|
7315
8445
|
paintBucket: "\u25CD",
|
|
7316
8446
|
blend: "\u29D3",
|
|
7317
|
-
gradient: "\u25D0"
|
|
8447
|
+
gradient: "\u25D0",
|
|
8448
|
+
envelope: "\u2317"
|
|
7318
8449
|
};
|
|
7319
8450
|
var SHAPE_TOOLS = /* @__PURE__ */ new Set(["rect", "ellipse", "polygon", "star", "line"]);
|
|
7320
8451
|
var BOOLEAN_OPS = {
|
|
@@ -7367,7 +8498,7 @@ function spliceTree(nodes, id, replacements) {
|
|
|
7367
8498
|
}
|
|
7368
8499
|
return changed ? out : nodes;
|
|
7369
8500
|
}
|
|
7370
|
-
var
|
|
8501
|
+
var toPoint3 = (p) => [p.x, p.y];
|
|
7371
8502
|
var placementOf = (n) => ({
|
|
7372
8503
|
...n.transform ? { transform: n.transform } : {},
|
|
7373
8504
|
...n.visible === false ? { visible: false } : {},
|
|
@@ -7412,18 +8543,19 @@ var VectorEditorController = (_class5 = class {
|
|
|
7412
8543
|
/** Options new blends get (the toolbars edit them along with the selected blend's). */
|
|
7413
8544
|
__init31() {this.blendDefaults = {}}
|
|
7414
8545
|
__init32() {this.gradientEdit = { target: "fill", stop: null }}
|
|
8546
|
+
__init33() {this.freeDistort = false}
|
|
7415
8547
|
/** What the highlight shows, to skip notifying when the pointer stays over the same face. */
|
|
7416
|
-
|
|
8548
|
+
__init34() {this.builderHoverKey = null}
|
|
7417
8549
|
|
|
7418
8550
|
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
8551
|
+
__init35() {this.listeners = /* @__PURE__ */ new Set()}
|
|
8552
|
+
__init36() {this.cleanups = []}
|
|
8553
|
+
__init37() {this.applying = false}
|
|
7422
8554
|
/** Set while a commit records a change that was already applied, so `restore` still reports it. */
|
|
7423
|
-
|
|
7424
|
-
|
|
8555
|
+
__init38() {this.committing = false}
|
|
8556
|
+
__init39() {this.revision = 0}
|
|
7425
8557
|
|
|
7426
|
-
constructor(options = {}) {;_class5.prototype.__init12.call(this);_class5.prototype.__init13.call(this);_class5.prototype.__init14.call(this);_class5.prototype.__init15.call(this);_class5.prototype.__init16.call(this);_class5.prototype.__init17.call(this);_class5.prototype.__init18.call(this);_class5.prototype.__init19.call(this);_class5.prototype.__init20.call(this);_class5.prototype.__init21.call(this);_class5.prototype.__init22.call(this);_class5.prototype.__init23.call(this);_class5.prototype.__init24.call(this);_class5.prototype.__init25.call(this);_class5.prototype.__init26.call(this);_class5.prototype.__init27.call(this);_class5.prototype.__init28.call(this);_class5.prototype.__init29.call(this);_class5.prototype.__init30.call(this);_class5.prototype.__init31.call(this);_class5.prototype.__init32.call(this);_class5.prototype.__init33.call(this);_class5.prototype.__init34.call(this);_class5.prototype.__init35.call(this);_class5.prototype.__init36.call(this);_class5.prototype.__init37.call(this);_class5.prototype.__init38.call(this);_class5.prototype.__init39.call(this);_class5.prototype.__init40.call(this);
|
|
8558
|
+
constructor(options = {}) {;_class5.prototype.__init12.call(this);_class5.prototype.__init13.call(this);_class5.prototype.__init14.call(this);_class5.prototype.__init15.call(this);_class5.prototype.__init16.call(this);_class5.prototype.__init17.call(this);_class5.prototype.__init18.call(this);_class5.prototype.__init19.call(this);_class5.prototype.__init20.call(this);_class5.prototype.__init21.call(this);_class5.prototype.__init22.call(this);_class5.prototype.__init23.call(this);_class5.prototype.__init24.call(this);_class5.prototype.__init25.call(this);_class5.prototype.__init26.call(this);_class5.prototype.__init27.call(this);_class5.prototype.__init28.call(this);_class5.prototype.__init29.call(this);_class5.prototype.__init30.call(this);_class5.prototype.__init31.call(this);_class5.prototype.__init32.call(this);_class5.prototype.__init33.call(this);_class5.prototype.__init34.call(this);_class5.prototype.__init35.call(this);_class5.prototype.__init36.call(this);_class5.prototype.__init37.call(this);_class5.prototype.__init38.call(this);_class5.prototype.__init39.call(this);_class5.prototype.__init40.call(this);_class5.prototype.__init41.call(this);
|
|
7427
8559
|
this.history = _nullishCoalesce(options.history, () => ( new (0, _chunkQKLRAA4Tcjs.HistoryManager)()));
|
|
7428
8560
|
this.doc = options.document ? cloneVectorDocument(options.document) : { width: 800, height: 600, nodes: [] };
|
|
7429
8561
|
this.doc = this.refreshed(this.doc);
|
|
@@ -7435,6 +8567,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
7435
8567
|
this.hitRadius = _nullishCoalesce(options.hitRadius, () => ( 6));
|
|
7436
8568
|
this.createId = _nullishCoalesce(options.createId, () => ( defaultCreateId));
|
|
7437
8569
|
this.onChange = options.onChange;
|
|
8570
|
+
this.freeDistort = !!options.freeDistort;
|
|
7438
8571
|
this.state = this.computeState();
|
|
7439
8572
|
this.connect();
|
|
7440
8573
|
}
|
|
@@ -7464,9 +8597,9 @@ var VectorEditorController = (_class5 = class {
|
|
|
7464
8597
|
// State
|
|
7465
8598
|
// -------------------------------------------------------------------------
|
|
7466
8599
|
/** The current snapshot (stable until the next change). */
|
|
7467
|
-
|
|
8600
|
+
__init40() {this.getState = () => this.state}
|
|
7468
8601
|
/** Calls `listener` after every change. Returns an unsubscribe function. */
|
|
7469
|
-
|
|
8602
|
+
__init41() {this.subscribe = (listener) => {
|
|
7470
8603
|
this.connect();
|
|
7471
8604
|
this.listeners.add(listener);
|
|
7472
8605
|
return () => {
|
|
@@ -7506,6 +8639,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
7506
8639
|
blendStart: this.blendStart,
|
|
7507
8640
|
blendDefaults: this.blendDefaults,
|
|
7508
8641
|
gradientEdit: this.gradientEdit,
|
|
8642
|
+
freeDistort: this.freeDistort,
|
|
7509
8643
|
canUndo: h.canUndo,
|
|
7510
8644
|
canRedo: h.canRedo,
|
|
7511
8645
|
undoLabel: h.undoName,
|
|
@@ -7524,7 +8658,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
7524
8658
|
if (this.blendStart && !this.getNode(this.blendStart.nodeId)) this.blendStart = null;
|
|
7525
8659
|
this.revision++;
|
|
7526
8660
|
this.state = this.computeState();
|
|
7527
|
-
if (docChanged) _optionalChain([this, 'access',
|
|
8661
|
+
if (docChanged) _optionalChain([this, 'access', _162 => _162.onChange, 'optionalCall', _163 => _163(this.doc)]);
|
|
7528
8662
|
const state = this.state;
|
|
7529
8663
|
this.listeners.forEach((listener) => {
|
|
7530
8664
|
try {
|
|
@@ -7554,33 +8688,38 @@ var VectorEditorController = (_class5 = class {
|
|
|
7554
8688
|
return applyMatrix(invertMatrix(this.worldOf(id, doc)), p);
|
|
7555
8689
|
}
|
|
7556
8690
|
cursorFor() {
|
|
7557
|
-
if (_optionalChain([this, 'access',
|
|
7558
|
-
if (_optionalChain([this, 'access',
|
|
7559
|
-
if (_optionalChain([this, 'access',
|
|
8691
|
+
if (_optionalChain([this, 'access', _164 => _164.drag, 'optionalAccess', _165 => _165.kind]) === "pan" || this.spaceHeld) return this.drag ? "grabbing" : "grab";
|
|
8692
|
+
if (_optionalChain([this, 'access', _166 => _166.drag, 'optionalAccess', _167 => _167.kind]) === "rotate") return "grabbing";
|
|
8693
|
+
if (_optionalChain([this, 'access', _168 => _168.drag, 'optionalAccess', _169 => _169.kind]) === "move") return "move";
|
|
7560
8694
|
const h = this.hover;
|
|
7561
8695
|
switch (this.tool) {
|
|
7562
8696
|
case "select":
|
|
7563
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
7564
|
-
|
|
8697
|
+
if (_optionalChain([h, 'optionalAccess', _170 => _170.transformHandle]) && this.freeDistort && h.transformHandle !== "rotate") return "crosshair";
|
|
8698
|
+
if (_optionalChain([h, 'optionalAccess', _171 => _171.transformHandle])) return vectorResizeCursor(h.transformHandle, _nullishCoalesce(_optionalChain([this, 'access', _172 => _172.frameOf, 'call', _173 => _173(this.selectedRoots()), 'optionalAccess', _174 => _174.angle]), () => ( 0)));
|
|
8699
|
+
return _optionalChain([h, 'optionalAccess', _175 => _175.nodeId]) ? "move" : "default";
|
|
8700
|
+
case "envelope":
|
|
8701
|
+
if (_optionalChain([this, 'access', _176 => _176.drag, 'optionalAccess', _177 => _177.kind]) === "envelope") return "grabbing";
|
|
8702
|
+
if (_optionalChain([h, 'optionalAccess', _178 => _178.envelope])) return h.envelope.index === null ? "grab" : "pointer";
|
|
8703
|
+
return _optionalChain([h, 'optionalAccess', _179 => _179.nodeId]) ? "pointer" : "default";
|
|
7565
8704
|
case "direct":
|
|
7566
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
7567
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
7568
|
-
return _optionalChain([h, 'optionalAccess',
|
|
8705
|
+
if (_optionalChain([h, 'optionalAccess', _180 => _180.anchor]) || _optionalChain([h, 'optionalAccess', _181 => _181.handle]) || _optionalChain([h, 'optionalAccess', _182 => _182.corner])) return "pointer";
|
|
8706
|
+
if (_optionalChain([h, 'optionalAccess', _183 => _183.segment])) return "copy";
|
|
8707
|
+
return _optionalChain([h, 'optionalAccess', _184 => _184.nodeId]) ? "move" : "default";
|
|
7569
8708
|
case "pen":
|
|
7570
|
-
return _optionalChain([h, 'optionalAccess',
|
|
8709
|
+
return _optionalChain([h, 'optionalAccess', _185 => _185.anchor]) ? "pointer" : "crosshair";
|
|
7571
8710
|
case "width":
|
|
7572
|
-
if (_optionalChain([this, 'access',
|
|
7573
|
-
if (_optionalChain([h, 'optionalAccess',
|
|
7574
|
-
return _optionalChain([h, 'optionalAccess',
|
|
8711
|
+
if (_optionalChain([this, 'access', _186 => _186.drag, 'optionalAccess', _187 => _187.kind]) === "width") return this.drag.mode === "width" ? "ew-resize" : "grabbing";
|
|
8712
|
+
if (_optionalChain([h, 'optionalAccess', _188 => _188.widthPoint])) return h.widthPoint.part === "center" ? "grab" : "ew-resize";
|
|
8713
|
+
return _optionalChain([h, 'optionalAccess', _189 => _189.strokeSpot]) ? "copy" : "default";
|
|
7575
8714
|
case "shapeBuilder":
|
|
7576
|
-
if (!_optionalChain([this, 'access',
|
|
8715
|
+
if (!_optionalChain([this, 'access', _190 => _190.builderPreview, 'optionalAccess', _191 => _191.faces, 'access', _192 => _192.length]) && !_optionalChain([this, 'access', _193 => _193.builderPreview, 'optionalAccess', _194 => _194.lines, 'access', _195 => _195.length])) return "crosshair";
|
|
7577
8716
|
return this.builderPreview.mode === "erase" ? "not-allowed" : "cell";
|
|
7578
8717
|
case "paintBucket":
|
|
7579
8718
|
return this.builderPreview ? "cell" : "crosshair";
|
|
7580
8719
|
case "blend":
|
|
7581
|
-
return _optionalChain([h, 'optionalAccess',
|
|
8720
|
+
return _optionalChain([h, 'optionalAccess', _196 => _196.nodeId]) ? this.blendStart && this.blendStart.nodeId !== h.nodeId ? "copy" : "pointer" : "crosshair";
|
|
7582
8721
|
case "gradient": {
|
|
7583
|
-
const part = _optionalChain([this, 'access',
|
|
8722
|
+
const part = _optionalChain([this, 'access', _197 => _197.drag, 'optionalAccess', _198 => _198.kind]) === "gradient" ? this.drag.part : _optionalChain([h, 'optionalAccess', _199 => _199.gradient]);
|
|
7584
8723
|
if (!part) return "crosshair";
|
|
7585
8724
|
if (part.kind === "bar") return this.drag ? "grabbing" : "copy";
|
|
7586
8725
|
if (part.kind === "handle" && part.handle === "start") return this.drag ? "grabbing" : "move";
|
|
@@ -7606,11 +8745,11 @@ var VectorEditorController = (_class5 = class {
|
|
|
7606
8745
|
this.selection = s.selection.filter((id) => this.getNode(id));
|
|
7607
8746
|
this.anchors = s.anchors.filter((r) => getAnchor(this.doc, r));
|
|
7608
8747
|
this.editingId = s.editingId && this.getNode(s.editingId) ? s.editingId : null;
|
|
7609
|
-
this.pen = s.pen && _optionalChain([this, 'access',
|
|
8748
|
+
this.pen = s.pen && _optionalChain([this, 'access', _200 => _200.getNode, 'call', _201 => _201(s.pen.nodeId), 'optionalAccess', _202 => _202.subpaths, 'optionalAccess', _203 => _203[s.pen.subpath]]) ? s.pen : null;
|
|
7610
8749
|
if (this.widthPoints.length) {
|
|
7611
8750
|
const kept = this.widthPoints.filter((r) => {
|
|
7612
8751
|
const n = this.getNode(r.nodeId);
|
|
7613
|
-
return _optionalChain([n, 'optionalAccess',
|
|
8752
|
+
return _optionalChain([n, 'optionalAccess', _204 => _204.type]) === "path" && !!_optionalChain([n, 'access', _205 => _205.strokeWidthProfile, 'optionalAccess', _206 => _206[r.index]]);
|
|
7614
8753
|
});
|
|
7615
8754
|
if (kept.length !== this.widthPoints.length) this.widthPoints = kept;
|
|
7616
8755
|
}
|
|
@@ -7792,7 +8931,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
7792
8931
|
if (res.kind) {
|
|
7793
8932
|
this.snappedToObject = true;
|
|
7794
8933
|
this.setGuides(res);
|
|
7795
|
-
return _optionalChain([leave, 'optionalAccess',
|
|
8934
|
+
return _optionalChain([leave, 'optionalAccess', _207 => _207.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) };
|
|
7796
8935
|
}
|
|
7797
8936
|
}
|
|
7798
8937
|
this.setGuides(null);
|
|
@@ -7810,14 +8949,14 @@ var VectorEditorController = (_class5 = class {
|
|
|
7810
8949
|
/** Where the pointer at `p` would place a point with the pen or a shape tool (and the guides showing why). */
|
|
7811
8950
|
hoverSnap(p, input) {
|
|
7812
8951
|
if (this.tool === "pen") {
|
|
7813
|
-
const sp = this.pen ? _optionalChain([this, 'access',
|
|
7814
|
-
if (this.pen && sp && _optionalChain([this, 'access',
|
|
8952
|
+
const sp = this.pen ? _optionalChain([this, 'access', _208 => _208.getNode, 'call', _209 => _209(this.pen.nodeId), 'optionalAccess', _210 => _210.subpaths, 'access', _211 => _211[this.pen.subpath]]) : void 0;
|
|
8953
|
+
if (this.pen && sp && _optionalChain([this, 'access', _212 => _212.hover, 'optionalAccess', _213 => _213.anchor])) {
|
|
7815
8954
|
this.setGuides(null);
|
|
7816
8955
|
return p;
|
|
7817
8956
|
}
|
|
7818
8957
|
const last = this.pen && sp ? getAnchorWorld(this.doc, { nodeId: this.pen.nodeId, subpath: this.pen.subpath, index: sp.anchors.length - 1 }) : void 0;
|
|
7819
8958
|
const leave = last ? { at: { x: last.x, y: last.y }, constrain: input.shift ? "angle" : null } : null;
|
|
7820
|
-
return this.snapDrawn(p, leave, input, () => this.drawingTargets(_nullishCoalesce(_optionalChain([this, 'access',
|
|
8959
|
+
return this.snapDrawn(p, leave, input, () => this.drawingTargets(_nullishCoalesce(_optionalChain([this, 'access', _214 => _214.pen, 'optionalAccess', _215 => _215.nodeId]), () => ( null))));
|
|
7821
8960
|
}
|
|
7822
8961
|
if (SHAPE_TOOLS.has(this.tool)) return this.snapDrawn(p, null, input, () => this.drawingTargets(null));
|
|
7823
8962
|
this.setGuides(null);
|
|
@@ -7965,7 +9104,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
7965
9104
|
if (d.fillRule) out.fillRule = d.fillRule;
|
|
7966
9105
|
if (d.strokeAlign && d.strokeAlign !== "center") out.strokeAlign = d.strokeAlign;
|
|
7967
9106
|
for (const key of ["startArrow", "endArrow", "arrowAlign", "startArrowScale", "endArrowScale"]) if (d[key]) out[key] = d[key];
|
|
7968
|
-
if (_optionalChain([d, 'access',
|
|
9107
|
+
if (_optionalChain([d, 'access', _216 => _216.strokeWidthProfile, 'optionalAccess', _217 => _217.length])) out.strokeWidthProfile = d.strokeWidthProfile.map((p) => ({ ...p }));
|
|
7969
9108
|
return out;
|
|
7970
9109
|
}
|
|
7971
9110
|
/** Merges `patch` into a node (paths take style and geometry; groups name / visibility / opacity). */
|
|
@@ -8059,7 +9198,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
8059
9198
|
next.set(path.id, { ...path, [target]: g });
|
|
8060
9199
|
}
|
|
8061
9200
|
this.change(_nullishCoalesce(options.label, () => ( "Gradient")), () => this.setDoc(mapTree(this.doc.nodes, (n) => _nullishCoalesce(next.get(n.id), () => ( n)))), options.merge);
|
|
8062
|
-
const stops = _nullishCoalesce(_optionalChain([next, 'access',
|
|
9201
|
+
const stops = _nullishCoalesce(_optionalChain([next, 'access', _218 => _218.values, 'call', _219 => _219(), 'access', _220 => _220.next, 'call', _221 => _221(), 'access', _222 => _222.value, 'optionalAccess', _223 => _223[target], 'optionalAccess', _224 => _224.stops, 'access', _225 => _225.length]), () => ( 0));
|
|
8063
9202
|
if (this.gradientEdit.stop !== null && this.gradientEdit.stop >= stops) this.gradientEdit = { ...this.gradientEdit, stop: null };
|
|
8064
9203
|
return { ok: true };
|
|
8065
9204
|
}
|
|
@@ -8228,7 +9367,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
8228
9367
|
upGradient(drag) {
|
|
8229
9368
|
const part = drag.part;
|
|
8230
9369
|
if (!drag.moved) {
|
|
8231
|
-
if (_optionalChain([part, 'optionalAccess',
|
|
9370
|
+
if (_optionalChain([part, 'optionalAccess', _226 => _226.kind]) === "bar") {
|
|
8232
9371
|
this.addGradientStop(part.offset);
|
|
8233
9372
|
return;
|
|
8234
9373
|
}
|
|
@@ -8247,7 +9386,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
8247
9386
|
const byNode = /* @__PURE__ */ new Map();
|
|
8248
9387
|
for (const r of refs) {
|
|
8249
9388
|
const node = this.getNode(r.nodeId);
|
|
8250
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
9389
|
+
if (_optionalChain([node, 'optionalAccess', _227 => _227.type]) !== "path" || !_optionalChain([node, 'access', _228 => _228.strokeWidthProfile, 'optionalAccess', _229 => _229[r.index]])) continue;
|
|
8251
9390
|
byNode.set(r.nodeId, [..._nullishCoalesce(byNode.get(r.nodeId), () => ( [])), r.index]);
|
|
8252
9391
|
}
|
|
8253
9392
|
if (!byNode.size) return { ok: false, message: "There is no such width point." };
|
|
@@ -8265,12 +9404,12 @@ var VectorEditorController = (_class5 = class {
|
|
|
8265
9404
|
}
|
|
8266
9405
|
/** Selects width points (width tool); points on other paths than the first are dropped. */
|
|
8267
9406
|
selectWidthPoints(refs) {
|
|
8268
|
-
const first = _optionalChain([refs, 'access',
|
|
9407
|
+
const first = _optionalChain([refs, 'access', _230 => _230[0], 'optionalAccess', _231 => _231.nodeId]);
|
|
8269
9408
|
const next = [];
|
|
8270
9409
|
for (const r of refs) {
|
|
8271
9410
|
if (r.nodeId !== first || next.some((q) => q.index === r.index)) continue;
|
|
8272
9411
|
const n = this.getNode(r.nodeId);
|
|
8273
|
-
if (_optionalChain([n, 'optionalAccess',
|
|
9412
|
+
if (_optionalChain([n, 'optionalAccess', _232 => _232.type]) === "path" && _optionalChain([n, 'access', _233 => _233.strokeWidthProfile, 'optionalAccess', _234 => _234[r.index]])) next.push({ nodeId: r.nodeId, index: r.index, subpath: _nullishCoalesce(r.subpath, () => ( 0)) });
|
|
8274
9413
|
}
|
|
8275
9414
|
this.widthPoints = next;
|
|
8276
9415
|
this.notify();
|
|
@@ -8285,7 +9424,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
8285
9424
|
*/
|
|
8286
9425
|
setWidthPoint(target, values) {
|
|
8287
9426
|
const node = this.getNode(target.nodeId);
|
|
8288
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
9427
|
+
if (_optionalChain([node, 'optionalAccess', _235 => _235.type]) !== "path") return { ok: false, message: "There is no such path." };
|
|
8289
9428
|
const g = vectorStrokeWidthGeometry(node);
|
|
8290
9429
|
if (!g || !(g.unit > 0)) return { ok: false, message: "The path has no visible stroke." };
|
|
8291
9430
|
const num2 = (v2) => typeof v2 === "number" && Number.isFinite(v2) ? v2 : void 0;
|
|
@@ -8318,11 +9457,11 @@ var VectorEditorController = (_class5 = class {
|
|
|
8318
9457
|
}
|
|
8319
9458
|
}
|
|
8320
9459
|
}
|
|
8321
|
-
const subpath = _optionalChain([this, 'access',
|
|
9460
|
+
const subpath = _optionalChain([this, 'access', _236 => _236.widthEdit, 'optionalAccess', _237 => _237.nodeId]) === node.id ? this.widthEdit.subpath : _nullishCoalesce(_optionalChain([this, 'access', _238 => _238.widthPoints, 'access', _239 => _239.find, 'call', _240 => _240((r) => r.nodeId === node.id), 'optionalAccess', _241 => _241.subpath]), () => ( 0));
|
|
8322
9461
|
const edit = this.widthEdit;
|
|
8323
9462
|
this.change("Width Point", () => this.replaceNode(node.id, withStyle(node, { strokeWidthProfile: points })));
|
|
8324
9463
|
this.widthPoints = [{ nodeId: node.id, index, subpath }];
|
|
8325
|
-
if (_optionalChain([edit, 'optionalAccess',
|
|
9464
|
+
if (_optionalChain([edit, 'optionalAccess', _242 => _242.nodeId]) === node.id && (edit.index === existing || existing === null)) this.widthEdit = this.widthEditFor(node.id, subpath, index, null);
|
|
8326
9465
|
this.notify();
|
|
8327
9466
|
return { ok: true };
|
|
8328
9467
|
}
|
|
@@ -8356,7 +9495,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
8356
9495
|
/** The editor's view of point `index` (or of the stroke at `t` when index is null) of `nodeId`. */
|
|
8357
9496
|
widthEditFor(nodeId, subpath, index, t) {
|
|
8358
9497
|
const node = this.getNode(nodeId);
|
|
8359
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
9498
|
+
if (_optionalChain([node, 'optionalAccess', _243 => _243.type]) !== "path") return null;
|
|
8360
9499
|
const g = vectorStrokeWidthGeometry(node);
|
|
8361
9500
|
if (!g) return null;
|
|
8362
9501
|
const profile = sanitizeWidthProfile(node.strokeWidthProfile);
|
|
@@ -8390,7 +9529,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
8390
9529
|
const refs = this.cornerTargets(options);
|
|
8391
9530
|
if (!refs.length) return { ok: false, message: "Nothing is selected." };
|
|
8392
9531
|
this.change("Corner Kind", () => {
|
|
8393
|
-
this.doc = this.updateAnchors(this.doc, refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access',
|
|
9532
|
+
this.doc = this.updateAnchors(this.doc, refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access', _244 => _244.corner, 'optionalAccess', _245 => _245.radius]), () => ( 0)), kind));
|
|
8394
9533
|
});
|
|
8395
9534
|
return { ok: true };
|
|
8396
9535
|
}
|
|
@@ -8512,7 +9651,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
8512
9651
|
updateEffect(nodeId, effectId, patch, options = {}) {
|
|
8513
9652
|
const merge = options.merge === true ? `effect:${nodeId}:${effectId}` : options.merge || void 0;
|
|
8514
9653
|
const node = this.getNode(nodeId);
|
|
8515
|
-
const current = _optionalChain([node, 'optionalAccess',
|
|
9654
|
+
const current = _optionalChain([node, 'optionalAccess', _246 => _246.effects, 'optionalAccess', _247 => _247.find, 'call', _248 => _248((e) => e.id === effectId)]);
|
|
8516
9655
|
const label = current ? _nullishCoalesce(VECTOR_EFFECT_LABELS[current.type], () => ( "Effect")) : "Effect";
|
|
8517
9656
|
return this.editEffects(
|
|
8518
9657
|
nodeId,
|
|
@@ -8521,7 +9660,8 @@ var VectorEditorController = (_class5 = class {
|
|
|
8521
9660
|
const i = list.findIndex((e2) => e2.id === effectId);
|
|
8522
9661
|
if (i < 0) return `Node "${nodeId}" has no effect "${effectId}".`;
|
|
8523
9662
|
const e = list[i];
|
|
8524
|
-
const
|
|
9663
|
+
const raw = patch.params && e.type === "envelope" && node ? this.envelopeParams(node, e, patch.params) : patch.params;
|
|
9664
|
+
const params = raw ? normalizeVectorEffectParams(e.type, raw, e.params) : e.params;
|
|
8525
9665
|
const next = { ...e, params, ...patch.enabled !== void 0 ? { enabled: patch.enabled } : {} };
|
|
8526
9666
|
if (next.enabled !== false) delete next.enabled;
|
|
8527
9667
|
return list.map((x, j) => j === i ? next : x);
|
|
@@ -8645,10 +9785,10 @@ var VectorEditorController = (_class5 = class {
|
|
|
8645
9785
|
return this.selection.filter((id) => {
|
|
8646
9786
|
let covered = false;
|
|
8647
9787
|
const loc = locateVectorNode(this.doc.nodes, id);
|
|
8648
|
-
let parent = _nullishCoalesce(_optionalChain([loc, 'optionalAccess',
|
|
9788
|
+
let parent = _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _249 => _249.parent]), () => ( null));
|
|
8649
9789
|
while (parent) {
|
|
8650
9790
|
if (this.selection.includes(parent.id)) covered = true;
|
|
8651
|
-
parent = _nullishCoalesce(_optionalChain([locateVectorNode, 'call',
|
|
9791
|
+
parent = _nullishCoalesce(_optionalChain([locateVectorNode, 'call', _250 => _250(this.doc.nodes, parent.id), 'optionalAccess', _251 => _251.parent]), () => ( null));
|
|
8652
9792
|
}
|
|
8653
9793
|
return !covered;
|
|
8654
9794
|
});
|
|
@@ -8661,6 +9801,318 @@ var VectorEditorController = (_class5 = class {
|
|
|
8661
9801
|
if (!angle) return m;
|
|
8662
9802
|
return multiplyMatrices(multiplyMatrices(rotateMatrix(-angle), m), rotateMatrix(angle));
|
|
8663
9803
|
}
|
|
9804
|
+
/** The selection frame's corners in document space, clockwise from the top left. */
|
|
9805
|
+
frameCorners(frame2) {
|
|
9806
|
+
const rot = rotateMatrix(frame2.angle);
|
|
9807
|
+
return vectorBoxCorners(frame2).map((c) => frame2.angle ? applyMatrix(rot, c) : c);
|
|
9808
|
+
}
|
|
9809
|
+
/** `doc` with nodes `ids` sent through `f` (a map of document space), each in its own space (see `distortVectorNode`). */
|
|
9810
|
+
distorted(doc, ids, f, tolerance = VECTOR_DISTORT_TOLERANCE) {
|
|
9811
|
+
const visit = (list, parent) => {
|
|
9812
|
+
let changed = false;
|
|
9813
|
+
const out = list.map((n) => {
|
|
9814
|
+
let next = n;
|
|
9815
|
+
if (ids.has(n.id) && !n.locked) next = distortVectorNode(n, parent, f, tolerance);
|
|
9816
|
+
else if (n.type === "group") {
|
|
9817
|
+
const children = visit(n.children, multiplyMatrices(nodeMatrix(n), parent));
|
|
9818
|
+
if (children !== n.children) next = { ...n, children };
|
|
9819
|
+
}
|
|
9820
|
+
if (next !== n) changed = true;
|
|
9821
|
+
return next;
|
|
9822
|
+
});
|
|
9823
|
+
return changed ? out : list;
|
|
9824
|
+
};
|
|
9825
|
+
const nodes = visit(doc.nodes, IDENTITY_MATRIX);
|
|
9826
|
+
return nodes === doc.nodes ? doc : { ...doc, nodes };
|
|
9827
|
+
}
|
|
9828
|
+
/**
|
|
9829
|
+
* Free Distort mode of the selection box (`state.freeDistort`): dragging a corner distorts the
|
|
9830
|
+
* selection in perspective, each corner on its own (Shift+Alt+Mod: symmetric perspective, the
|
|
9831
|
+
* corner beside it moving the other way); dragging a side moves its two corners; Mod-dragging a
|
|
9832
|
+
* side skews along it (Alt: about the centre). Each drag is one undo step.
|
|
9833
|
+
*/
|
|
9834
|
+
setFreeDistort(on) {
|
|
9835
|
+
if (this.freeDistort === on) return;
|
|
9836
|
+
this.freeDistort = on;
|
|
9837
|
+
this.notify();
|
|
9838
|
+
}
|
|
9839
|
+
/**
|
|
9840
|
+
* Distorts the selected (or given) nodes so the corners of their selection box (clockwise from
|
|
9841
|
+
* the top left, in the box's own rotation) land on `corners` (document space): a projective map,
|
|
9842
|
+
* so straight lines stay straight. Curves are followed within `tolerance` (document units).
|
|
9843
|
+
* One undo step.
|
|
9844
|
+
*/
|
|
9845
|
+
distort(corners2, options = {}) {
|
|
9846
|
+
const ids = _nullishCoalesce(options.ids, () => ( this.selectedRoots()));
|
|
9847
|
+
const frame2 = this.frameOf(ids);
|
|
9848
|
+
if (!frame2) return { ok: false, message: "Nothing is selected." };
|
|
9849
|
+
if (!(frame2.width > 0 && frame2.height > 0)) return { ok: false, message: "The selection has no area to distort." };
|
|
9850
|
+
const from = this.frameCorners(frame2);
|
|
9851
|
+
const h = corners2.length === 4 ? vectorHomography(from, corners2) : null;
|
|
9852
|
+
if (!h || !vectorHomographyKeepsQuad(h, from)) return { ok: false, message: "The four corners must make a convex quadrilateral, clockwise from the top left." };
|
|
9853
|
+
this.change("Distort", () => {
|
|
9854
|
+
this.doc = this.distorted(this.doc, new Set(ids), (p) => _nullishCoalesce(applyVectorHomography(h, p), () => ( p)), options.tolerance);
|
|
9855
|
+
});
|
|
9856
|
+
return { ok: true };
|
|
9857
|
+
}
|
|
9858
|
+
/**
|
|
9859
|
+
* Skews the selected (or given) nodes along the selection box's own axes by `ax` degrees
|
|
9860
|
+
* horizontally (x' = x + tan(ax)·y: vertical lines lean right for positive angles) and `ay`
|
|
9861
|
+
* vertically, about `origin` (default: the box centre, document space). One undo step.
|
|
9862
|
+
*/
|
|
9863
|
+
skew(ax, ay = 0, options = {}) {
|
|
9864
|
+
const frame2 = this.frameOf(_nullishCoalesce(options.ids, () => ( this.selectedRoots())));
|
|
9865
|
+
if (!frame2) return { ok: false, message: "Nothing is selected." };
|
|
9866
|
+
if (![ax, ay].every((v2) => Number.isFinite(v2) && Math.abs(v2) < 89.9)) return { ok: false, message: "Skew angles must be between \u221289.9\xB0 and 89.9\xB0." };
|
|
9867
|
+
const origin = applyMatrix(rotateMatrix(-frame2.angle), _nullishCoalesce(options.origin, () => ( this.frameCenter(frame2))));
|
|
9868
|
+
return this.transform(this.inFrame(frame2.angle, vectorSkewMatrix(ax, ay, origin)), { ids: options.ids, label: "Skew" });
|
|
9869
|
+
}
|
|
9870
|
+
/** A selection box handle dragged in Free Distort mode. */
|
|
9871
|
+
moveDistort(drag, p, input) {
|
|
9872
|
+
const angle = drag.frame.angle;
|
|
9873
|
+
const unrotate = (v2) => angle ? applyMatrix(rotateMatrix(-angle), v2) : v2;
|
|
9874
|
+
const q = unrotate(p);
|
|
9875
|
+
const q0 = unrotate(drag.start);
|
|
9876
|
+
const d = { x: q.x - q0.x, y: q.y - q0.y };
|
|
9877
|
+
const ids = new Set(this.selectedRoots());
|
|
9878
|
+
const from = this.frameCorners(drag.frame);
|
|
9879
|
+
const corner = drag.handle.length === 2;
|
|
9880
|
+
this.setGuides(null);
|
|
9881
|
+
if (!corner && input.mod) {
|
|
9882
|
+
const m = this.inFrame(angle, vectorShearForSide(drag.frame, drag.handle, d, !!input.alt));
|
|
9883
|
+
drag.op = "Skew";
|
|
9884
|
+
this.doc = this.transformed(drag.base, ids, m);
|
|
9885
|
+
this.interaction = { type: "distort", mode: "skew", corners: from.map((c) => applyMatrix(m, c)) };
|
|
9886
|
+
this.notify(true);
|
|
9887
|
+
return;
|
|
9888
|
+
}
|
|
9889
|
+
const mode = corner && input.mod && input.alt && input.shift ? "perspective" : "distort";
|
|
9890
|
+
const rot = rotateMatrix(angle);
|
|
9891
|
+
const quad = vectorDistortQuad(drag.frame, drag.handle, d, mode).map((c) => angle ? applyMatrix(rot, c) : c);
|
|
9892
|
+
const h = vectorHomography(from, quad);
|
|
9893
|
+
if (!h || !vectorHomographyKeepsQuad(h, from)) return;
|
|
9894
|
+
drag.op = mode === "perspective" ? "Perspective" : "Distort";
|
|
9895
|
+
this.doc = this.distorted(drag.base, ids, (pt2) => _nullishCoalesce(applyVectorHomography(h, pt2), () => ( pt2)));
|
|
9896
|
+
this.interaction = { type: "distort", mode, corners: quad };
|
|
9897
|
+
this.notify(true);
|
|
9898
|
+
}
|
|
9899
|
+
// -------------------------------------------------------------------------
|
|
9900
|
+
// Envelopes
|
|
9901
|
+
// -------------------------------------------------------------------------
|
|
9902
|
+
/** Selected (or given) roots that can carry an envelope. */
|
|
9903
|
+
envelopeTargets(ids) {
|
|
9904
|
+
return this.effectTargets(ids).filter((n) => !n.locked);
|
|
9905
|
+
}
|
|
9906
|
+
/** Envelope parameters for `node` after `patch`: a preset switched to a mesh becomes the mesh it stood for. */
|
|
9907
|
+
envelopeParams(node, current, patch) {
|
|
9908
|
+
if (patch.style !== "mesh" || patch.mesh !== void 0 || !current || current.params.style === "mesh") return patch;
|
|
9909
|
+
const frame2 = vectorEnvelopeFrame(node, current.id);
|
|
9910
|
+
if (!frame2) return patch;
|
|
9911
|
+
const rows = typeof patch.rows === "number" ? patch.rows : current.params.rows;
|
|
9912
|
+
const columns = typeof patch.columns === "number" ? patch.columns : current.params.columns;
|
|
9913
|
+
return { ...patch, mesh: resizeVectorMesh(frame2.mesh, columns, rows) };
|
|
9914
|
+
}
|
|
9915
|
+
/**
|
|
9916
|
+
* Gives the selected (or given) nodes an envelope distortion, or changes the one they have: a
|
|
9917
|
+
* warp preset (`style` with `bend`, `horizontal` and `vertical` in percent and `orientation`) or
|
|
9918
|
+
* a mesh (`style: 'mesh'` with `rows` and `columns`, and optionally its `mesh` points). The
|
|
9919
|
+
* envelope stays live (an `envelope` effect: edit it with the Envelope tool, Expand Appearance
|
|
9920
|
+
* bakes it). One undo step (with `merge`, consecutive changes fold into one, as a slider drag
|
|
9921
|
+
* should). Returns the envelope of each node.
|
|
9922
|
+
*/
|
|
9923
|
+
envelope(params = {}, options = {}) {
|
|
9924
|
+
const targets = this.envelopeTargets(options.ids);
|
|
9925
|
+
if (!targets.length) return [];
|
|
9926
|
+
const out = [];
|
|
9927
|
+
const next = /* @__PURE__ */ new Map();
|
|
9928
|
+
const raw = params;
|
|
9929
|
+
for (const node of targets) {
|
|
9930
|
+
const list = _nullishCoalesce(node.effects, () => ( []));
|
|
9931
|
+
const current = _nullishCoalesce(list.find((e) => e.type === "envelope"), () => ( null));
|
|
9932
|
+
if (current) {
|
|
9933
|
+
const p = normalizeVectorEffectParams("envelope", this.envelopeParams(node, current, raw), current.params);
|
|
9934
|
+
const { enabled: _e, ...rest } = current;
|
|
9935
|
+
next.set(node.id, { ...node, effects: list.map((e) => e === current ? { ...rest, params: p } : e) });
|
|
9936
|
+
out.push({ nodeId: node.id, effectId: current.id });
|
|
9937
|
+
} else {
|
|
9938
|
+
let k = list.length + 1;
|
|
9939
|
+
while (list.some((e) => e.id === `fx${k}`)) k++;
|
|
9940
|
+
const effect = createVectorEffect("envelope", `fx${k}`, raw);
|
|
9941
|
+
next.set(node.id, { ...node, effects: [...list, effect] });
|
|
9942
|
+
out.push({ nodeId: node.id, effectId: effect.id });
|
|
9943
|
+
}
|
|
9944
|
+
}
|
|
9945
|
+
const made = out.some((o) => !_optionalChain([targets, 'access', _252 => _252.find, 'call', _253 => _253((n) => n.id === o.nodeId), 'optionalAccess', _254 => _254.effects, 'optionalAccess', _255 => _255.some, 'call', _256 => _256((e) => e.id === o.effectId)]));
|
|
9946
|
+
const merge = options.merge ? `envelope:${out.map((o) => o.nodeId).join(",")}` : void 0;
|
|
9947
|
+
this.change(made ? params.style === "mesh" ? "Make Envelope with Mesh" : "Make Envelope with Warp" : "Edit Envelope", () => this.setDoc(mapTree(this.doc.nodes, (n) => _nullishCoalesce(next.get(n.id), () => ( n)))), merge);
|
|
9948
|
+
return out;
|
|
9949
|
+
}
|
|
9950
|
+
/**
|
|
9951
|
+
* Make with Top Object: the topmost selected object's outline (a closed path) becomes the envelope
|
|
9952
|
+
* of the other selected objects (grouped when there are several; they must share a parent), as a
|
|
9953
|
+
* mesh of `columns × rows` patches whose border follows the outline. The top object is used up.
|
|
9954
|
+
* One undo step; returns the id of the enveloped node.
|
|
9955
|
+
*/
|
|
9956
|
+
makeEnvelopeWithTopObject(options = {}) {
|
|
9957
|
+
const ids = _nullishCoalesce(options.ids, () => ( this.selectedRoots()));
|
|
9958
|
+
if (ids.length < 2) return { ok: false, message: "Select the objects and, on top of them, the shape to use as the envelope." };
|
|
9959
|
+
const order = /* @__PURE__ */ new Map();
|
|
9960
|
+
walkVectorNodes(this.doc.nodes, (n) => order.set(n.id, order.size));
|
|
9961
|
+
const sorted = ids.filter((id) => order.has(id)).sort((a, b) => order.get(a) - order.get(b));
|
|
9962
|
+
const topId = sorted[sorted.length - 1];
|
|
9963
|
+
const top = this.getNode(topId);
|
|
9964
|
+
const outline = _optionalChain([top, 'optionalAccess', _257 => _257.type]) === "path" ? top.subpaths.find((sp) => sp.closed && sp.anchors.length > 1) : void 0;
|
|
9965
|
+
if (!top || !outline) return { ok: false, message: "The top object must be a path with a closed outline." };
|
|
9966
|
+
const contents = sorted.slice(0, -1).map((id) => this.getNode(id));
|
|
9967
|
+
if (contents.some((n) => n.locked)) return { ok: false, message: "Locked objects cannot be enveloped." };
|
|
9968
|
+
const parents = contents.map((n) => _nullishCoalesce(_optionalChain([locateVectorNode, 'call', _258 => _258(this.doc.nodes, n.id), 'optionalAccess', _259 => _259.parent, 'optionalAccess', _260 => _260.id]), () => ( null)));
|
|
9969
|
+
if (parents.some((p) => p !== parents[0])) return { ok: false, message: "The objects to envelope must be in the same group." };
|
|
9970
|
+
const target = contents.length === 1 ? contents[0] : { id: this.newId(), type: "group", name: "Envelope", children: contents.map((n) => n) };
|
|
9971
|
+
const parentToDoc = parents[0] ? this.worldOf(parents[0]) : IDENTITY_MATRIX;
|
|
9972
|
+
const targetToDoc = multiplyMatrices(nodeMatrix(target), parentToDoc);
|
|
9973
|
+
const toLocal = multiplyMatrices(this.worldOf(topId), invertMatrix(targetToDoc));
|
|
9974
|
+
const local = {
|
|
9975
|
+
closed: true,
|
|
9976
|
+
anchors: outline.anchors.map((a) => ({
|
|
9977
|
+
...applyMatrix(toLocal, a),
|
|
9978
|
+
...a.in ? { in: applyMatrix(toLocal, a.in) } : {},
|
|
9979
|
+
...a.out ? { out: applyMatrix(toLocal, a.out) } : {}
|
|
9980
|
+
}))
|
|
9981
|
+
};
|
|
9982
|
+
const mesh = vectorMeshFromOutline(local, _nullishCoalesce(options.columns, () => ( 4)), _nullishCoalesce(options.rows, () => ( 4)));
|
|
9983
|
+
if (!mesh) return { ok: false, message: "The top object\u2019s outline is too small to use as an envelope." };
|
|
9984
|
+
const list = _nullishCoalesce(target.effects, () => ( []));
|
|
9985
|
+
let k = list.length + 1;
|
|
9986
|
+
while (list.some((e) => e.id === `fx${k}`)) k++;
|
|
9987
|
+
const effect = createVectorEffect("envelope", `fx${k}`, { style: "mesh", mesh });
|
|
9988
|
+
const enveloped = { ...target, effects: [...list, effect] };
|
|
9989
|
+
this.change("Make Envelope with Top Object", () => {
|
|
9990
|
+
let nodes = spliceTree(this.doc.nodes, topId, []);
|
|
9991
|
+
if (contents.length === 1) nodes = spliceTree(nodes, target.id, [enveloped]);
|
|
9992
|
+
else {
|
|
9993
|
+
const last = contents[contents.length - 1].id;
|
|
9994
|
+
for (const n of contents.slice(0, -1)) nodes = spliceTree(nodes, n.id, []);
|
|
9995
|
+
nodes = spliceTree(nodes, last, [enveloped]);
|
|
9996
|
+
}
|
|
9997
|
+
this.setDoc(nodes);
|
|
9998
|
+
this.selection = [target.id];
|
|
9999
|
+
this.anchors = [];
|
|
10000
|
+
this.editingId = null;
|
|
10001
|
+
});
|
|
10002
|
+
return { ok: true, nodeId: target.id };
|
|
10003
|
+
}
|
|
10004
|
+
/**
|
|
10005
|
+
* Release: the selected (or given) nodes lose their envelope, and its shape (the mesh's border)
|
|
10006
|
+
* comes back as a path above each of them. One undo step; returns the new paths' ids.
|
|
10007
|
+
*/
|
|
10008
|
+
releaseEnvelope(options = {}) {
|
|
10009
|
+
const targets = this.envelopeTargets(options.ids).filter((n) => _optionalChain([n, 'access', _261 => _261.effects, 'optionalAccess', _262 => _262.some, 'call', _263 => _263((e) => e.type === "envelope")]));
|
|
10010
|
+
if (!targets.length) return [];
|
|
10011
|
+
const created = [];
|
|
10012
|
+
const replace = /* @__PURE__ */ new Map();
|
|
10013
|
+
for (const node of targets) {
|
|
10014
|
+
const effect = node.effects.find((e) => e.type === "envelope");
|
|
10015
|
+
const frame2 = vectorEnvelopeFrame(node, effect.id);
|
|
10016
|
+
const rest = node.effects.filter((e) => e !== effect);
|
|
10017
|
+
const { effects: _e, ...plain3 } = node;
|
|
10018
|
+
const kept = rest.length ? { ...plain3, effects: rest } : plain3;
|
|
10019
|
+
if (!frame2) {
|
|
10020
|
+
replace.set(node.id, [kept]);
|
|
10021
|
+
continue;
|
|
10022
|
+
}
|
|
10023
|
+
const id = this.newId();
|
|
10024
|
+
created.push(id);
|
|
10025
|
+
const shape = {
|
|
10026
|
+
id,
|
|
10027
|
+
type: "path",
|
|
10028
|
+
name: "Envelope",
|
|
10029
|
+
...node.transform ? { transform: node.transform } : {},
|
|
10030
|
+
subpaths: [vectorMeshOutline(frame2.mesh)],
|
|
10031
|
+
fill: null,
|
|
10032
|
+
stroke: "#808080",
|
|
10033
|
+
strokeWidth: 1
|
|
10034
|
+
};
|
|
10035
|
+
replace.set(node.id, [kept, shape]);
|
|
10036
|
+
}
|
|
10037
|
+
this.change("Release Envelope", () => {
|
|
10038
|
+
let nodes = this.doc.nodes;
|
|
10039
|
+
for (const [id, list] of replace) nodes = spliceTree(nodes, id, list);
|
|
10040
|
+
this.setDoc(nodes);
|
|
10041
|
+
this.selection = [...targets.map((n) => n.id), ...created];
|
|
10042
|
+
this.anchors = [];
|
|
10043
|
+
});
|
|
10044
|
+
return created;
|
|
10045
|
+
}
|
|
10046
|
+
/** The selected node the Envelope tool edits, with its mesh (node space) and node → document matrix. */
|
|
10047
|
+
envelopeTarget() {
|
|
10048
|
+
const target = getVectorEnvelopeTarget(this.doc, this.selection);
|
|
10049
|
+
return target && !target.node.locked ? target : null;
|
|
10050
|
+
}
|
|
10051
|
+
/** The envelope mesh point under `screen` (handles first), or a spot inside the mesh. */
|
|
10052
|
+
hitEnvelope(screen, p) {
|
|
10053
|
+
const target = this.envelopeTarget();
|
|
10054
|
+
if (!target) return null;
|
|
10055
|
+
const { mesh } = target.frame;
|
|
10056
|
+
const pts = vectorMeshEditPoints(mesh);
|
|
10057
|
+
let best = null;
|
|
10058
|
+
let bestD = Infinity;
|
|
10059
|
+
for (const index of [...pts.handles.map((h) => h.index), ...pts.anchors]) {
|
|
10060
|
+
const s = this.documentToScreen(applyMatrix(target.world, mesh.points[index]));
|
|
10061
|
+
const d = Math.hypot(s.x - screen.x, s.y - screen.y);
|
|
10062
|
+
if (d <= this.hitRadius && d < bestD - 0.5) {
|
|
10063
|
+
best = index;
|
|
10064
|
+
bestD = d;
|
|
10065
|
+
}
|
|
10066
|
+
}
|
|
10067
|
+
if (best !== null) return { target, index: best, s: 0, t: 0 };
|
|
10068
|
+
const local = applyMatrix(invertMatrix(target.world), p);
|
|
10069
|
+
const at2 = vectorMeshParamAt(mesh, local);
|
|
10070
|
+
if (at2.distance > this.tolerance()) return null;
|
|
10071
|
+
return { target, index: null, s: at2.s, t: at2.t };
|
|
10072
|
+
}
|
|
10073
|
+
downEnvelope(screen, p, input) {
|
|
10074
|
+
const hit = this.hitEnvelope(screen, p);
|
|
10075
|
+
if (hit) {
|
|
10076
|
+
const { node: node2, frame: frame2 } = hit.target;
|
|
10077
|
+
this.drag = {
|
|
10078
|
+
kind: "envelope",
|
|
10079
|
+
nodeId: node2.id,
|
|
10080
|
+
effectId: frame2.effectId,
|
|
10081
|
+
base: frame2.mesh,
|
|
10082
|
+
baseDoc: this.doc,
|
|
10083
|
+
before: this.snapshot(),
|
|
10084
|
+
index: hit.index,
|
|
10085
|
+
s: hit.s,
|
|
10086
|
+
t: hit.t,
|
|
10087
|
+
start: this.toLocal(node2.id, p),
|
|
10088
|
+
moved: false
|
|
10089
|
+
};
|
|
10090
|
+
this.interaction = { type: "envelope", nodeId: node2.id, index: hit.index };
|
|
10091
|
+
this.notify();
|
|
10092
|
+
return;
|
|
10093
|
+
}
|
|
10094
|
+
const node = hitTestVectorNodes(this.doc.nodes, p, this.tolerance(), { entered: this.enteredGroups() });
|
|
10095
|
+
if (node) this.selection = input.shift ? this.selection.includes(node.id) ? this.selection.filter((id) => id !== node.id) : [...this.selection, node.id] : [node.id];
|
|
10096
|
+
else if (!input.shift) this.selection = [];
|
|
10097
|
+
this.anchors = [];
|
|
10098
|
+
this.notify();
|
|
10099
|
+
}
|
|
10100
|
+
moveEnvelope(drag, p) {
|
|
10101
|
+
const local = this.toLocal(drag.nodeId, p, drag.baseDoc);
|
|
10102
|
+
const d = { x: local.x - drag.start.x, y: local.y - drag.start.y };
|
|
10103
|
+
if (!drag.moved && Math.hypot(d.x, d.y) * this.viewport.zoom < 1) return;
|
|
10104
|
+
drag.moved = true;
|
|
10105
|
+
const mesh = drag.index !== null ? dragVectorMeshPoint(drag.base, drag.index, d) : pullVectorMesh(drag.base, drag.s, drag.t, d);
|
|
10106
|
+
const nodes = mapTree(drag.baseDoc.nodes, (n) => {
|
|
10107
|
+
if (n.id !== drag.nodeId) return n;
|
|
10108
|
+
const effects = (_nullishCoalesce(n.effects, () => ( []))).map(
|
|
10109
|
+
(e) => e.id === drag.effectId && e.type === "envelope" ? { ...e, params: { ...e.params, style: "mesh", mesh, columns: mesh.us.length - 1, rows: mesh.vs.length - 1 } } : e
|
|
10110
|
+
);
|
|
10111
|
+
return { ...n, effects };
|
|
10112
|
+
});
|
|
10113
|
+
this.doc = { ...drag.baseDoc, nodes };
|
|
10114
|
+
this.notify(true);
|
|
10115
|
+
}
|
|
8664
10116
|
/** Applies a matrix to the selected (or given) nodes as one undo step. */
|
|
8665
10117
|
transform(matrix, options = {}) {
|
|
8666
10118
|
const ids = new Set(_nullishCoalesce(options.ids, () => ( this.selectedRoots())));
|
|
@@ -8831,8 +10283,8 @@ var VectorEditorController = (_class5 = class {
|
|
|
8831
10283
|
if (!ids.length) return null;
|
|
8832
10284
|
const locs = ids.map((id2) => locateVectorNode(this.doc.nodes, id2));
|
|
8833
10285
|
if (locs.some((l) => !l)) return null;
|
|
8834
|
-
const parent = _nullishCoalesce(_optionalChain([locs, 'access',
|
|
8835
|
-
if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access',
|
|
10286
|
+
const parent = _nullishCoalesce(_optionalChain([locs, 'access', _264 => _264[0], 'access', _265 => _265.parent, 'optionalAccess', _266 => _266.id]), () => ( null));
|
|
10287
|
+
if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access', _267 => _267.parent, 'optionalAccess', _268 => _268.id]), () => ( null))) !== parent)) return null;
|
|
8836
10288
|
const id = this.newId();
|
|
8837
10289
|
this.change("Group", () => {
|
|
8838
10290
|
const set = new Set(ids);
|
|
@@ -8855,7 +10307,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
8855
10307
|
}
|
|
8856
10308
|
/** Replaces selected groups with their children. */
|
|
8857
10309
|
ungroup(options = {}) {
|
|
8858
|
-
const groups = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess',
|
|
10310
|
+
const groups = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess', _269 => _269.type]) === "group");
|
|
8859
10311
|
if (!groups.length) return { ok: false, message: "Select a group to ungroup." };
|
|
8860
10312
|
const set = new Set(groups.map((g) => g.id));
|
|
8861
10313
|
this.change("Ungroup", () => {
|
|
@@ -8955,7 +10407,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
8955
10407
|
this.change(label, () => this.replaceNode(lone.id, { ...lone, liveBoolean: op, children }));
|
|
8956
10408
|
return lone.id;
|
|
8957
10409
|
}
|
|
8958
|
-
const parents = roots.map((id2) => _nullishCoalesce(_optionalChain([locateVectorNode, 'call',
|
|
10410
|
+
const parents = roots.map((id2) => _nullishCoalesce(_optionalChain([locateVectorNode, 'call', _270 => _270(this.doc.nodes, id2), 'optionalAccess', _271 => _271.parent]), () => ( null)));
|
|
8959
10411
|
if (parents.every((g) => isVectorLiveBoolean(g))) {
|
|
8960
10412
|
const set = new Set(roots);
|
|
8961
10413
|
this.change(
|
|
@@ -8976,8 +10428,8 @@ var VectorEditorController = (_class5 = class {
|
|
|
8976
10428
|
return parents[0].id;
|
|
8977
10429
|
}
|
|
8978
10430
|
if (nodes.length < 2) return null;
|
|
8979
|
-
const parent = _nullishCoalesce(_optionalChain([parents, 'access',
|
|
8980
|
-
if (parents.some((g) => (_nullishCoalesce(_optionalChain([g, 'optionalAccess',
|
|
10431
|
+
const parent = _nullishCoalesce(_optionalChain([parents, 'access', _272 => _272[0], 'optionalAccess', _273 => _273.id]), () => ( null));
|
|
10432
|
+
if (parents.some((g) => (_nullishCoalesce(_optionalChain([g, 'optionalAccess', _274 => _274.id]), () => ( null))) !== parent)) return null;
|
|
8981
10433
|
const id = this.newId();
|
|
8982
10434
|
this.change(label, () => {
|
|
8983
10435
|
const set = new Set(roots);
|
|
@@ -9025,7 +10477,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9025
10477
|
}
|
|
9026
10478
|
/** Splits selected compound paths into one path per subpath. */
|
|
9027
10479
|
breakApart(options = {}) {
|
|
9028
|
-
const paths = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess',
|
|
10480
|
+
const paths = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess', _275 => _275.type]) === "path" && n.subpaths.length > 1);
|
|
9029
10481
|
if (!paths.length) return { ok: false, message: "Select a compound path to break apart." };
|
|
9030
10482
|
const created = [];
|
|
9031
10483
|
const set = new Set(paths.map((p) => p.id));
|
|
@@ -9093,7 +10545,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9093
10545
|
const out = /* @__PURE__ */ new Map();
|
|
9094
10546
|
for (const id of _nullishCoalesce(ids, () => ( this.selection))) {
|
|
9095
10547
|
const node = this.getNode(id);
|
|
9096
|
-
const group = isVectorBlendGroup(node) ? node : _optionalChain([locateVectorNode, 'call',
|
|
10548
|
+
const group = isVectorBlendGroup(node) ? node : _optionalChain([locateVectorNode, 'call', _276 => _276(this.doc.nodes, id), 'optionalAccess', _277 => _277.parent]);
|
|
9097
10549
|
if (isVectorBlendGroup(group)) out.set(group.id, group);
|
|
9098
10550
|
}
|
|
9099
10551
|
return [...out.values()];
|
|
@@ -9111,8 +10563,8 @@ var VectorEditorController = (_class5 = class {
|
|
|
9111
10563
|
});
|
|
9112
10564
|
if (ids.length < 2) return null;
|
|
9113
10565
|
const locs = ids.map((id2) => locateVectorNode(this.doc.nodes, id2));
|
|
9114
|
-
const parent = _nullishCoalesce(_optionalChain([locs, 'access',
|
|
9115
|
-
if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access',
|
|
10566
|
+
const parent = _nullishCoalesce(_optionalChain([locs, 'access', _278 => _278[0], 'access', _279 => _279.parent, 'optionalAccess', _280 => _280.id]), () => ( null));
|
|
10567
|
+
if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access', _281 => _281.parent, 'optionalAccess', _282 => _282.id]), () => ( null))) !== parent)) return null;
|
|
9116
10568
|
const order = input.keepOrder ? ids : ids.slice().sort((a, b) => locs[ids.indexOf(a)].index - locs[ids.indexOf(b)].index);
|
|
9117
10569
|
const blend = blendOptionsOf({ ...this.blendDefaults, ...input });
|
|
9118
10570
|
if (input.starts) {
|
|
@@ -9154,7 +10606,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9154
10606
|
const node = this.getNode(nodeId);
|
|
9155
10607
|
if (!isVectorBlendGroup(group)) return { ok: false, message: `"${blendId}" is not a blend.` };
|
|
9156
10608
|
if (!node || node.blendStep || node.locked || node.id === blendId) return { ok: false, message: `"${nodeId}" cannot be a key.` };
|
|
9157
|
-
const parentOf = (id) => _nullishCoalesce(_optionalChain([locateVectorNode, 'call',
|
|
10609
|
+
const parentOf = (id) => _nullishCoalesce(_optionalChain([locateVectorNode, 'call', _283 => _283(this.doc.nodes, id), 'optionalAccess', _284 => _284.parent, 'optionalAccess', _285 => _285.id]), () => ( null));
|
|
9158
10610
|
if (parentOf(blendId) !== parentOf(nodeId)) return { ok: false, message: "The new key must sit beside the blend (same parent)." };
|
|
9159
10611
|
const start = options.start;
|
|
9160
10612
|
this.change("Blend", () => {
|
|
@@ -9224,7 +10676,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9224
10676
|
replaceBlendSpine(options = {}) {
|
|
9225
10677
|
const roots = _nullishCoalesce(options.ids, () => ( this.selectedRoots()));
|
|
9226
10678
|
const groups = this.blendTargets(roots);
|
|
9227
|
-
const paths = roots.map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess',
|
|
10679
|
+
const paths = roots.map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess', _286 => _286.type]) === "path" && !n.blendStep && !isVectorBlendGroup(_optionalChain([locateVectorNode, 'call', _287 => _287(this.doc.nodes, n.id), 'optionalAccess', _288 => _288.parent])));
|
|
9228
10680
|
if (groups.length !== 1 || paths.length !== 1) return { ok: false, message: "Select one blend and one path to be its spine." };
|
|
9229
10681
|
const group = groups[0];
|
|
9230
10682
|
const path = paths[0];
|
|
@@ -9255,7 +10707,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9255
10707
|
shapeBuilderMap(ids) {
|
|
9256
10708
|
const roots = _nullishCoalesce(ids, () => ( this.selectedRoots()));
|
|
9257
10709
|
const key = roots.join("\0");
|
|
9258
|
-
if (_optionalChain([this, 'access',
|
|
10710
|
+
if (_optionalChain([this, 'access', _289 => _289.builderCache, 'optionalAccess', _290 => _290.doc]) === this.doc && this.builderCache.key === key) return this.builderCache.map;
|
|
9259
10711
|
const entries = roots.length ? vectorPathEntries(this.doc, roots, { expand: false }) : [];
|
|
9260
10712
|
const map = entries.length ? vectorShapeBuilderMap(entries) : null;
|
|
9261
10713
|
this.builderCache = { doc: this.doc, key, map };
|
|
@@ -9315,9 +10767,9 @@ var VectorEditorController = (_class5 = class {
|
|
|
9315
10767
|
const list = [];
|
|
9316
10768
|
const r = plan.replace.get(i);
|
|
9317
10769
|
if (r === void 0) list.push(node);
|
|
9318
|
-
else if (_optionalChain([r, 'optionalAccess',
|
|
9319
|
-
else if (_optionalChain([r, 'optionalAccess',
|
|
9320
|
-
else if (_optionalChain([r, 'optionalAccess',
|
|
10770
|
+
else if (_optionalChain([r, 'optionalAccess', _291 => _291.kind]) === "fill") list.push({ ...node, fillRule: "nonzero", subpaths: bezierToSubpaths(toLocal(r.path)) });
|
|
10771
|
+
else if (_optionalChain([r, 'optionalAccess', _292 => _292.kind]) === "outline") list.push({ ...node, subpaths: bezierToSubpaths(toLocal(r.path)) });
|
|
10772
|
+
else if (_optionalChain([r, 'optionalAccess', _293 => _293.kind]) === "pieces") {
|
|
9321
10773
|
r.paths.forEach(
|
|
9322
10774
|
(path, k) => list.push({ ...node, id: k === 0 ? node.id : this.newId(), subpaths: bezierToSubpaths(toLocal(path)).map((sp) => ({ ...sp, closed: false })) })
|
|
9323
10775
|
);
|
|
@@ -9351,7 +10803,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9351
10803
|
}
|
|
9352
10804
|
/** The paint bucket's map of the visible outlines, cached per document and gap. */
|
|
9353
10805
|
fillMap(gap) {
|
|
9354
|
-
if (_optionalChain([this, 'access',
|
|
10806
|
+
if (_optionalChain([this, 'access', _294 => _294.fillCache, 'optionalAccess', _295 => _295.doc]) === this.doc && this.fillCache.gap === gap) return this.fillCache.map;
|
|
9355
10807
|
const map = vectorFillMap(this.doc, gap);
|
|
9356
10808
|
this.fillCache = { doc: this.doc, gap, map };
|
|
9357
10809
|
return map;
|
|
@@ -9365,8 +10817,8 @@ var VectorEditorController = (_class5 = class {
|
|
|
9365
10817
|
*/
|
|
9366
10818
|
fillRegion(point, options = {}) {
|
|
9367
10819
|
if (!Number.isFinite(point.x) || !Number.isFinite(point.y)) return null;
|
|
9368
|
-
const region = _optionalChain([this, 'access',
|
|
9369
|
-
if (!_optionalChain([region, 'optionalAccess',
|
|
10820
|
+
const region = _optionalChain([this, 'access', _296 => _296.fillMap, 'call', _297 => _297(_nullishCoalesce(options.gap, () => ( this.editing.fillGap))), 'optionalAccess', _298 => _298.regionAt, 'call', _299 => _299([point.x, point.y])]);
|
|
10821
|
+
if (!_optionalChain([region, 'optionalAccess', _300 => _300.length])) return null;
|
|
9370
10822
|
let below = null;
|
|
9371
10823
|
const roots = new Set(this.selectedRoots());
|
|
9372
10824
|
walkVectorNodes(this.doc.nodes, (n) => {
|
|
@@ -9392,7 +10844,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9392
10844
|
/** Updates the Shape Builder / paint bucket highlight for the pointer at `p`; true when it changed. */
|
|
9393
10845
|
hoverBuilder(p, alt) {
|
|
9394
10846
|
if (this.tool === "paintBucket") {
|
|
9395
|
-
const region = _nullishCoalesce(_optionalChain([this, 'access',
|
|
10847
|
+
const region = _nullishCoalesce(_optionalChain([this, 'access', _301 => _301.fillMap, 'call', _302 => _302(this.editing.fillGap), 'optionalAccess', _303 => _303.regionAt, 'call', _304 => _304([p.x, p.y])]), () => ( null));
|
|
9396
10848
|
const key2 = region ? _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, region, { precision: 2 }) : null;
|
|
9397
10849
|
if (key2 === this.builderHoverKey) return false;
|
|
9398
10850
|
this.builderHoverKey = key2;
|
|
@@ -9500,7 +10952,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9500
10952
|
/** `doc` with anchor `ref` moved to document point `to` by a Curvature-tool move. */
|
|
9501
10953
|
curvatureMoved(doc, ref, to) {
|
|
9502
10954
|
const node = findVectorNode(doc.nodes, ref.nodeId);
|
|
9503
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
10955
|
+
if (_optionalChain([node, 'optionalAccess', _305 => _305.type]) !== "path" || node.locked || !node.subpaths[ref.subpath]) return doc;
|
|
9504
10956
|
const q = this.toLocal(ref.nodeId, to, doc);
|
|
9505
10957
|
const subpaths = node.subpaths.map((sp, i) => i === ref.subpath ? curvatureMoveAnchor(sp, ref.index, q) : sp);
|
|
9506
10958
|
const nodes = mapTree(doc.nodes, (n) => n.id === ref.nodeId ? { ...node, subpaths } : n);
|
|
@@ -9509,7 +10961,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9509
10961
|
/** `doc` with segment `ref` bent through document point `p` at parameter `t`. */
|
|
9510
10962
|
bent(doc, ref, t, p) {
|
|
9511
10963
|
const node = findVectorNode(doc.nodes, ref.nodeId);
|
|
9512
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
10964
|
+
if (_optionalChain([node, 'optionalAccess', _306 => _306.type]) !== "path" || node.locked || !node.subpaths[ref.subpath]) return doc;
|
|
9513
10965
|
const q = this.toLocal(ref.nodeId, p, doc);
|
|
9514
10966
|
const subpaths = node.subpaths.map((sp, i) => i === ref.subpath ? bendSegment(sp, ref.segment, t, q) : sp);
|
|
9515
10967
|
return { ...doc, nodes: mapTree(doc.nodes, (n) => n.id === ref.nodeId ? { ...node, subpaths } : n) };
|
|
@@ -9520,7 +10972,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9520
10972
|
*/
|
|
9521
10973
|
bendSegment(ref, to, t = 0.5) {
|
|
9522
10974
|
const node = this.getNode(ref.nodeId);
|
|
9523
|
-
const sp = _optionalChain([node, 'optionalAccess',
|
|
10975
|
+
const sp = _optionalChain([node, 'optionalAccess', _307 => _307.type]) === "path" ? node.subpaths[ref.subpath] : void 0;
|
|
9524
10976
|
if (!sp || ref.segment < 0 || ref.segment >= (sp.closed ? sp.anchors.length : sp.anchors.length - 1) || sp.anchors.length < 2) return { ok: false, message: "There is no such segment." };
|
|
9525
10977
|
if (node.locked) return { ok: false, message: "The path is locked." };
|
|
9526
10978
|
this.change("Bend Segment", () => {
|
|
@@ -9555,7 +11007,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9555
11007
|
/** Adds an anchor on the nearest segment of `nodeId` to document point `point` (shape unchanged). */
|
|
9556
11008
|
insertAnchorAt(nodeId, point) {
|
|
9557
11009
|
const node = this.getNode(nodeId);
|
|
9558
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
11010
|
+
if (_optionalChain([node, 'optionalAccess', _308 => _308.type]) !== "path") return null;
|
|
9559
11011
|
const hit = nearestSegment(node, this.toLocal(nodeId, point));
|
|
9560
11012
|
if (!hit) return null;
|
|
9561
11013
|
const { subpath, index } = insertAnchor(node.subpaths[hit.subpath], hit.segment, hit.t);
|
|
@@ -9599,7 +11051,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9599
11051
|
setClosed(closed, nodeId) {
|
|
9600
11052
|
const targets = nodeId ? (() => {
|
|
9601
11053
|
const n = this.getNode(nodeId);
|
|
9602
|
-
return _optionalChain([n, 'optionalAccess',
|
|
11054
|
+
return _optionalChain([n, 'optionalAccess', _309 => _309.type]) === "path" ? n.subpaths.map((_, s) => ({ nodeId, subpath: s })) : [];
|
|
9603
11055
|
})() : this.anchors.map((r) => ({ nodeId: r.nodeId, subpath: r.subpath }));
|
|
9604
11056
|
if (!targets.length) return { ok: false, message: "Select a path or points." };
|
|
9605
11057
|
this.change(closed ? "Close Path" : "Open Path", () => {
|
|
@@ -9620,7 +11072,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9620
11072
|
this.setDoc(
|
|
9621
11073
|
mapTree(
|
|
9622
11074
|
this.doc.nodes,
|
|
9623
|
-
(n) => n.type === "path" && set.has(n.id) ? { ...n, subpaths: n.subpaths.map(reverseSubpath), ..._optionalChain([n, 'access',
|
|
11075
|
+
(n) => n.type === "path" && set.has(n.id) ? { ...n, subpaths: n.subpaths.map(reverseSubpath), ..._optionalChain([n, 'access', _310 => _310.strokeWidthProfile, 'optionalAccess', _311 => _311.length]) ? { strokeWidthProfile: reverseWidthProfile(n.strokeWidthProfile) } : {} } : n
|
|
9624
11076
|
)
|
|
9625
11077
|
);
|
|
9626
11078
|
this.anchors = [];
|
|
@@ -9758,7 +11210,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9758
11210
|
*/
|
|
9759
11211
|
cutPathAt(nodeId, point) {
|
|
9760
11212
|
const node = this.getNode(nodeId);
|
|
9761
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
11213
|
+
if (_optionalChain([node, 'optionalAccess', _312 => _312.type]) !== "path" || node.locked) return null;
|
|
9762
11214
|
const local = this.toLocal(nodeId, point);
|
|
9763
11215
|
const hit = nearestSegment(node, local);
|
|
9764
11216
|
if (!hit) return null;
|
|
@@ -9808,8 +11260,8 @@ var VectorEditorController = (_class5 = class {
|
|
|
9808
11260
|
if (n.visible === false || n.locked || parent && blocked.has(parent.id)) blocked.add(n.id);
|
|
9809
11261
|
});
|
|
9810
11262
|
const visible = (p) => !blocked.has(p.id);
|
|
9811
|
-
if (_optionalChain([ids, 'optionalAccess',
|
|
9812
|
-
const box = polylineBounds(points.map(
|
|
11263
|
+
if (_optionalChain([ids, 'optionalAccess', _313 => _313.length]) || this.selection.length) return this.pathTargets(_nullishCoalesce(ids, () => ( this.selection))).filter(visible);
|
|
11264
|
+
const box = polylineBounds(points.map(toPoint3), pad);
|
|
9813
11265
|
if (!box) return [];
|
|
9814
11266
|
const out = [];
|
|
9815
11267
|
walkVectorNodes(this.doc.nodes, (n) => {
|
|
@@ -9822,7 +11274,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9822
11274
|
/** A stroke's points in node `id`'s own space. */
|
|
9823
11275
|
localPoints(id, points) {
|
|
9824
11276
|
const inv = invertMatrix(this.worldOf(id));
|
|
9825
|
-
return points.map((p) =>
|
|
11277
|
+
return points.map((p) => toPoint3(applyMatrix(inv, p)));
|
|
9826
11278
|
}
|
|
9827
11279
|
/**
|
|
9828
11280
|
* Knife: cuts closed paths along the polyline `points` (document space) wherever it crosses
|
|
@@ -9831,7 +11283,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9831
11283
|
* when nothing was cut).
|
|
9832
11284
|
*/
|
|
9833
11285
|
knife(points, options = {}) {
|
|
9834
|
-
const pts = simplifyPolyline(points.map(
|
|
11286
|
+
const pts = simplifyPolyline(points.map(toPoint3), 0.25 / this.viewport.zoom).map(([x, y]) => ({ x, y }));
|
|
9835
11287
|
if (pts.length < 2) return [];
|
|
9836
11288
|
const plan = [];
|
|
9837
11289
|
for (const node of this.strokeTargets(pts, options.ids, 0)) {
|
|
@@ -9860,7 +11312,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9860
11312
|
erase(points, options = {}) {
|
|
9861
11313
|
const width = _nullishCoalesce(options.size, () => ( this.editing.eraserSize));
|
|
9862
11314
|
if (!(width > 0) || !points.length) return [];
|
|
9863
|
-
const pts = simplifyPolyline(points.map(
|
|
11315
|
+
const pts = simplifyPolyline(points.map(toPoint3), Math.min(width * 0.05, 0.25 / this.viewport.zoom));
|
|
9864
11316
|
const region = eraserRegion(pts, width);
|
|
9865
11317
|
if (!region.length) return [];
|
|
9866
11318
|
const plan = [];
|
|
@@ -9894,7 +11346,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9894
11346
|
finishPath() {
|
|
9895
11347
|
if (!this.pen) return;
|
|
9896
11348
|
const node = this.getNode(this.pen.nodeId);
|
|
9897
|
-
const sp = _optionalChain([node, 'optionalAccess',
|
|
11349
|
+
const sp = _optionalChain([node, 'optionalAccess', _314 => _314.subpaths, 'access', _315 => _315[this.pen.subpath]]);
|
|
9898
11350
|
const pen = this.pen;
|
|
9899
11351
|
this.pen = null;
|
|
9900
11352
|
this.pointer = null;
|
|
@@ -9938,7 +11390,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9938
11390
|
if (trimmed.startsWith("{")) {
|
|
9939
11391
|
try {
|
|
9940
11392
|
const data = JSON.parse(trimmed);
|
|
9941
|
-
if (_optionalChain([data, 'optionalAccess',
|
|
11393
|
+
if (_optionalChain([data, 'optionalAccess', _316 => _316.type]) === VECTOR_CLIPBOARD_TYPE && Array.isArray(data.nodes)) nodes = data.nodes;
|
|
9942
11394
|
} catch (e7) {
|
|
9943
11395
|
nodes = null;
|
|
9944
11396
|
}
|
|
@@ -9950,7 +11402,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
9950
11402
|
}
|
|
9951
11403
|
}
|
|
9952
11404
|
} else nodes = this.clipboard;
|
|
9953
|
-
if (!_optionalChain([nodes, 'optionalAccess',
|
|
11405
|
+
if (!_optionalChain([nodes, 'optionalAccess', _317 => _317.length])) return [];
|
|
9954
11406
|
const offset = _nullishCoalesce(options.offset, () => ( (text && !text.trim().startsWith("{") ? { x: 0, y: 0 } : { x: 10, y: 10 })));
|
|
9955
11407
|
const copies = nodes.map((n) => transformVectorNode(this.freshIds(n), translateMatrix(offset.x, offset.y)));
|
|
9956
11408
|
this.change("Paste", () => {
|
|
@@ -10001,7 +11453,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
10001
11453
|
hitHandle(screen) {
|
|
10002
11454
|
for (const ref of getVisibleHandles(this.view()).reverse()) {
|
|
10003
11455
|
const a = getAnchorWorld(this.doc, ref);
|
|
10004
|
-
const h = _optionalChain([a, 'optionalAccess',
|
|
11456
|
+
const h = _optionalChain([a, 'optionalAccess', _318 => _318[ref.handle]]);
|
|
10005
11457
|
if (!h) continue;
|
|
10006
11458
|
const s = this.documentToScreen(h);
|
|
10007
11459
|
if (Math.hypot(s.x - screen.x, s.y - screen.y) <= this.hitRadius) return ref;
|
|
@@ -10128,6 +11580,12 @@ var VectorEditorController = (_class5 = class {
|
|
|
10128
11580
|
const path = this.hitPath(p);
|
|
10129
11581
|
return path ? { nodeId: path.id } : null;
|
|
10130
11582
|
}
|
|
11583
|
+
case "envelope": {
|
|
11584
|
+
const hit = this.hitEnvelope(screen, p);
|
|
11585
|
+
if (hit) return { nodeId: hit.target.node.id, envelope: { nodeId: hit.target.node.id, index: hit.index } };
|
|
11586
|
+
const node = hitTestVectorNodes(this.doc.nodes, p, this.tolerance(), { entered: this.enteredGroups() });
|
|
11587
|
+
return node ? { nodeId: node.id } : null;
|
|
11588
|
+
}
|
|
10131
11589
|
default:
|
|
10132
11590
|
return null;
|
|
10133
11591
|
}
|
|
@@ -10140,7 +11598,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
10140
11598
|
const shown = this.hitWidthHandleIn(screen, this.widthView());
|
|
10141
11599
|
if (shown) return shown;
|
|
10142
11600
|
const spot = this.strokeSpotAt(this.screenToDocument(screen));
|
|
10143
|
-
return spot && spot.nodeId !== _optionalChain([this, 'access',
|
|
11601
|
+
return spot && spot.nodeId !== _optionalChain([this, 'access', _319 => _319.hover, 'optionalAccess', _320 => _320.nodeId]) ? this.hitWidthHandleIn(screen, { ...this.widthView(), hover: { nodeId: spot.nodeId } }) : null;
|
|
10144
11602
|
}
|
|
10145
11603
|
hitWidthHandleIn(screen, view) {
|
|
10146
11604
|
let best = null;
|
|
@@ -10195,9 +11653,9 @@ var VectorEditorController = (_class5 = class {
|
|
|
10195
11653
|
downWidth(screen, p, input) {
|
|
10196
11654
|
const hit = this.hitWidthHandle(screen);
|
|
10197
11655
|
const spot = hit ? null : this.strokeSpotAt(p);
|
|
10198
|
-
const nodeId = _nullishCoalesce(_optionalChain([hit, 'optionalAccess',
|
|
11656
|
+
const nodeId = _nullishCoalesce(_optionalChain([hit, 'optionalAccess', _321 => _321.ref, 'access', _322 => _322.nodeId]), () => ( _optionalChain([spot, 'optionalAccess', _323 => _323.nodeId])));
|
|
10199
11657
|
const node = nodeId ? this.getNode(nodeId) : void 0;
|
|
10200
|
-
const g = _optionalChain([node, 'optionalAccess',
|
|
11658
|
+
const g = _optionalChain([node, 'optionalAccess', _324 => _324.type]) === "path" ? vectorStrokeWidthGeometry(node) : null;
|
|
10201
11659
|
if (this.widthEdit) this.widthEdit = null;
|
|
10202
11660
|
if (!node || node.type !== "path" || !g) {
|
|
10203
11661
|
if (!input.shift) this.widthPoints = [];
|
|
@@ -10217,19 +11675,19 @@ var VectorEditorController = (_class5 = class {
|
|
|
10217
11675
|
if (hit) {
|
|
10218
11676
|
profile = sanitizeWidthProfile(node.strokeWidthProfile);
|
|
10219
11677
|
ref = { nodeId: node.id, index: hit.ref.index, subpath: hit.ref.subpath };
|
|
10220
|
-
t = _nullishCoalesce(_optionalChain([profile, 'access',
|
|
11678
|
+
t = _nullishCoalesce(_optionalChain([profile, 'access', _325 => _325[ref.index], 'optionalAccess', _326 => _326.t]), () => ( 0));
|
|
10221
11679
|
subpath = hit.ref.subpath;
|
|
10222
11680
|
if (hit.ref.part === "center") mode = input.alt && profile.length < VECTOR_WIDTH_PROFILE_MAX_POINTS ? "copy" : "move";
|
|
10223
11681
|
else if (input.alt) side = hit.ref.part;
|
|
10224
|
-
const
|
|
10225
|
-
const selected =
|
|
11682
|
+
const same2 = this.widthPoints.length > 0 && this.widthPoints[0].nodeId === node.id;
|
|
11683
|
+
const selected = same2 && this.widthPoints.some((r) => r.index === ref.index);
|
|
10226
11684
|
if (input.shift && mode !== "copy") {
|
|
10227
11685
|
if (selected) {
|
|
10228
11686
|
this.widthPoints = this.widthPoints.filter((r) => r.index !== ref.index);
|
|
10229
11687
|
this.notify();
|
|
10230
11688
|
return;
|
|
10231
11689
|
}
|
|
10232
|
-
this.widthPoints =
|
|
11690
|
+
this.widthPoints = same2 ? [...this.widthPoints, ref] : [ref];
|
|
10233
11691
|
shift = true;
|
|
10234
11692
|
} else if (mode === "copy" || !selected) this.widthPoints = [ref];
|
|
10235
11693
|
if (mode !== "copy") group = this.widthPoints.filter((r) => r.index !== ref.index).map((r) => r.index);
|
|
@@ -10352,6 +11810,8 @@ var VectorEditorController = (_class5 = class {
|
|
|
10352
11810
|
return this.downBlend(screen, p);
|
|
10353
11811
|
case "gradient":
|
|
10354
11812
|
return this.downGradient(screen, p, input);
|
|
11813
|
+
case "envelope":
|
|
11814
|
+
return this.downEnvelope(screen, p, input);
|
|
10355
11815
|
case "scissors": {
|
|
10356
11816
|
const seg = this.nearestOutline(p);
|
|
10357
11817
|
if (seg) this.cutPathAt(seg.nodeId, seg.point);
|
|
@@ -10374,7 +11834,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
10374
11834
|
let anchor = null;
|
|
10375
11835
|
if (node.type === "path" && node.subpaths[0]) {
|
|
10376
11836
|
const refs = node.subpaths[0].anchors.map((_, index) => ({ nodeId: node.id, subpath: 0, index }));
|
|
10377
|
-
anchor = _nullishCoalesce(_optionalChain([this, 'access',
|
|
11837
|
+
anchor = _nullishCoalesce(_optionalChain([this, 'access', _327 => _327.hitAnchor, 'call', _328 => _328(screen, refs), 'optionalAccess', _329 => _329.index]), () => ( null));
|
|
10378
11838
|
}
|
|
10379
11839
|
return { nodeId: node.id, anchor };
|
|
10380
11840
|
}
|
|
@@ -10527,7 +11987,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
10527
11987
|
}
|
|
10528
11988
|
downPen(screen, p, input) {
|
|
10529
11989
|
const before = this.snapshot();
|
|
10530
|
-
const sp = this.pen ? _optionalChain([this, 'access',
|
|
11990
|
+
const sp = this.pen ? _optionalChain([this, 'access', _330 => _330.getNode, 'call', _331 => _331(this.pen.nodeId), 'optionalAccess', _332 => _332.subpaths, 'access', _333 => _333[this.pen.subpath]]) : void 0;
|
|
10531
11991
|
if (this.pen && sp) {
|
|
10532
11992
|
const pen = this.pen;
|
|
10533
11993
|
const first = { nodeId: pen.nodeId, subpath: pen.subpath, index: 0 };
|
|
@@ -10645,6 +12105,8 @@ var VectorEditorController = (_class5 = class {
|
|
|
10645
12105
|
return;
|
|
10646
12106
|
case "gradient":
|
|
10647
12107
|
return this.moveGradient(drag, screen, p, input);
|
|
12108
|
+
case "envelope":
|
|
12109
|
+
return this.moveEnvelope(drag, p);
|
|
10648
12110
|
case "move": {
|
|
10649
12111
|
let dx = p.x - drag.start.x;
|
|
10650
12112
|
let dy = p.y - drag.start.y;
|
|
@@ -10665,6 +12127,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
10665
12127
|
return;
|
|
10666
12128
|
}
|
|
10667
12129
|
case "scale": {
|
|
12130
|
+
if (this.freeDistort && drag.handle !== "rotate") return this.moveDistort(drag, p, input);
|
|
10668
12131
|
const angle = drag.frame.angle;
|
|
10669
12132
|
const q = angle ? applyMatrix(rotateMatrix(-angle), p) : p;
|
|
10670
12133
|
let { sx, sy, origin } = scaleFor(drag.handle, drag.frame, q, input);
|
|
@@ -10791,7 +12254,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
10791
12254
|
}
|
|
10792
12255
|
case "shape": {
|
|
10793
12256
|
const node = this.getNode(drag.nodeId);
|
|
10794
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
12257
|
+
if (_optionalChain([node, 'optionalAccess', _334 => _334.type]) !== "path") return;
|
|
10795
12258
|
const leave = { at: drag.start, constrain: input.shift ? drag.tool === "line" ? "angle" : "square" : null, curves: false };
|
|
10796
12259
|
let end = this.snapDrawn(p, leave, input, () => drag.targets ??= this.drawingTargets(null));
|
|
10797
12260
|
if (!this.snappedToObject && drag.tool !== "line" && !input.shift && !input.mod && this.snap.objects && drag.targets) end = this.matchShapeSize(drag.targets, drag.start, end, input.alt);
|
|
@@ -10865,14 +12328,14 @@ var VectorEditorController = (_class5 = class {
|
|
|
10865
12328
|
for (const q of drag.lazy.push([p.x, p.y])) {
|
|
10866
12329
|
if (Math.hypot(q[0] - last[0], q[1] - last[1]) * this.viewport.zoom < 1.5) continue;
|
|
10867
12330
|
drag.points.push(q);
|
|
10868
|
-
_optionalChain([drag, 'access',
|
|
12331
|
+
_optionalChain([drag, 'access', _335 => _335.pressures, 'optionalAccess', _336 => _336.push, 'call', _337 => _337(drag.pressure)]);
|
|
10869
12332
|
moved = true;
|
|
10870
12333
|
}
|
|
10871
12334
|
const string = drag.lazy.string();
|
|
10872
12335
|
const node = this.getNode(drag.nodeId);
|
|
10873
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
12336
|
+
if (_optionalChain([node, 'optionalAccess', _338 => _338.type]) !== "path") return;
|
|
10874
12337
|
if (!moved) {
|
|
10875
|
-
if (string && _optionalChain([this, 'access',
|
|
12338
|
+
if (string && _optionalChain([this, 'access', _339 => _339.interaction, 'optionalAccess', _340 => _340.type]) === "draw") {
|
|
10876
12339
|
this.interaction = { ...this.interaction, string: [{ x: string[0][0], y: string[0][1] }, { x: string[1][0], y: string[1][1] }] };
|
|
10877
12340
|
this.notify();
|
|
10878
12341
|
}
|
|
@@ -10908,8 +12371,8 @@ var VectorEditorController = (_class5 = class {
|
|
|
10908
12371
|
}
|
|
10909
12372
|
this.setGuides(res);
|
|
10910
12373
|
return {
|
|
10911
|
-
dx: _optionalChain([res, 'optionalAccess',
|
|
10912
|
-
dy: _optionalChain([res, 'optionalAccess',
|
|
12374
|
+
dx: _optionalChain([res, 'optionalAccess', _341 => _341.x]) ? dx + res.dx : axes.x ? this.gridValue(origin.x + dx) - origin.x : dx,
|
|
12375
|
+
dy: _optionalChain([res, 'optionalAccess', _342 => _342.y]) ? dy + res.dy : axes.y ? this.gridValue(origin.y + dy) - origin.y : dy
|
|
10913
12376
|
};
|
|
10914
12377
|
}
|
|
10915
12378
|
/** The anchor a point drag snaps by, where it started: the grabbed one, else the moving one nearest the press. */
|
|
@@ -10965,7 +12428,13 @@ var VectorEditorController = (_class5 = class {
|
|
|
10965
12428
|
}
|
|
10966
12429
|
return this.commit(drag.duplicated ? "Duplicate" : "Move", drag.before);
|
|
10967
12430
|
case "scale":
|
|
10968
|
-
return this.commit("Scale", drag.before);
|
|
12431
|
+
return this.commit(_nullishCoalesce(drag.op, () => ( "Scale")), drag.before);
|
|
12432
|
+
case "envelope":
|
|
12433
|
+
if (!drag.moved) {
|
|
12434
|
+
this.notify();
|
|
12435
|
+
return;
|
|
12436
|
+
}
|
|
12437
|
+
return this.commit("Edit Envelope", drag.before);
|
|
10969
12438
|
case "rotate":
|
|
10970
12439
|
return this.commit("Rotate", drag.before);
|
|
10971
12440
|
case "anchors":
|
|
@@ -10988,7 +12457,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
10988
12457
|
if (drag.moved) return this.commit("Corner Radius", drag.before);
|
|
10989
12458
|
if (drag.alt) {
|
|
10990
12459
|
const kind = nextVectorCornerKind(drag.widget.kind);
|
|
10991
|
-
this.doc = this.updateAnchors(drag.base, drag.refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access',
|
|
12460
|
+
this.doc = this.updateAnchors(drag.base, drag.refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access', _343 => _343.corner, 'optionalAccess', _344 => _344.radius]), () => ( 0)), kind));
|
|
10992
12461
|
return this.commit("Corner Kind", drag.before);
|
|
10993
12462
|
}
|
|
10994
12463
|
const ref = drag.widget.ref;
|
|
@@ -11003,7 +12472,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
11003
12472
|
const several = drag.group.length > 0;
|
|
11004
12473
|
if (drag.mode === "copy") this.widthPoints = [drag.ref];
|
|
11005
12474
|
else if (drag.mode === "move" && several) {
|
|
11006
|
-
this.widthPoints = [drag.source, ...drag.group].map((i) => ({ ...drag.ref, index: _nullishCoalesce(_optionalChain([drag, 'access',
|
|
12475
|
+
this.widthPoints = [drag.source, ...drag.group].map((i) => ({ ...drag.ref, index: _nullishCoalesce(_optionalChain([drag, 'access', _345 => _345.renumber, 'optionalAccess', _346 => _346.get, 'call', _347 => _347(i)]), () => ( i)) }));
|
|
11007
12476
|
} else if (!several) this.widthPoints = [drag.ref];
|
|
11008
12477
|
const label = drag.mode === "copy" ? "Copy Width Point" : drag.mode === "move" ? several ? "Move Width Points" : "Move Width Point" : several ? "Width Points" : "Width Point";
|
|
11009
12478
|
return this.commit(label, drag.before);
|
|
@@ -11047,14 +12516,14 @@ var VectorEditorController = (_class5 = class {
|
|
|
11047
12516
|
}
|
|
11048
12517
|
case "pencil": {
|
|
11049
12518
|
const node = this.getNode(drag.nodeId);
|
|
11050
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
12519
|
+
if (_optionalChain([node, 'optionalAccess', _348 => _348.type]) !== "path" || drag.points.length < 2) {
|
|
11051
12520
|
this.doc = drag.before.doc;
|
|
11052
12521
|
this.notify(true);
|
|
11053
12522
|
return;
|
|
11054
12523
|
}
|
|
11055
12524
|
for (const q of drag.lazy.finish()) {
|
|
11056
12525
|
drag.points.push(q);
|
|
11057
|
-
_optionalChain([drag, 'access',
|
|
12526
|
+
_optionalChain([drag, 'access', _349 => _349.pressures, 'optionalAccess', _350 => _350.push, 'call', _351 => _351(drag.pressure)]);
|
|
11058
12527
|
}
|
|
11059
12528
|
const shape = this.editing.recognizeShapes ? recognizeInkShape(drag.points, { minSize: 6 / this.viewport.zoom }) : null;
|
|
11060
12529
|
if (shape) {
|
|
@@ -11129,7 +12598,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
11129
12598
|
this.convertAnchors(a.in || a.out ? "corner" : "smooth", [anchor]);
|
|
11130
12599
|
return;
|
|
11131
12600
|
}
|
|
11132
|
-
const id = _nullishCoalesce(_optionalChain([this, 'access',
|
|
12601
|
+
const id = _nullishCoalesce(_optionalChain([this, 'access', _352 => _352.hover, 'optionalAccess', _353 => _353.segment, 'optionalAccess', _354 => _354.nodeId]), () => ( this.editingId));
|
|
11133
12602
|
if (id) {
|
|
11134
12603
|
const node = this.getNode(id);
|
|
11135
12604
|
const seg = node ? nearestSegment(node, this.toLocal(id, p)) : null;
|
|
@@ -11226,7 +12695,7 @@ var VectorEditorController = (_class5 = class {
|
|
|
11226
12695
|
this.finishPath();
|
|
11227
12696
|
return true;
|
|
11228
12697
|
}
|
|
11229
|
-
if (this.tool === "select" && this.selection.length === 1 && _optionalChain([this, 'access',
|
|
12698
|
+
if (this.tool === "select" && this.selection.length === 1 && _optionalChain([this, 'access', _355 => _355.getNode, 'call', _356 => _356(this.selection[0]), 'optionalAccess', _357 => _357.type]) === "path") {
|
|
11230
12699
|
this.tool = "direct";
|
|
11231
12700
|
this.editingId = this.selection[0];
|
|
11232
12701
|
this.notify();
|
|
@@ -11370,7 +12839,7 @@ function renderNode(stored, defs, idPrefix) {
|
|
|
11370
12839
|
strokeWidth: _nullishCoalesce(node.strokeWidth, () => ( 1)),
|
|
11371
12840
|
...node.strokeLinecap ? { strokeLinecap: node.strokeLinecap } : {},
|
|
11372
12841
|
...node.strokeLinejoin ? { strokeLinejoin: node.strokeLinejoin } : {},
|
|
11373
|
-
..._optionalChain([node, 'access',
|
|
12842
|
+
..._optionalChain([node, 'access', _358 => _358.strokeDasharray, 'optionalAccess', _359 => _359.length]) ? { strokeDasharray: node.strokeDasharray.join(" ") } : {},
|
|
11374
12843
|
fillRule: _nullishCoalesce(node.fillRule, () => ( "nonzero")),
|
|
11375
12844
|
opacity: _nullishCoalesce(node.opacity, () => ( 1))
|
|
11376
12845
|
};
|
|
@@ -11424,11 +12893,11 @@ function getVectorOverlayRenderData(state) {
|
|
|
11424
12893
|
};
|
|
11425
12894
|
for (const id of state.selection) outline(id, true);
|
|
11426
12895
|
if (state.editingId) outline(state.editingId, true);
|
|
11427
|
-
if (_optionalChain([state, 'access',
|
|
12896
|
+
if (_optionalChain([state, 'access', _360 => _360.hover, 'optionalAccess', _361 => _361.nodeId]) && !state.interaction) outline(state.hover.nodeId, false);
|
|
11428
12897
|
let selectionBox = null;
|
|
11429
|
-
if (state.tool === "select" && state.selectionFrame && _optionalChain([state, 'access',
|
|
12898
|
+
if (state.tool === "select" && state.selectionFrame && _optionalChain([state, 'access', _362 => _362.interaction, 'optionalAccess', _363 => _363.type]) !== "marquee" && _optionalChain([state, 'access', _364 => _364.interaction, 'optionalAccess', _365 => _365.type]) !== "distort") {
|
|
11430
12899
|
const g = getVectorSelectionBoxGeometry(state.selectionFrame, state.viewport);
|
|
11431
|
-
selectionBox = { ...g.box, angle: g.angle, transform: g.transform, corners: g.corners, handles: g.handles };
|
|
12900
|
+
selectionBox = { ...g.box, angle: g.angle, transform: g.transform, corners: g.corners, handles: g.handles, freeDistort: state.freeDistort };
|
|
11432
12901
|
}
|
|
11433
12902
|
const selected = (r) => state.selectedAnchors.some((a) => a.nodeId === r.nodeId && a.subpath === r.subpath && a.index === r.index);
|
|
11434
12903
|
const sameAnchor = (a, b) => !!a && a.nodeId === b.nodeId && a.subpath === b.subpath && a.index === b.index;
|
|
@@ -11436,9 +12905,9 @@ function getVectorOverlayRenderData(state) {
|
|
|
11436
12905
|
const a = getAnchorWorld(doc, ref);
|
|
11437
12906
|
const s = toScreen(state, a);
|
|
11438
12907
|
const closes = !!state.pen && state.pen.nodeId === ref.nodeId && state.pen.subpath === ref.subpath && ref.index === 0;
|
|
11439
|
-
return { ref, x: s.x, y: s.y, type: _nullishCoalesce(a.type, () => ( inferAnchorType(a))), selected: selected(ref), hovered: sameAnchor(_optionalChain([state, 'access',
|
|
12908
|
+
return { ref, x: s.x, y: s.y, type: _nullishCoalesce(a.type, () => ( inferAnchorType(a))), selected: selected(ref), hovered: sameAnchor(_optionalChain([state, 'access', _366 => _366.hover, 'optionalAccess', _367 => _367.anchor]), ref), closes };
|
|
11440
12909
|
});
|
|
11441
|
-
if (state.tool === "pen" && !state.pen && _optionalChain([state, 'access',
|
|
12910
|
+
if (state.tool === "pen" && !state.pen && _optionalChain([state, 'access', _368 => _368.hover, 'optionalAccess', _369 => _369.anchor])) {
|
|
11442
12911
|
const a = getAnchorWorld(doc, state.hover.anchor);
|
|
11443
12912
|
if (a) {
|
|
11444
12913
|
const s = toScreen(state, a);
|
|
@@ -11447,15 +12916,15 @@ function getVectorOverlayRenderData(state) {
|
|
|
11447
12916
|
}
|
|
11448
12917
|
const handles = getVisibleHandles(state).flatMap((ref) => {
|
|
11449
12918
|
const a = getAnchorWorld(doc, ref);
|
|
11450
|
-
const h = _optionalChain([a, 'optionalAccess',
|
|
12919
|
+
const h = _optionalChain([a, 'optionalAccess', _370 => _370[ref.handle]]);
|
|
11451
12920
|
if (!a || !h) return [];
|
|
11452
12921
|
const s = toScreen(state, h);
|
|
11453
12922
|
const sa = toScreen(state, a);
|
|
11454
|
-
const hovered = !!_optionalChain([state, 'access',
|
|
12923
|
+
const hovered = !!_optionalChain([state, 'access', _371 => _371.hover, 'optionalAccess', _372 => _372.handle]) && sameAnchor(state.hover.handle, ref) && state.hover.handle.handle === ref.handle;
|
|
11455
12924
|
return [{ ref, x: s.x, y: s.y, anchorX: sa.x, anchorY: sa.y, hovered }];
|
|
11456
12925
|
});
|
|
11457
12926
|
let marquee = null;
|
|
11458
|
-
if (_optionalChain([state, 'access',
|
|
12927
|
+
if (_optionalChain([state, 'access', _373 => _373.interaction, 'optionalAccess', _374 => _374.type]) === "marquee") {
|
|
11459
12928
|
const b = state.interaction.bounds;
|
|
11460
12929
|
const tl = toScreen(state, b);
|
|
11461
12930
|
marquee = { x: tl.x, y: tl.y, width: b.width * z, height: b.height * z };
|
|
@@ -11463,7 +12932,7 @@ function getVectorOverlayRenderData(state) {
|
|
|
11463
12932
|
let penPreview = null;
|
|
11464
12933
|
if (state.tool === "pen" && state.pen && state.pointer && !state.interaction) {
|
|
11465
12934
|
const node = findVectorNode(doc.nodes, state.pen.nodeId);
|
|
11466
|
-
const sp = _optionalChain([node, 'optionalAccess',
|
|
12935
|
+
const sp = _optionalChain([node, 'optionalAccess', _375 => _375.type]) === "path" ? node.subpaths[state.pen.subpath] : void 0;
|
|
11467
12936
|
const last = sp ? getAnchorWorld(doc, { nodeId: state.pen.nodeId, subpath: state.pen.subpath, index: sp.anchors.length - 1 }) : void 0;
|
|
11468
12937
|
if (last) {
|
|
11469
12938
|
const a = toScreen(state, last);
|
|
@@ -11476,9 +12945,9 @@ function getVectorOverlayRenderData(state) {
|
|
|
11476
12945
|
const artboard = { x: origin.x, y: origin.y, width: doc.width * z, height: doc.height * z };
|
|
11477
12946
|
let status = null;
|
|
11478
12947
|
const it = state.interaction;
|
|
11479
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
11480
|
-
else if (_optionalChain([it, 'optionalAccess',
|
|
11481
|
-
else if (_optionalChain([it, 'optionalAccess',
|
|
12948
|
+
if (_optionalChain([it, 'optionalAccess', _376 => _376.type]) === "rotate") status = `${Math.round(it.angle)}\xB0`;
|
|
12949
|
+
else if (_optionalChain([it, 'optionalAccess', _377 => _377.type]) === "move" || _optionalChain([it, 'optionalAccess', _378 => _378.type]) === "anchors") status = `\u0394 ${fmt4(it.dx)}, ${fmt4(it.dy)}`;
|
|
12950
|
+
else if (_optionalChain([it, 'optionalAccess', _379 => _379.type]) === "scale" || _optionalChain([it, 'optionalAccess', _380 => _380.type]) === "draw") {
|
|
11482
12951
|
const b = it.type === "draw" ? findVectorNode(doc.nodes, it.nodeId) ? vectorNodeBounds(findVectorNode(doc.nodes, it.nodeId)) : null : state.selectionFrame;
|
|
11483
12952
|
if (b) status = `W ${fmt4(b.width)} \xD7 H ${fmt4(b.height)}`;
|
|
11484
12953
|
}
|
|
@@ -11495,24 +12964,24 @@ function getVectorOverlayRenderData(state) {
|
|
|
11495
12964
|
}
|
|
11496
12965
|
}
|
|
11497
12966
|
let toolStroke = null;
|
|
11498
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
12967
|
+
if (_optionalChain([it, 'optionalAccess', _381 => _381.type]) === "stroke") {
|
|
11499
12968
|
const pts = it.points.map((q) => toScreen(state, q));
|
|
11500
12969
|
const d = pts.map((q, i) => `${i ? "L" : "M"}${fmt4(q.x)} ${fmt4(q.y)}`).join("") + (pts.length === 1 ? `L${fmt4(pts[0].x)} ${fmt4(pts[0].y)}` : "");
|
|
11501
12970
|
toolStroke = { tool: it.tool, d, width: fmt4(it.width * z) };
|
|
11502
12971
|
}
|
|
11503
12972
|
let pencilString = null;
|
|
11504
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
12973
|
+
if (_optionalChain([it, 'optionalAccess', _382 => _382.type]) === "draw" && it.string) {
|
|
11505
12974
|
const a = toScreen(state, it.string[0]);
|
|
11506
12975
|
const b = toScreen(state, it.string[1]);
|
|
11507
12976
|
pencilString = { x1: fmt4(a.x), y1: fmt4(a.y), x2: fmt4(b.x), y2: fmt4(b.y) };
|
|
11508
12977
|
}
|
|
11509
|
-
const dragged = _optionalChain([it, 'optionalAccess',
|
|
12978
|
+
const dragged = _optionalChain([it, 'optionalAccess', _383 => _383.type]) === "corner" ? it.ref : null;
|
|
11510
12979
|
const cornerWidgets = getVectorCornerWidgets(state).map((w) => {
|
|
11511
12980
|
const s = toScreen(state, w);
|
|
11512
|
-
return { ref: w.ref, x: fmt4(s.x), y: fmt4(s.y), radius: w.radius, kind: w.kind, hovered: sameAnchor(_optionalChain([state, 'access',
|
|
12981
|
+
return { ref: w.ref, x: fmt4(s.x), y: fmt4(s.y), radius: w.radius, kind: w.kind, hovered: sameAnchor(_optionalChain([state, 'access', _384 => _384.hover, 'optionalAccess', _385 => _385.corner]), w.ref), active: !!dragged };
|
|
11513
12982
|
});
|
|
11514
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
11515
|
-
const cutPoint = state.tool === "scissors" && _optionalChain([state, 'access',
|
|
12983
|
+
if (_optionalChain([it, 'optionalAccess', _386 => _386.type]) === "corner") status = `R ${fmt4(it.radius)}`;
|
|
12984
|
+
const cutPoint = state.tool === "scissors" && _optionalChain([state, 'access', _387 => _387.hover, 'optionalAccess', _388 => _388.segment]) && !it ? (({ x, y }) => ({ x: fmt4(x), y: fmt4(y) }))(toScreen(state, state.hover.segment.point)) : null;
|
|
11516
12985
|
const sc = (p) => {
|
|
11517
12986
|
const q = toScreen(state, p);
|
|
11518
12987
|
return { x: fmt4(q.x), y: fmt4(q.y) };
|
|
@@ -11520,13 +12989,13 @@ function getVectorOverlayRenderData(state) {
|
|
|
11520
12989
|
const sameWidth = (a, b) => !!a && a.nodeId === b.nodeId && a.index === b.index;
|
|
11521
12990
|
const widthPoints = getVectorWidthHandles(state).map((h) => {
|
|
11522
12991
|
const c = sc(h);
|
|
11523
|
-
const hw = _optionalChain([state, 'access',
|
|
12992
|
+
const hw = _optionalChain([state, 'access', _389 => _389.hover, 'optionalAccess', _390 => _390.widthPoint]);
|
|
11524
12993
|
const hovered = hw && sameWidth(hw, h.ref) && hw.subpath === h.ref.subpath ? hw.part : null;
|
|
11525
|
-
return { ref: h.ref, x: c.x, y: c.y, left: sc(h.left), right: sc(h.right), selected: h.selected, hovered, active: _optionalChain([it, 'optionalAccess',
|
|
12994
|
+
return { ref: h.ref, x: c.x, y: c.y, left: sc(h.left), right: sc(h.right), selected: h.selected, hovered, active: _optionalChain([it, 'optionalAccess', _391 => _391.type]) === "width" && sameWidth(it.ref, h.ref) };
|
|
11526
12995
|
});
|
|
11527
|
-
const spot = state.tool === "width" && !it ? _optionalChain([state, 'access',
|
|
12996
|
+
const spot = state.tool === "width" && !it ? _optionalChain([state, 'access', _392 => _392.hover, 'optionalAccess', _393 => _393.strokeSpot]) : null;
|
|
11528
12997
|
const widthSpot = spot ? { ...sc(spot.point), left: sc(spot.left), right: sc(spot.right) } : null;
|
|
11529
|
-
if (_optionalChain([it, 'optionalAccess',
|
|
12998
|
+
if (_optionalChain([it, 'optionalAccess', _394 => _394.type]) === "width") status = it.mode === "move" ? "Move width point" : it.mode === "copy" ? "Copy width point" : `W ${fmt4(it.width)}`;
|
|
11530
12999
|
let builder = null;
|
|
11531
13000
|
if (state.builder) {
|
|
11532
13001
|
const v2 = state.viewport;
|
|
@@ -11542,7 +13011,7 @@ function getVectorOverlayRenderData(state) {
|
|
|
11542
13011
|
lines: state.builder.lines.map((l) => svg(_chunkVNYRI265cjs.transformBezierPath.call(void 0, l, view))),
|
|
11543
13012
|
trail
|
|
11544
13013
|
};
|
|
11545
|
-
if (state.builder.mode !== "fill" && _optionalChain([it, 'optionalAccess',
|
|
13014
|
+
if (state.builder.mode !== "fill" && _optionalChain([it, 'optionalAccess', _395 => _395.type]) === "builder") {
|
|
11546
13015
|
const n = state.builder.faces.length;
|
|
11547
13016
|
status = state.builder.mode === "erase" ? `Delete ${n} ${n === 1 ? "face" : "faces"}` : `Merge ${n} ${n === 1 ? "face" : "faces"}`;
|
|
11548
13017
|
}
|
|
@@ -11553,18 +13022,72 @@ function getVectorOverlayRenderData(state) {
|
|
|
11553
13022
|
if (state.tool === "gradient") {
|
|
11554
13023
|
gradient = gradientOverlay(state);
|
|
11555
13024
|
if (!gradient && !it) status = "Drag across a shape to set a gradient";
|
|
11556
|
-
else if (_optionalChain([it, 'optionalAccess',
|
|
13025
|
+
else if (_optionalChain([it, 'optionalAccess', _396 => _396.type]) === "gradient" && it.removing) status = "Release to delete the stop";
|
|
11557
13026
|
}
|
|
11558
|
-
|
|
13027
|
+
let distort = null;
|
|
13028
|
+
if (_optionalChain([it, 'optionalAccess', _397 => _397.type]) === "distort") {
|
|
13029
|
+
const corners2 = it.corners.map(sc);
|
|
13030
|
+
distort = { mode: it.mode, corners: corners2, d: corners2.map((c, i) => `${i ? "L" : "M"}${c.x} ${c.y}`).join("") + "Z" };
|
|
13031
|
+
status = it.mode === "skew" ? "Skew" : it.mode === "perspective" ? "Perspective" : "Distort";
|
|
13032
|
+
}
|
|
13033
|
+
const envelope = state.tool === "envelope" ? envelopeOverlay(state) : null;
|
|
13034
|
+
if (state.tool === "envelope" && !envelope && !it) status = "Select an object with an envelope to edit its mesh";
|
|
13035
|
+
return { outlines, selectionBox, distort, anchors, handles, marquee, penPreview, artboard, guides, status, toolStroke, pencilString, cutPoint, cornerWidgets, widthPoints, widthSpot, builder, blend, gradient, envelope };
|
|
13036
|
+
}
|
|
13037
|
+
function envelopeOverlay(state) {
|
|
13038
|
+
const target = getVectorEnvelopeTarget(state.document, state.selection);
|
|
13039
|
+
if (!target) return null;
|
|
13040
|
+
const v2 = state.viewport;
|
|
13041
|
+
const m = multiplyMatrices(target.world, [v2.zoom, 0, 0, v2.zoom, v2.x, v2.y]);
|
|
13042
|
+
const sc = (p) => ({ x: fmt4(m[0] * p.x + m[2] * p.y + m[4]), y: fmt4(m[1] * p.x + m[3] * p.y + m[5]) });
|
|
13043
|
+
const { mesh } = target.frame;
|
|
13044
|
+
const grid = vectorMeshGridCurves(mesh).map((c) => {
|
|
13045
|
+
const [a, b, cc, d] = c.map(sc);
|
|
13046
|
+
return `M${a.x} ${a.y}C${b.x} ${b.y} ${cc.x} ${cc.y} ${d.x} ${d.y}`;
|
|
13047
|
+
}).join("");
|
|
13048
|
+
const hover = _optionalChain([state, 'access', _398 => _398.hover, 'optionalAccess', _399 => _399.envelope, 'optionalAccess', _400 => _400.nodeId]) === target.node.id ? state.hover.envelope.index : void 0;
|
|
13049
|
+
const it = state.interaction;
|
|
13050
|
+
const active = _optionalChain([it, 'optionalAccess', _401 => _401.type]) === "envelope" && it.nodeId === target.node.id ? it.index : void 0;
|
|
13051
|
+
const pts = vectorMeshEditPoints(mesh);
|
|
13052
|
+
return {
|
|
13053
|
+
nodeId: target.node.id,
|
|
13054
|
+
grid,
|
|
13055
|
+
anchors: pts.anchors.map((index) => ({ index, ...sc(mesh.points[index]), hovered: !it && hover === index, active: active === index })),
|
|
13056
|
+
handles: pts.handles.map((h) => {
|
|
13057
|
+
const a = sc(mesh.points[h.anchor]);
|
|
13058
|
+
return { index: h.index, ...sc(mesh.points[h.index]), anchorX: a.x, anchorY: a.y, hovered: !it && hover === h.index, active: active === h.index };
|
|
13059
|
+
})
|
|
13060
|
+
};
|
|
13061
|
+
}
|
|
13062
|
+
var VECTOR_ENVELOPE_STYLE_OPTIONS = [
|
|
13063
|
+
...VECTOR_WARP_STYLES.map((value) => ({ value, label: VECTOR_WARP_STYLE_LABELS[value] })),
|
|
13064
|
+
{ value: "mesh", label: "Mesh" }
|
|
13065
|
+
];
|
|
13066
|
+
function getVectorEnvelopePanel(state) {
|
|
13067
|
+
const nodes = state.selection.map((id) => findVectorNode(state.document.nodes, id)).filter((n) => !!n && !n.blendStep);
|
|
13068
|
+
if (!nodes.length) return null;
|
|
13069
|
+
const one = nodes.length === 1 ? nodes[0] : null;
|
|
13070
|
+
const first = _optionalChain([one, 'optionalAccess', _402 => _402.effects, 'optionalAccess', _403 => _403.find, 'call', _404 => _404((e) => e.type === "envelope")]);
|
|
13071
|
+
const order = /* @__PURE__ */ new Map();
|
|
13072
|
+
walkVectorNodes(state.document.nodes, (n) => order.set(n.id, order.size));
|
|
13073
|
+
const top = nodes.length > 1 ? nodes.slice().sort((a, b) => (_nullishCoalesce(order.get(a.id), () => ( 0))) - (_nullishCoalesce(order.get(b.id), () => ( 0))))[nodes.length - 1] : null;
|
|
13074
|
+
return {
|
|
13075
|
+
nodeId: _nullishCoalesce(_optionalChain([one, 'optionalAccess', _405 => _405.id]), () => ( null)),
|
|
13076
|
+
count: nodes.length,
|
|
13077
|
+
envelope: _optionalChain([first, 'optionalAccess', _406 => _406.type]) === "envelope" ? { effectId: first.id, enabled: first.enabled !== false, params: first.params } : null,
|
|
13078
|
+
canMake: nodes.some((n) => !n.locked),
|
|
13079
|
+
canMakeWithTopObject: _optionalChain([top, 'optionalAccess', _407 => _407.type]) === "path" && top.subpaths.some((sp) => sp.closed && sp.anchors.length > 1),
|
|
13080
|
+
canRelease: nodes.some((n) => !n.locked && !!_optionalChain([n, 'access', _408 => _408.effects, 'optionalAccess', _409 => _409.some, 'call', _410 => _410((e) => e.type === "envelope")]))
|
|
13081
|
+
};
|
|
11559
13082
|
}
|
|
11560
13083
|
function gradientOverlay(state) {
|
|
11561
13084
|
const a = getVectorGradientAnnotator(state.document, state.selection, state.viewport, state.gradientEdit.target);
|
|
11562
13085
|
if (!a) return null;
|
|
11563
|
-
const hover = state.interaction ? null : _optionalChain([state, 'access',
|
|
11564
|
-
const handleHovered = (h) => _optionalChain([hover, 'optionalAccess',
|
|
13086
|
+
const hover = state.interaction ? null : _optionalChain([state, 'access', _411 => _411.hover, 'optionalAccess', _412 => _412.gradient]);
|
|
13087
|
+
const handleHovered = (h) => _optionalChain([hover, 'optionalAccess', _413 => _413.kind]) === "handle" && hover.handle === h;
|
|
11565
13088
|
const pt2 = (p) => ({ x: fmt4(p.x), y: fmt4(p.y) });
|
|
11566
13089
|
const centred = isCentredVectorGradient(a.gradient.type);
|
|
11567
|
-
const removing = _optionalChain([state, 'access',
|
|
13090
|
+
const removing = _optionalChain([state, 'access', _414 => _414.interaction, 'optionalAccess', _415 => _415.type]) === "gradient" && !!state.interaction.removing;
|
|
11568
13091
|
return {
|
|
11569
13092
|
nodeId: a.nodeId,
|
|
11570
13093
|
type: a.gradient.type,
|
|
@@ -11580,9 +13103,9 @@ function gradientOverlay(state) {
|
|
|
11580
13103
|
color: s.color,
|
|
11581
13104
|
opacity: _nullishCoalesce(s.opacity, () => ( 1)),
|
|
11582
13105
|
selected: state.gradientEdit.stop === s.index,
|
|
11583
|
-
hovered: _optionalChain([hover, 'optionalAccess',
|
|
13106
|
+
hovered: _optionalChain([hover, 'optionalAccess', _416 => _416.kind]) === "stop" && hover.index === s.index
|
|
11584
13107
|
})),
|
|
11585
|
-
midpoints: a.midpoints.map((m) => ({ index: m.index, ...pt2(m), hovered: _optionalChain([hover, 'optionalAccess',
|
|
13108
|
+
midpoints: a.midpoints.map((m) => ({ index: m.index, ...pt2(m), hovered: _optionalChain([hover, 'optionalAccess', _417 => _417.kind]) === "midpoint" && hover.index === m.index })),
|
|
11586
13109
|
extent: a.extent,
|
|
11587
13110
|
removing
|
|
11588
13111
|
};
|
|
@@ -11591,7 +13114,7 @@ function selectedBlends(state) {
|
|
|
11591
13114
|
const out = /* @__PURE__ */ new Map();
|
|
11592
13115
|
for (const id of state.selection) {
|
|
11593
13116
|
const node = findVectorNode(state.document.nodes, id);
|
|
11594
|
-
const group = isVectorBlendGroup(node) ? node : _optionalChain([locateVectorNode, 'call',
|
|
13117
|
+
const group = isVectorBlendGroup(node) ? node : _optionalChain([locateVectorNode, 'call', _418 => _418(state.document.nodes, id), 'optionalAccess', _419 => _419.parent]);
|
|
11595
13118
|
if (isVectorBlendGroup(group)) out.set(group.id, group);
|
|
11596
13119
|
}
|
|
11597
13120
|
return [...out.values()];
|
|
@@ -11623,11 +13146,11 @@ function blendOverlay(state) {
|
|
|
11623
13146
|
const a = state.blendStart.anchor === null ? void 0 : getAnchorWorld(doc, { nodeId: from.id, subpath: 0, index: state.blendStart.anchor });
|
|
11624
13147
|
start = { d: screenOutline(state, from, /* @__PURE__ */ new Set()), anchor: a ? sc(a, view) : null };
|
|
11625
13148
|
}
|
|
11626
|
-
const hovered = _optionalChain([state, 'access',
|
|
11627
|
-
if (_optionalChain([hovered, 'optionalAccess',
|
|
13149
|
+
const hovered = _optionalChain([state, 'access', _420 => _420.hover, 'optionalAccess', _421 => _421.nodeId]) ? findVectorNode(doc.nodes, state.hover.nodeId) : void 0;
|
|
13150
|
+
if (_optionalChain([hovered, 'optionalAccess', _422 => _422.type]) === "path" && hovered.subpaths[0]) {
|
|
11628
13151
|
hovered.subpaths[0].anchors.forEach((_, index) => {
|
|
11629
13152
|
const a = getAnchorWorld(doc, { nodeId: hovered.id, subpath: 0, index });
|
|
11630
|
-
if (a) anchors.push({ ...sc(a, view), hovered: _optionalChain([state, 'access',
|
|
13153
|
+
if (a) anchors.push({ ...sc(a, view), hovered: _optionalChain([state, 'access', _423 => _423.hover, 'optionalAccess', _424 => _424.anchor, 'optionalAccess', _425 => _425.index]) === index });
|
|
11631
13154
|
});
|
|
11632
13155
|
}
|
|
11633
13156
|
}
|
|
@@ -11638,17 +13161,17 @@ function getVectorBlendControls(state) {
|
|
|
11638
13161
|
const doc = state.document;
|
|
11639
13162
|
const roots = state.selection.filter((id) => {
|
|
11640
13163
|
const node = findVectorNode(doc.nodes, id);
|
|
11641
|
-
return !!node && !node.blendStep && !node.locked && !state.selection.includes(_nullishCoalesce(_optionalChain([locateVectorNode, 'call',
|
|
13164
|
+
return !!node && !node.blendStep && !node.locked && !state.selection.includes(_nullishCoalesce(_optionalChain([locateVectorNode, 'call', _426 => _426(doc.nodes, id), 'optionalAccess', _427 => _427.parent, 'optionalAccess', _428 => _428.id]), () => ( "")));
|
|
11642
13165
|
});
|
|
11643
|
-
const parents = new Set(roots.map((id) => _nullishCoalesce(_optionalChain([locateVectorNode, 'call',
|
|
11644
|
-
const paths = roots.filter((id) => _optionalChain([findVectorNode, 'call',
|
|
13166
|
+
const parents = new Set(roots.map((id) => _nullishCoalesce(_optionalChain([locateVectorNode, 'call', _429 => _429(doc.nodes, id), 'optionalAccess', _430 => _430.parent, 'optionalAccess', _431 => _431.id]), () => ( null))));
|
|
13167
|
+
const paths = roots.filter((id) => _optionalChain([findVectorNode, 'call', _432 => _432(doc.nodes, id), 'optionalAccess', _433 => _433.type]) === "path" && !isVectorBlendGroup(_optionalChain([locateVectorNode, 'call', _434 => _434(doc.nodes, id), 'optionalAccess', _435 => _435.parent])));
|
|
11645
13168
|
const first = blends[0];
|
|
11646
13169
|
return {
|
|
11647
13170
|
ids: blends.map((g) => g.id),
|
|
11648
13171
|
options: resolveVectorBlendOptions(first ? first.blend : state.blendDefaults),
|
|
11649
13172
|
canBlend: roots.length >= 2 && parents.size === 1,
|
|
11650
13173
|
canReplaceSpine: blends.length === 1 && paths.length === 1,
|
|
11651
|
-
hasSpine: !!_optionalChain([first, 'optionalAccess',
|
|
13174
|
+
hasSpine: !!_optionalChain([first, 'optionalAccess', _436 => _436.blend, 'optionalAccess', _437 => _437.spine])
|
|
11652
13175
|
};
|
|
11653
13176
|
}
|
|
11654
13177
|
function applyVectorBlendOptions(controller, patch) {
|
|
@@ -11701,7 +13224,7 @@ function isVectorTextTarget(target) {
|
|
|
11701
13224
|
if (!el || typeof el !== "object") return false;
|
|
11702
13225
|
const tag = (_nullishCoalesce(el.tagName, () => ( ""))).toUpperCase();
|
|
11703
13226
|
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
11704
|
-
return !!el.isContentEditable || _optionalChain([el, 'access',
|
|
13227
|
+
return !!el.isContentEditable || _optionalChain([el, 'access', _438 => _438.getAttribute, 'optionalCall', _439 => _439("contenteditable")]) === "true";
|
|
11705
13228
|
}
|
|
11706
13229
|
function getVectorSelectionStyle(state) {
|
|
11707
13230
|
const paths = [];
|
|
@@ -11709,23 +13232,23 @@ function getVectorSelectionStyle(state) {
|
|
|
11709
13232
|
const node = findVectorNode(state.document.nodes, id);
|
|
11710
13233
|
if (node) paths.push(...collect(node));
|
|
11711
13234
|
}
|
|
11712
|
-
const anchorMode = state.tool === "direct" && !!_optionalChain([state, 'access',
|
|
13235
|
+
const anchorMode = state.tool === "direct" && !!_optionalChain([state, 'access', _440 => _440.selectedAnchors, 'optionalAccess', _441 => _441.length]);
|
|
11713
13236
|
if (anchorMode) {
|
|
11714
13237
|
for (const r of state.selectedAnchors) {
|
|
11715
13238
|
if (paths.some((p) => p.id === r.nodeId)) continue;
|
|
11716
13239
|
const node = findVectorNode(state.document.nodes, r.nodeId);
|
|
11717
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
13240
|
+
if (_optionalChain([node, 'optionalAccess', _442 => _442.type]) === "path") paths.push(node);
|
|
11718
13241
|
}
|
|
11719
13242
|
}
|
|
11720
13243
|
if (!paths.length) return null;
|
|
11721
13244
|
const first = paths[0];
|
|
11722
|
-
const
|
|
13245
|
+
const same2 = (get) => paths.every((p) => JSON.stringify(_nullishCoalesce(get(p), () => ( null))) === JSON.stringify(_nullishCoalesce(get(first), () => ( null))));
|
|
11723
13246
|
const corners2 = [];
|
|
11724
13247
|
for (const p of paths) {
|
|
11725
13248
|
for (const c of vectorCorners(p.subpaths)) {
|
|
11726
13249
|
if (anchorMode && !state.selectedAnchors.some((r) => r.nodeId === p.id && r.subpath === c.subpath && r.index === c.index)) continue;
|
|
11727
13250
|
const corner = p.subpaths[c.subpath].anchors[c.index].corner;
|
|
11728
|
-
corners2.push({ radius: _nullishCoalesce(_optionalChain([corner, 'optionalAccess',
|
|
13251
|
+
corners2.push({ radius: _nullishCoalesce(_optionalChain([corner, 'optionalAccess', _443 => _443.radius]), () => ( 0)), kind: _nullishCoalesce(_optionalChain([corner, 'optionalAccess', _444 => _444.kind]), () => ( "round")) });
|
|
11729
13252
|
}
|
|
11730
13253
|
}
|
|
11731
13254
|
const c0 = _nullishCoalesce(corners2[0], () => ( { radius: 0, kind: "round" }));
|
|
@@ -11747,17 +13270,17 @@ function getVectorSelectionStyle(state) {
|
|
|
11747
13270
|
corners: corners2.length,
|
|
11748
13271
|
hasOpenPath: paths.some((p) => p.subpaths.some((sp) => !sp.closed && sp.anchors.length > 1)),
|
|
11749
13272
|
mixed: {
|
|
11750
|
-
fill: !
|
|
11751
|
-
stroke: !
|
|
11752
|
-
strokeWidth: !
|
|
11753
|
-
opacity: !
|
|
11754
|
-
strokeAlign: !
|
|
11755
|
-
startArrow: !
|
|
11756
|
-
endArrow: !
|
|
11757
|
-
arrowAlign: !
|
|
11758
|
-
startArrowScale: !
|
|
11759
|
-
endArrowScale: !
|
|
11760
|
-
widthProfile: !
|
|
13273
|
+
fill: !same2((p) => p.fill),
|
|
13274
|
+
stroke: !same2((p) => p.stroke),
|
|
13275
|
+
strokeWidth: !same2((p) => _nullishCoalesce(p.strokeWidth, () => ( 1))),
|
|
13276
|
+
opacity: !same2((p) => _nullishCoalesce(p.opacity, () => ( 1))),
|
|
13277
|
+
strokeAlign: !same2((p) => _nullishCoalesce(p.strokeAlign, () => ( "center"))),
|
|
13278
|
+
startArrow: !same2((p) => _nullishCoalesce(p.startArrow, () => ( null))),
|
|
13279
|
+
endArrow: !same2((p) => _nullishCoalesce(p.endArrow, () => ( null))),
|
|
13280
|
+
arrowAlign: !same2((p) => _nullishCoalesce(p.arrowAlign, () => ( "extend"))),
|
|
13281
|
+
startArrowScale: !same2((p) => _nullishCoalesce(p.startArrowScale, () => ( 1))),
|
|
13282
|
+
endArrowScale: !same2((p) => _nullishCoalesce(p.endArrowScale, () => ( 1))),
|
|
13283
|
+
widthProfile: !same2(profileOf),
|
|
11761
13284
|
cornerRadius: corners2.some((c) => c.radius !== c0.radius),
|
|
11762
13285
|
cornerKind: corners2.some((c) => c.kind !== c0.kind)
|
|
11763
13286
|
},
|
|
@@ -11805,7 +13328,7 @@ function getVectorGradientEditor(state) {
|
|
|
11805
13328
|
const sel = stopIndex !== null && sorted[stopIndex] ? { ...sorted[stopIndex], index: stopIndex, last: stopIndex === sorted.length - 1 } : null;
|
|
11806
13329
|
const preview = gradient ? `linear-gradient(to right, ${expandVectorGradientStops(gradient).map((s) => {
|
|
11807
13330
|
const c = parseVectorColor(s.color);
|
|
11808
|
-
const a = (_nullishCoalesce(_optionalChain([c, 'optionalAccess',
|
|
13331
|
+
const a = (_nullishCoalesce(_optionalChain([c, 'optionalAccess', _445 => _445[3]]), () => ( 1))) * (_nullishCoalesce(s.opacity, () => ( 1)));
|
|
11809
13332
|
const color = c ? `rgba(${Math.round(c[0] * 255)}, ${Math.round(c[1] * 255)}, ${Math.round(c[2] * 255)}, ${Math.round(a * 1e3) / 1e3})` : s.color;
|
|
11810
13333
|
return `${color} ${Math.round(s.offset * 1e4) / 100}%`;
|
|
11811
13334
|
}).join(", ")})` : null;
|
|
@@ -11816,11 +13339,11 @@ function getVectorGradientEditor(state) {
|
|
|
11816
13339
|
stops,
|
|
11817
13340
|
selected: sel,
|
|
11818
13341
|
preview,
|
|
11819
|
-
type: _nullishCoalesce(_optionalChain([gradient, 'optionalAccess',
|
|
11820
|
-
spread: _nullishCoalesce(_optionalChain([gradient, 'optionalAccess',
|
|
11821
|
-
interpolation: _nullishCoalesce(_optionalChain([gradient, 'optionalAccess',
|
|
11822
|
-
smoothness: _nullishCoalesce(_optionalChain([gradient, 'optionalAccess',
|
|
11823
|
-
strokeMode: _nullishCoalesce(_optionalChain([gradient, 'optionalAccess',
|
|
13342
|
+
type: _nullishCoalesce(_optionalChain([gradient, 'optionalAccess', _446 => _446.type]), () => ( null)),
|
|
13343
|
+
spread: _nullishCoalesce(_optionalChain([gradient, 'optionalAccess', _447 => _447.spread]), () => ( "pad")),
|
|
13344
|
+
interpolation: _nullishCoalesce(_optionalChain([gradient, 'optionalAccess', _448 => _448.interpolation]), () => ( "srgb")),
|
|
13345
|
+
smoothness: _nullishCoalesce(_optionalChain([gradient, 'optionalAccess', _449 => _449.smoothness]), () => ( 0)),
|
|
13346
|
+
strokeMode: _nullishCoalesce(_optionalChain([gradient, 'optionalAccess', _450 => _450.strokeMode]), () => ( "within")),
|
|
11824
13347
|
mixed: paths.some((p) => JSON.stringify(_nullishCoalesce(p[target], () => ( null))) !== JSON.stringify(_nullishCoalesce(paint, () => ( null))))
|
|
11825
13348
|
};
|
|
11826
13349
|
}
|
|
@@ -11851,22 +13374,23 @@ function getVectorEffectsPanel(state) {
|
|
|
11851
13374
|
if (!nodes.length) return null;
|
|
11852
13375
|
const one = nodes.length === 1 ? nodes[0] : null;
|
|
11853
13376
|
return {
|
|
11854
|
-
nodeId: _nullishCoalesce(_optionalChain([one, 'optionalAccess',
|
|
13377
|
+
nodeId: _nullishCoalesce(_optionalChain([one, 'optionalAccess', _451 => _451.id]), () => ( null)),
|
|
11855
13378
|
count: nodes.length,
|
|
11856
|
-
effects: (_nullishCoalesce(_optionalChain([one, 'optionalAccess',
|
|
13379
|
+
effects: (_nullishCoalesce(_optionalChain([one, 'optionalAccess', _452 => _452.effects]), () => ( []))).map((e) => ({
|
|
11857
13380
|
id: e.id,
|
|
11858
13381
|
type: e.type,
|
|
11859
13382
|
label: _nullishCoalesce(VECTOR_EFFECT_LABELS[e.type], () => ( e.type)),
|
|
11860
13383
|
enabled: e.enabled !== false,
|
|
11861
13384
|
params: e.params,
|
|
11862
|
-
|
|
13385
|
+
// The Envelope panel (`getVectorEnvelopePanel`) edits an envelope's warp and mesh.
|
|
13386
|
+
specs: e.type === "envelope" ? [] : _nullishCoalesce(VECTOR_EFFECT_PARAM_SPECS[e.type], () => ( []))
|
|
11863
13387
|
})),
|
|
11864
13388
|
expandable: nodes.some(hasVectorAppearance)
|
|
11865
13389
|
};
|
|
11866
13390
|
}
|
|
11867
13391
|
|
|
11868
13392
|
// src/vector/commands.ts
|
|
11869
|
-
var EFFECT_PARAMS_DESCRIPTION = "Effect parameters (missing ones keep their value or default). trim: start, end (percent), offset (degrees), mode simultaneous|individual. roundCorners: radius. puckerBloat: amount (\u2212100\u2026100). twist: angle, center {x, y} (offset from the middle). zigzag: size, ridges, smooth. wiggle: size, detail, smooth, speed, correlation, phase, seed, time (seconds). offset: amount, join miter|round|bevel, miterLimit, copies, copyOffset. merge: mode merge|add|subtract|intersect|exclude. repeater: copies (fractions fade the last), offset, position {x, y}, anchor {x, y} (offset from the middle), rotation, scale {x, y} (percent), startOpacity, endOpacity (percent), composite below|above.";
|
|
13393
|
+
var EFFECT_PARAMS_DESCRIPTION = "Effect parameters (missing ones keep their value or default). trim: start, end (percent), offset (degrees), mode simultaneous|individual. roundCorners: radius. puckerBloat: amount (\u2212100\u2026100). twist: angle, center {x, y} (offset from the middle). zigzag: size, ridges, smooth. wiggle: size, detail, smooth, speed, correlation, phase, seed, time (seconds). offset: amount, join miter|round|bevel, miterLimit, copies, copyOffset. merge: mode merge|add|subtract|intersect|exclude. repeater: copies (fractions fade the last), offset, position {x, y}, anchor {x, y} (offset from the middle), rotation, scale {x, y} (percent), startOpacity, endOpacity (percent), composite below|above. envelope: style (a warp preset: arc|arcLower|arcUpper|arch|bulge|shellLower|shellUpper|flag|wave|fish|rise|fisheye|inflate|squeeze|twist, or mesh), bend, horizontal, vertical (percent, \u2212100\u2026100), orientation horizontal|vertical, rows, columns, mesh { us, vs, points } (node space; prefer vector.envelope).";
|
|
11870
13394
|
var fail = (message) => {
|
|
11871
13395
|
throw new Error(message);
|
|
11872
13396
|
};
|
|
@@ -11907,9 +13431,9 @@ var BLEND_PROPS = {
|
|
|
11907
13431
|
linear: { type: "boolean", description: "Move anchors in straight lines instead of the rotation-aware morph." }
|
|
11908
13432
|
};
|
|
11909
13433
|
var checkBlendOptions = (params) => {
|
|
11910
|
-
if (_optionalChain([params, 'optionalAccess',
|
|
11911
|
-
if (_optionalChain([params, 'optionalAccess',
|
|
11912
|
-
if (_optionalChain([params, 'optionalAccess',
|
|
13434
|
+
if (_optionalChain([params, 'optionalAccess', _453 => _453.spacing]) !== void 0 && !VECTOR_BLEND_SPACINGS.includes(params.spacing)) fail(`Unknown blend spacing "${params.spacing}".`);
|
|
13435
|
+
if (_optionalChain([params, 'optionalAccess', _454 => _454.steps]) !== void 0 && !(Number.isFinite(params.steps) && params.steps >= 1)) fail("steps must be at least 1.");
|
|
13436
|
+
if (_optionalChain([params, 'optionalAccess', _455 => _455.distance]) !== void 0 && !(Number.isFinite(params.distance) && params.distance > 0)) fail("distance must be positive.");
|
|
11913
13437
|
};
|
|
11914
13438
|
var POINT = { type: "object", properties: { x: { type: "number" }, y: { type: "number" } }, required: ["x", "y"] };
|
|
11915
13439
|
var GRADIENT_PROPS = {
|
|
@@ -11981,17 +13505,17 @@ function createVectorCommands(controller, options = {}) {
|
|
|
11981
13505
|
const base = { group, ...options.scope ? { scope: options.scope } : {} };
|
|
11982
13506
|
const hasSelection = () => controller.getState().selection.length ? true : "Nothing is selected.";
|
|
11983
13507
|
const ids = (params) => {
|
|
11984
|
-
const list2 = _nullishCoalesce(_optionalChain([params, 'optionalAccess',
|
|
13508
|
+
const list2 = _nullishCoalesce(_optionalChain([params, 'optionalAccess', _456 => _456.ids]), () => ( controller.getState().selection));
|
|
11985
13509
|
for (const id of list2) if (!controller.getNode(id)) fail(`There is no node "${id}".`);
|
|
11986
13510
|
if (!list2.length) fail("Nothing is selected; pass ids.");
|
|
11987
13511
|
return list2;
|
|
11988
13512
|
};
|
|
11989
|
-
const enabledFor = (_, params) => _optionalChain([params, 'optionalAccess',
|
|
13513
|
+
const enabledFor = (_, params) => _optionalChain([params, 'optionalAccess', _457 => _457.ids, 'optionalAccess', _458 => _458.length]) ? true : hasSelection();
|
|
11990
13514
|
const anchorsOf = (refs) => {
|
|
11991
13515
|
if (!refs) return [...controller.getState().selectedAnchors];
|
|
11992
13516
|
for (const r of refs) {
|
|
11993
13517
|
const node = controller.getNode(r.nodeId);
|
|
11994
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
13518
|
+
if (_optionalChain([node, 'optionalAccess', _459 => _459.type]) !== "path" || !_optionalChain([node, 'access', _460 => _460.subpaths, 'access', _461 => _461[r.subpath], 'optionalAccess', _462 => _462.anchors, 'access', _463 => _463[r.index]])) fail(`There is no anchor ${r.index} on subpath ${r.subpath} of "${r.nodeId}".`);
|
|
11995
13519
|
}
|
|
11996
13520
|
return refs;
|
|
11997
13521
|
};
|
|
@@ -12015,7 +13539,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12015
13539
|
...n.type === "path" ? { fill: _nullishCoalesce(n.fill, () => ( null)), stroke: _nullishCoalesce(n.stroke, () => ( null)), strokeWidth: _nullishCoalesce(n.strokeWidth, () => ( 1)), d: vectorPathData(n, 2) } : { children: n.children.length },
|
|
12016
13540
|
...n.type === "group" && n.blend ? { blend: { ...resolveVectorBlendOptions(n.blend), spine: !!n.blend.spine, keys: vectorBlendKeys(n).map((k) => k.id) } } : {},
|
|
12017
13541
|
...n.blendStep ? { blendStep: true } : {},
|
|
12018
|
-
..._optionalChain([n, 'access',
|
|
13542
|
+
..._optionalChain([n, 'access', _464 => _464.effects, 'optionalAccess', _465 => _465.length]) ? { effects: n.effects } : {},
|
|
12019
13543
|
...n.type === "group" && n.liveBoolean ? { liveBoolean: n.liveBoolean } : {},
|
|
12020
13544
|
...n.booleanOperation ? { booleanOperation: n.booleanOperation } : {}
|
|
12021
13545
|
});
|
|
@@ -12087,7 +13611,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12087
13611
|
run: (_ctx, params) => {
|
|
12088
13612
|
const id = controller.addPath(params.d, { ...pickStyle(params), ...params.name ? { name: params.name } : {} });
|
|
12089
13613
|
const node = controller.getNode(id);
|
|
12090
|
-
if (_optionalChain([node, 'optionalAccess',
|
|
13614
|
+
if (_optionalChain([node, 'optionalAccess', _466 => _466.type]) === "path" && !node.subpaths.length) {
|
|
12091
13615
|
controller.undo();
|
|
12092
13616
|
fail("The path data has no points.");
|
|
12093
13617
|
}
|
|
@@ -12126,7 +13650,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12126
13650
|
check(controller.setGradient(patch, { ids: ids(params), target: _nullishCoalesce(target, () => ( "fill")) }));
|
|
12127
13651
|
const id = ids(params)[0];
|
|
12128
13652
|
const node = id ? controller.getNode(id) : void 0;
|
|
12129
|
-
const path = _optionalChain([node, 'optionalAccess',
|
|
13653
|
+
const path = _optionalChain([node, 'optionalAccess', _467 => _467.type]) === "path" ? node : void 0;
|
|
12130
13654
|
return { ok: true, ...path ? { gradient: path[_nullishCoalesce(target, () => ( "fill"))] } : {} };
|
|
12131
13655
|
}
|
|
12132
13656
|
},
|
|
@@ -12139,10 +13663,10 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12139
13663
|
params: { type: "object", properties: { radius: { type: "number", minimum: 0 }, kind: { type: "string", enum: VECTOR_CORNER_KINDS }, ids: IDS, anchors: ANCHORS } },
|
|
12140
13664
|
undoable: true,
|
|
12141
13665
|
run: (_ctx, params) => {
|
|
12142
|
-
const refs = _optionalChain([params, 'optionalAccess',
|
|
12143
|
-
const target = { refs, ids: _optionalChain([params, 'optionalAccess',
|
|
12144
|
-
if (_optionalChain([params, 'optionalAccess',
|
|
12145
|
-
else if (_optionalChain([params, 'optionalAccess',
|
|
13666
|
+
const refs = _optionalChain([params, 'optionalAccess', _468 => _468.anchors]) ? anchorsOf(params.anchors) : void 0;
|
|
13667
|
+
const target = { refs, ids: _optionalChain([params, 'optionalAccess', _469 => _469.ids]) ? ids(params) : void 0 };
|
|
13668
|
+
if (_optionalChain([params, 'optionalAccess', _470 => _470.radius]) !== void 0) check(controller.setCornerRadius(params.radius, { ...target, kind: params.kind }));
|
|
13669
|
+
else if (_optionalChain([params, 'optionalAccess', _471 => _471.kind])) check(controller.setCornerKind(params.kind, target));
|
|
12146
13670
|
else fail("Pass `radius` and / or `kind`.");
|
|
12147
13671
|
return { ok: true };
|
|
12148
13672
|
}
|
|
@@ -12177,12 +13701,12 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12177
13701
|
undoable: true,
|
|
12178
13702
|
run: (_ctx, params) => {
|
|
12179
13703
|
const target = { ids: ids(params) };
|
|
12180
|
-
if (_optionalChain([params, 'optionalAccess',
|
|
12181
|
-
else if (_optionalChain([params, 'optionalAccess',
|
|
12182
|
-
else if (_optionalChain([params, 'optionalAccess',
|
|
13704
|
+
if (_optionalChain([params, 'optionalAccess', _472 => _472.preset])) check(controller.setWidthProfile(params.preset, target));
|
|
13705
|
+
else if (_optionalChain([params, 'optionalAccess', _473 => _473.points]) !== void 0) check(controller.setWidthProfile(_nullishCoalesce(params.points, () => ( null)), target));
|
|
13706
|
+
else if (_optionalChain([params, 'optionalAccess', _474 => _474.taper]) || _optionalChain([params, 'optionalAccess', _475 => _475.wave])) check(controller.setWidthProfile({ taper: params.taper, wave: params.wave }, target));
|
|
12183
13707
|
else fail("Pass `preset`, `points`, `taper` or `wave`.");
|
|
12184
13708
|
const node = controller.getNode(target.ids[0]);
|
|
12185
|
-
return { ok: true, points: _optionalChain([node, 'optionalAccess',
|
|
13709
|
+
return { ok: true, points: _optionalChain([node, 'optionalAccess', _476 => _476.type]) === "path" ? _nullishCoalesce(node.strokeWidthProfile, () => ( [])) : [] };
|
|
12186
13710
|
}
|
|
12187
13711
|
},
|
|
12188
13712
|
{
|
|
@@ -12204,10 +13728,10 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12204
13728
|
},
|
|
12205
13729
|
undoable: true,
|
|
12206
13730
|
run: (_ctx, params) => {
|
|
12207
|
-
if (!_optionalChain([params, 'optionalAccess',
|
|
13731
|
+
if (!_optionalChain([params, 'optionalAccess', _477 => _477.id])) fail("Pass the path `id`.");
|
|
12208
13732
|
check(controller.setWidthPoint({ nodeId: params.id, index: _nullishCoalesce(params.index, () => ( null)) }, { t: params.t, left: params.left, right: params.right }));
|
|
12209
13733
|
const node = controller.getNode(params.id);
|
|
12210
|
-
return { ok: true, points: _optionalChain([node, 'optionalAccess',
|
|
13734
|
+
return { ok: true, points: _optionalChain([node, 'optionalAccess', _478 => _478.type]) === "path" ? _nullishCoalesce(node.strokeWidthProfile, () => ( [])) : [] };
|
|
12211
13735
|
}
|
|
12212
13736
|
},
|
|
12213
13737
|
{
|
|
@@ -12220,11 +13744,119 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12220
13744
|
enabled: enabledFor,
|
|
12221
13745
|
undoable: true,
|
|
12222
13746
|
run: (_ctx, params) => {
|
|
12223
|
-
const created = controller.outlineStroke({ ids: _optionalChain([params, 'optionalAccess',
|
|
13747
|
+
const created = controller.outlineStroke({ ids: _optionalChain([params, 'optionalAccess', _479 => _479.ids]) ? ids(params) : void 0 });
|
|
12224
13748
|
if (!created.length) fail("No selected path has a stroke.");
|
|
12225
13749
|
return { ids: created };
|
|
12226
13750
|
}
|
|
12227
13751
|
},
|
|
13752
|
+
{
|
|
13753
|
+
...base,
|
|
13754
|
+
id: `${prefix}distort`,
|
|
13755
|
+
label: "Free Distort\u2026",
|
|
13756
|
+
keywords: ["distort", "perspective", "free distort", "corners", "projective", "keystone"],
|
|
13757
|
+
description: "Free Distort: moves the four corners of the selection box (clockwise from the top left, in the box\u2019s own rotation) to `corners` in document units, distorting the nodes in perspective (straight lines stay straight; curves are followed within `tolerance`). The corners must make a convex quadrilateral. One undo step.",
|
|
13758
|
+
params: {
|
|
13759
|
+
type: "object",
|
|
13760
|
+
properties: {
|
|
13761
|
+
ids: IDS,
|
|
13762
|
+
corners: { type: "array", items: POINT, minItems: 4, maxItems: 4, description: "New top-left, top-right, bottom-right and bottom-left corners." },
|
|
13763
|
+
tolerance: { type: "number", exclusiveMinimum: 0, description: "How closely curves follow the distortion (document units, default 0.05)." }
|
|
13764
|
+
},
|
|
13765
|
+
required: ["corners"]
|
|
13766
|
+
},
|
|
13767
|
+
enabled: enabledFor,
|
|
13768
|
+
undoable: true,
|
|
13769
|
+
run: (_ctx, params) => {
|
|
13770
|
+
check(controller.distort(params.corners, { ids: ids(params), tolerance: params.tolerance }));
|
|
13771
|
+
const frame2 = controller.getState().selectionFrame;
|
|
13772
|
+
return { ok: true, bounds: frame2 ? { x: frame2.x, y: frame2.y, width: frame2.width, height: frame2.height } : null };
|
|
13773
|
+
}
|
|
13774
|
+
},
|
|
13775
|
+
{
|
|
13776
|
+
...base,
|
|
13777
|
+
id: `${prefix}skew`,
|
|
13778
|
+
label: "Skew\u2026",
|
|
13779
|
+
keywords: ["skew", "shear", "slant", "oblique"],
|
|
13780
|
+
description: "Skews nodes along the selection box\u2019s axes: `ax` degrees horizontally (vertical lines lean right for positive angles) and `ay` degrees vertically, about the box centre or `origin`. One undo step.",
|
|
13781
|
+
params: {
|
|
13782
|
+
type: "object",
|
|
13783
|
+
properties: {
|
|
13784
|
+
ids: IDS,
|
|
13785
|
+
ax: { type: "number", minimum: -89.9, maximum: 89.9 },
|
|
13786
|
+
ay: { type: "number", minimum: -89.9, maximum: 89.9 },
|
|
13787
|
+
origin: POINT
|
|
13788
|
+
}
|
|
13789
|
+
},
|
|
13790
|
+
enabled: enabledFor,
|
|
13791
|
+
undoable: true,
|
|
13792
|
+
run: (_ctx, params) => {
|
|
13793
|
+
check(controller.skew(_nullishCoalesce(params.ax, () => ( 0)), _nullishCoalesce(params.ay, () => ( 0)), { ids: ids(params), origin: params.origin }));
|
|
13794
|
+
return { ok: true };
|
|
13795
|
+
}
|
|
13796
|
+
},
|
|
13797
|
+
{
|
|
13798
|
+
...base,
|
|
13799
|
+
id: `${prefix}envelope`,
|
|
13800
|
+
label: "Envelope Distort\u2026",
|
|
13801
|
+
keywords: ["envelope", "warp", "mesh", "arc", "arch", "bulge", "flag", "wave", "fish", "rise", "fisheye", "inflate", "squeeze", "twist", "shell", "bend", "distort"],
|
|
13802
|
+
description: "Envelope distortion that stays editable (a live `envelope` effect). Give `preset` (with `bend`, `horizontal`, `vertical` in percent, \u2212100\u2026100, and `orientation`) to warp, or `mesh` ({ rows, columns } and optionally `points`, the control grid row by row in the node\u2019s own space) for an editable mesh; a node that already has an envelope is changed. `topObject: true` uses the topmost selected closed path as the envelope of the others; `release: true` removes the envelope and gives back its shape as a path; `expand: true` bakes it (Expand Appearance). One undo step.",
|
|
13803
|
+
params: {
|
|
13804
|
+
type: "object",
|
|
13805
|
+
properties: {
|
|
13806
|
+
ids: IDS,
|
|
13807
|
+
preset: { type: "string", enum: VECTOR_WARP_STYLES },
|
|
13808
|
+
bend: { type: "number", minimum: -100, maximum: 100 },
|
|
13809
|
+
horizontal: { type: "number", minimum: -100, maximum: 100 },
|
|
13810
|
+
vertical: { type: "number", minimum: -100, maximum: 100 },
|
|
13811
|
+
orientation: { type: "string", enum: ["horizontal", "vertical"] },
|
|
13812
|
+
mesh: {
|
|
13813
|
+
type: "object",
|
|
13814
|
+
properties: {
|
|
13815
|
+
rows: { type: "integer", minimum: 1, maximum: 16 },
|
|
13816
|
+
columns: { type: "integer", minimum: 1, maximum: 16 },
|
|
13817
|
+
points: { type: "array", items: POINT, description: "(3\xB7columns + 1) \xD7 (3\xB7rows + 1) control points, row by row (node space)." }
|
|
13818
|
+
}
|
|
13819
|
+
},
|
|
13820
|
+
topObject: { type: "boolean" },
|
|
13821
|
+
release: { type: "boolean" },
|
|
13822
|
+
expand: { type: "boolean" }
|
|
13823
|
+
}
|
|
13824
|
+
},
|
|
13825
|
+
enabled: enabledFor,
|
|
13826
|
+
undoable: true,
|
|
13827
|
+
run: (_ctx, params) => {
|
|
13828
|
+
const target = ids(params);
|
|
13829
|
+
if (params.release) return { released: target, shapes: controller.releaseEnvelope({ ids: target }) };
|
|
13830
|
+
if (params.expand) return { expanded: controller.expandAppearance({ ids: target }) };
|
|
13831
|
+
if (params.topObject) {
|
|
13832
|
+
const r = controller.makeEnvelopeWithTopObject({ ids: target, rows: _optionalChain([params, 'access', _480 => _480.mesh, 'optionalAccess', _481 => _481.rows]), columns: _optionalChain([params, 'access', _482 => _482.mesh, 'optionalAccess', _483 => _483.columns]) });
|
|
13833
|
+
check(r);
|
|
13834
|
+
return { nodeId: r.nodeId };
|
|
13835
|
+
}
|
|
13836
|
+
if (params.preset !== void 0 && !VECTOR_WARP_STYLES.includes(params.preset)) fail(`Unknown warp preset "${params.preset}".`);
|
|
13837
|
+
const patch = {};
|
|
13838
|
+
if (params.preset) patch.style = params.preset;
|
|
13839
|
+
for (const k of ["bend", "horizontal", "vertical"]) if (params[k] !== void 0) patch[k] = params[k];
|
|
13840
|
+
if (params.orientation) patch.orientation = params.orientation;
|
|
13841
|
+
if (params.mesh) {
|
|
13842
|
+
if (params.preset) fail("Give either `preset` or `mesh`, not both.");
|
|
13843
|
+
patch.style = "mesh";
|
|
13844
|
+
const columns = _nullishCoalesce(params.mesh.columns, () => ( 2));
|
|
13845
|
+
const rows = _nullishCoalesce(params.mesh.rows, () => ( 2));
|
|
13846
|
+
patch.columns = columns;
|
|
13847
|
+
patch.rows = rows;
|
|
13848
|
+
if (params.mesh.points) {
|
|
13849
|
+
const even = (n) => Array.from({ length: n + 1 }, (_, i) => i / n);
|
|
13850
|
+
const mesh = { us: even(columns), vs: even(rows), points: params.mesh.points.map((p) => ({ x: p.x, y: p.y })) };
|
|
13851
|
+
if (!isValidVectorMesh(mesh)) fail(`A ${columns} \xD7 ${rows} mesh needs ${(3 * columns + 1) * (3 * rows + 1)} finite points.`);
|
|
13852
|
+
patch.mesh = mesh;
|
|
13853
|
+
}
|
|
13854
|
+
}
|
|
13855
|
+
const made = controller.envelope(patch, { ids: target });
|
|
13856
|
+
if (!made.length) fail("Nothing to envelope.");
|
|
13857
|
+
return { envelopes: made };
|
|
13858
|
+
}
|
|
13859
|
+
},
|
|
12228
13860
|
{
|
|
12229
13861
|
...base,
|
|
12230
13862
|
id: `${prefix}transform`,
|
|
@@ -12337,7 +13969,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12337
13969
|
run: (_ctx, params) => {
|
|
12338
13970
|
if (params.params !== void 0 || params.enabled !== void 0) check(controller.updateEffect(params.nodeId, params.effectId, { params: params.params, enabled: params.enabled }));
|
|
12339
13971
|
if (params.index !== void 0) check(controller.moveEffect(params.nodeId, params.effectId, params.index));
|
|
12340
|
-
return { effects: _nullishCoalesce(_optionalChain([controller, 'access',
|
|
13972
|
+
return { effects: _nullishCoalesce(_optionalChain([controller, 'access', _484 => _484.getNode, 'call', _485 => _485(params.nodeId), 'optionalAccess', _486 => _486.effects]), () => ( [])) };
|
|
12341
13973
|
}
|
|
12342
13974
|
},
|
|
12343
13975
|
{
|
|
@@ -12401,7 +14033,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12401
14033
|
undoable: true,
|
|
12402
14034
|
run: (_ctx, params) => {
|
|
12403
14035
|
checkBlendOptions(params);
|
|
12404
|
-
const r = controller.setBlendOptions(_nullishCoalesce(params, () => ( {})), { ids: _optionalChain([params, 'optionalAccess',
|
|
14036
|
+
const r = controller.setBlendOptions(_nullishCoalesce(params, () => ( {})), { ids: _optionalChain([params, 'optionalAccess', _487 => _487.ids]) });
|
|
12405
14037
|
if (!r.ok) fail(r.message);
|
|
12406
14038
|
return { ok: true };
|
|
12407
14039
|
}
|
|
@@ -12415,7 +14047,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12415
14047
|
params: { type: "object", properties: { ids: IDS } },
|
|
12416
14048
|
undoable: true,
|
|
12417
14049
|
run: (_ctx, params) => {
|
|
12418
|
-
const groups = controller.expandBlend({ ids: _optionalChain([params, 'optionalAccess',
|
|
14050
|
+
const groups = controller.expandBlend({ ids: _optionalChain([params, 'optionalAccess', _488 => _488.ids]) });
|
|
12419
14051
|
if (!groups.length) fail("Select a blend to expand.");
|
|
12420
14052
|
return { ids: groups };
|
|
12421
14053
|
}
|
|
@@ -12429,7 +14061,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12429
14061
|
params: { type: "object", properties: { ids: IDS } },
|
|
12430
14062
|
undoable: true,
|
|
12431
14063
|
run: (_ctx, params) => {
|
|
12432
|
-
const released = controller.releaseBlend({ ids: _optionalChain([params, 'optionalAccess',
|
|
14064
|
+
const released = controller.releaseBlend({ ids: _optionalChain([params, 'optionalAccess', _489 => _489.ids]) });
|
|
12433
14065
|
if (!released.length) fail("Select a blend to release.");
|
|
12434
14066
|
return { ids: released };
|
|
12435
14067
|
}
|
|
@@ -12443,7 +14075,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12443
14075
|
params: { type: "object", properties: { ids: IDS } },
|
|
12444
14076
|
undoable: true,
|
|
12445
14077
|
run: (_ctx, params) => {
|
|
12446
|
-
const r = controller.replaceBlendSpine({ ids: _optionalChain([params, 'optionalAccess',
|
|
14078
|
+
const r = controller.replaceBlendSpine({ ids: _optionalChain([params, 'optionalAccess', _490 => _490.ids]) });
|
|
12447
14079
|
if (!r.ok) fail(r.message);
|
|
12448
14080
|
return { ok: true };
|
|
12449
14081
|
}
|
|
@@ -12557,7 +14189,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12557
14189
|
enabled: enabledFor,
|
|
12558
14190
|
undoable: true,
|
|
12559
14191
|
run: (_ctx, params) => {
|
|
12560
|
-
const id = controller.group({ ids: ids(params), name: _optionalChain([params, 'optionalAccess',
|
|
14192
|
+
const id = controller.group({ ids: ids(params), name: _optionalChain([params, 'optionalAccess', _491 => _491.name]) });
|
|
12561
14193
|
if (!id) fail("Only nodes that share a parent can be grouped.");
|
|
12562
14194
|
return { id };
|
|
12563
14195
|
}
|
|
@@ -12585,7 +14217,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12585
14217
|
params: { type: "object", properties: { anchors: ANCHORS, keepShape: { type: "boolean" } } },
|
|
12586
14218
|
undoable: true,
|
|
12587
14219
|
run: (_ctx, params) => {
|
|
12588
|
-
check(controller.deleteAnchors(anchorsOf(_optionalChain([params, 'optionalAccess',
|
|
14220
|
+
check(controller.deleteAnchors(anchorsOf(_optionalChain([params, 'optionalAccess', _492 => _492.anchors])), { keepShape: _optionalChain([params, 'optionalAccess', _493 => _493.keepShape]) }));
|
|
12589
14221
|
return { ok: true };
|
|
12590
14222
|
}
|
|
12591
14223
|
},
|
|
@@ -12640,7 +14272,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12640
14272
|
params: { type: "object", properties: { ids: IDS, tolerance: { type: "number", minimum: 0 } } },
|
|
12641
14273
|
undoable: true,
|
|
12642
14274
|
run: (_ctx, params) => {
|
|
12643
|
-
check(controller.joinPaths({ ids: _optionalChain([params, 'optionalAccess',
|
|
14275
|
+
check(controller.joinPaths({ ids: _optionalChain([params, 'optionalAccess', _494 => _494.ids]) ? ids(params) : void 0, tolerance: _optionalChain([params, 'optionalAccess', _495 => _495.tolerance]) }));
|
|
12644
14276
|
return { selection: controller.getState().selection };
|
|
12645
14277
|
}
|
|
12646
14278
|
},
|
|
@@ -12654,7 +14286,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12654
14286
|
params: { type: "object", properties: { axis: { type: "string", enum: ["horizontal", "vertical", "both"] }, anchors: ANCHORS } },
|
|
12655
14287
|
undoable: true,
|
|
12656
14288
|
run: (_ctx, params) => {
|
|
12657
|
-
check(controller.averageAnchors(_nullishCoalesce(_optionalChain([params, 'optionalAccess',
|
|
14289
|
+
check(controller.averageAnchors(_nullishCoalesce(_optionalChain([params, 'optionalAccess', _496 => _496.axis]), () => ( "both")), anchorsOf(_optionalChain([params, 'optionalAccess', _497 => _497.anchors]))));
|
|
12658
14290
|
return { ok: true };
|
|
12659
14291
|
}
|
|
12660
14292
|
},
|
|
@@ -12668,7 +14300,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12668
14300
|
enabled: enabledFor,
|
|
12669
14301
|
undoable: true,
|
|
12670
14302
|
run: (_ctx, params) => {
|
|
12671
|
-
check(controller.removeRedundantPoints({ ids: _optionalChain([params, 'optionalAccess',
|
|
14303
|
+
check(controller.removeRedundantPoints({ ids: _optionalChain([params, 'optionalAccess', _498 => _498.ids]) ? ids(params) : void 0, tolerance: _optionalChain([params, 'optionalAccess', _499 => _499.tolerance]) }));
|
|
12672
14304
|
return { ok: true };
|
|
12673
14305
|
}
|
|
12674
14306
|
},
|
|
@@ -12681,7 +14313,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12681
14313
|
params: { type: "object", properties: { ids: IDS, amount: { type: "number", minimum: 0, maximum: 1 }, anchors: ANCHORS } },
|
|
12682
14314
|
undoable: true,
|
|
12683
14315
|
run: (_ctx, params) => {
|
|
12684
|
-
check(controller.smoothPaths({ ids: _optionalChain([params, 'optionalAccess',
|
|
14316
|
+
check(controller.smoothPaths({ ids: _optionalChain([params, 'optionalAccess', _500 => _500.ids]) ? ids(params) : void 0, amount: _optionalChain([params, 'optionalAccess', _501 => _501.amount]), refs: _optionalChain([params, 'optionalAccess', _502 => _502.anchors]) }));
|
|
12685
14317
|
return { ok: true };
|
|
12686
14318
|
}
|
|
12687
14319
|
},
|
|
@@ -12694,14 +14326,14 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12694
14326
|
params: { type: "object", properties: { nodeId: { type: "string" }, x: { type: "number" }, y: { type: "number" }, anchors: ANCHORS } },
|
|
12695
14327
|
undoable: true,
|
|
12696
14328
|
run: (_ctx, params) => {
|
|
12697
|
-
if (_optionalChain([params, 'optionalAccess',
|
|
14329
|
+
if (_optionalChain([params, 'optionalAccess', _503 => _503.nodeId]) !== void 0) {
|
|
12698
14330
|
if (!controller.getNode(params.nodeId)) fail(`There is no node "${params.nodeId}".`);
|
|
12699
14331
|
if (params.x === void 0 || params.y === void 0) fail("Pass x and y with nodeId.");
|
|
12700
14332
|
const created = controller.cutPathAt(params.nodeId, { x: params.x, y: params.y });
|
|
12701
14333
|
if (!created) fail("Nothing to cut there (the end of an open path, or a locked path).");
|
|
12702
14334
|
return { ids: created };
|
|
12703
14335
|
}
|
|
12704
|
-
check(controller.cutAtAnchors(anchorsOf(_optionalChain([params, 'optionalAccess',
|
|
14336
|
+
check(controller.cutAtAnchors(anchorsOf(_optionalChain([params, 'optionalAccess', _504 => _504.anchors]))));
|
|
12705
14337
|
return { ids: controller.getState().selection };
|
|
12706
14338
|
}
|
|
12707
14339
|
},
|
|
@@ -12752,7 +14384,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12752
14384
|
},
|
|
12753
14385
|
run: (_ctx, params) => {
|
|
12754
14386
|
const patch = {};
|
|
12755
|
-
for (const key of ["keepShapeOnDelete", "curvatureMoves", "pencilSmoothing", "recognizeShapes", "eraserSize", "pencilPressure"]) if (_optionalChain([params, 'optionalAccess',
|
|
14387
|
+
for (const key of ["keepShapeOnDelete", "curvatureMoves", "pencilSmoothing", "recognizeShapes", "eraserSize", "pencilPressure"]) if (_optionalChain([params, 'optionalAccess', _505 => _505[key]]) !== void 0) patch[key] = params[key];
|
|
12756
14388
|
controller.setEditing(patch);
|
|
12757
14389
|
return { editing: controller.getState().editing };
|
|
12758
14390
|
}
|
|
@@ -12777,7 +14409,7 @@ function createVectorCommands(controller, options = {}) {
|
|
|
12777
14409
|
keywords: ["download", "save", "markup"],
|
|
12778
14410
|
description: "Returns the document as SVG markup.",
|
|
12779
14411
|
params: { type: "object", properties: { precision: { type: "integer", minimum: 0, maximum: 8 } } },
|
|
12780
|
-
run: (_ctx, params) => ({ svg: controller.toSvg({ precision: _optionalChain([params, 'optionalAccess',
|
|
14412
|
+
run: (_ctx, params) => ({ svg: controller.toSvg({ precision: _optionalChain([params, 'optionalAccess', _506 => _506.precision]) }) })
|
|
12781
14413
|
},
|
|
12782
14414
|
{
|
|
12783
14415
|
...base,
|
|
@@ -13136,5 +14768,54 @@ function createVectorCommands(controller, options = {}) {
|
|
|
13136
14768
|
|
|
13137
14769
|
|
|
13138
14770
|
|
|
13139
|
-
exports.DEFAULT_VECTOR_BLEND_DISTANCE = DEFAULT_VECTOR_BLEND_DISTANCE; exports.DEFAULT_VECTOR_BLEND_STEPS = DEFAULT_VECTOR_BLEND_STEPS; 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_BLEND_MAX_SMOOTH_STEPS = VECTOR_BLEND_MAX_SMOOTH_STEPS; exports.VECTOR_BLEND_MAX_STEPS = VECTOR_BLEND_MAX_STEPS; exports.VECTOR_BLEND_SPACINGS = VECTOR_BLEND_SPACINGS; exports.VECTOR_BLEND_SPACING_LABELS = VECTOR_BLEND_SPACING_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_EFFECT_DEFAULTS = VECTOR_EFFECT_DEFAULTS; exports.VECTOR_EFFECT_LABELS = VECTOR_EFFECT_LABELS; exports.VECTOR_EFFECT_MENU = VECTOR_EFFECT_MENU; exports.VECTOR_EFFECT_PARAM_SPECS = VECTOR_EFFECT_PARAM_SPECS; exports.VECTOR_EFFECT_TYPES = VECTOR_EFFECT_TYPES; exports.VECTOR_FILL_GAP = VECTOR_FILL_GAP; exports.VECTOR_GRADIENT_INTERPOLATIONS = VECTOR_GRADIENT_INTERPOLATIONS; exports.VECTOR_GRADIENT_INTERPOLATION_LABELS = VECTOR_GRADIENT_INTERPOLATION_LABELS; exports.VECTOR_GRADIENT_MAX_PERIODS = VECTOR_GRADIENT_MAX_PERIODS; exports.VECTOR_GRADIENT_MIDPOINT_GAP = VECTOR_GRADIENT_MIDPOINT_GAP; exports.VECTOR_GRADIENT_MIN_STOPS = VECTOR_GRADIENT_MIN_STOPS; exports.VECTOR_GRADIENT_OFF_BAR = VECTOR_GRADIENT_OFF_BAR; exports.VECTOR_GRADIENT_SPREADS = VECTOR_GRADIENT_SPREADS; exports.VECTOR_GRADIENT_SPREAD_LABELS = VECTOR_GRADIENT_SPREAD_LABELS; exports.VECTOR_GRADIENT_STOP_GAP = VECTOR_GRADIENT_STOP_GAP; exports.VECTOR_GRADIENT_TYPES = VECTOR_GRADIENT_TYPES; exports.VECTOR_GRADIENT_TYPE_LABELS = VECTOR_GRADIENT_TYPE_LABELS; exports.VECTOR_INK_MAX_CORNERS = VECTOR_INK_MAX_CORNERS; exports.VECTOR_MERGE_MODES = VECTOR_MERGE_MODES; 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_STROKE_GRADIENT_MODES = VECTOR_STROKE_GRADIENT_MODES; exports.VECTOR_STROKE_GRADIENT_MODE_LABELS = VECTOR_STROKE_GRADIENT_MODE_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.activeVectorEffects = activeVectorEffects; exports.addBuilderHit = addBuilderHit; exports.applyMatrix = applyMatrix; exports.applyMatrixLinear = applyMatrixLinear; exports.applyVectorBlendOptions = applyVectorBlendOptions; exports.applyVectorCornersAttribute = applyVectorCornersAttribute; exports.applyVectorEffects = applyVectorEffects; exports.applyVectorGradientPatch = applyVectorGradientPatch; exports.applyVectorGradientSpread = applyVectorGradientSpread; exports.arrowheadInset = arrowheadInset; exports.arrowheadPath = arrowheadPath; exports.arrowheadWeight = arrowheadWeight; exports.bendSegment = bendSegment; exports.bezierToSubpaths = bezierToSubpaths; exports.boundsFromPoints = boundsFromPoints; exports.boundsIntersect = boundsIntersect; exports.clearVectorLiveBooleanCache = clearVectorLiveBooleanCache; exports.cloneAnchor = cloneAnchor; exports.cloneSubpath = cloneSubpath; exports.cloneVectorDocument = cloneVectorDocument; exports.cloneVectorNode = cloneVectorNode; exports.collectPathNodes = collectPathNodes; exports.constrainToLeave = constrainToLeave; exports.convertAnchor = convertAnchor; exports.convertVectorGradient = convertVectorGradient; exports.cornerBisectorPoint = cornerBisectorPoint; exports.cornerRadiusChange = cornerRadiusChange; exports.cornerSetback = cornerSetback; exports.correspondMorphContours = correspondMorphContours; exports.createVectorCommands = createVectorCommands; exports.createVectorEffect = createVectorEffect; exports.createVectorMorph = createVectorMorph; exports.curvatureMoveAnchor = curvatureMoveAnchor; exports.cutSubpathAt = cutSubpathAt; exports.dashIntervals = dashIntervals; exports.decomposeRigid = decomposeRigid; exports.defaultVectorGradient = defaultVectorGradient; exports.effectPathLength = effectPathLength; exports.effectPathVertexCount = effectPathVertexCount; exports.effectiveStrokeAlign = effectiveStrokeAlign; exports.ellipseSubpath = ellipseSubpath; exports.eraseFromFill = eraseFromFill; exports.eraseFromOutline = eraseFromOutline; exports.eraserRegion = eraserRegion; exports.evaluateVectorPathKeyframes = evaluateVectorPathKeyframes; exports.expandVectorAppearance = expandVectorAppearance; exports.expandVectorAppearances = expandVectorAppearances; exports.expandVectorBlend = expandVectorBlend; exports.expandVectorCorners = expandVectorCorners; exports.expandVectorCornersOf = expandVectorCornersOf; exports.expandVectorGradientSpread = expandVectorGradientSpread; exports.expandVectorGradientStops = expandVectorGradientStops; exports.explicitVectorGradient = explicitVectorGradient; exports.findVectorNode = findVectorNode; exports.fitCornerRadius = fitCornerRadius; exports.foldVectorBooleanOperands = foldVectorBooleanOperands; exports.generateVectorBlendChildren = generateVectorBlendChildren; exports.generateWidthProfile = generateWidthProfile; exports.getAnchor = getAnchor; exports.getAnchorWorld = getAnchorWorld; exports.getEditablePathIds = getEditablePathIds; exports.getTransformHandlePositions = getTransformHandlePositions; exports.getVectorBlendControls = getVectorBlendControls; exports.getVectorCornerWidgets = getVectorCornerWidgets; exports.getVectorEffectsPanel = getVectorEffectsPanel; exports.getVectorEnteredGroups = getVectorEnteredGroups; exports.getVectorGradientAnnotator = getVectorGradientAnnotator; exports.getVectorGradientEditor = getVectorGradientEditor; 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.gradientMidpointRemap = gradientMidpointRemap; exports.hasExplicitGradientGeometry = hasExplicitGradientGeometry; exports.hasOwnVectorAppearance = hasOwnVectorAppearance; exports.hasPaint = hasPaint; exports.hasStrokeExtras = hasStrokeExtras; exports.hasVectorAppearance = hasVectorAppearance; exports.hasVectorCorners = hasVectorCorners; exports.hitTestVectorNode = hitTestVectorNode; exports.hitTestVectorNodes = hitTestVectorNodes; exports.hitTestVectorStroke = hitTestVectorStroke; exports.hitVectorGradientAnnotator = hitVectorGradientAnnotator; exports.inferAnchorType = inferAnchorType; exports.insertAnchor = insertAnchor; exports.insertVectorGradientStop = insertVectorGradientStop; exports.insertWidthPoint = insertWidthPoint; exports.interpolateMorphContours = interpolateMorphContours; exports.interpolateRigidMatrix = interpolateRigidMatrix; exports.interpolateVectorColor = interpolateVectorColor; exports.interpolateVectorPaint = interpolateVectorPaint; exports.interpolateVectorPaths = interpolateVectorPaths; exports.interpolateVectorStyle = interpolateVectorStyle; exports.interpolateWidthProfiles = interpolateWidthProfiles; exports.invertMatrix = invertMatrix; exports.isCentredVectorGradient = isCentredVectorGradient; exports.isClosedBezierShape = isClosedBezierShape; exports.isIdentityMatrix = isIdentityMatrix; exports.isUniformWidthProfile = isUniformWidthProfile; exports.isVectorBlendGroup = isVectorBlendGroup; exports.isVectorGradient = isVectorGradient; exports.isVectorLiveBoolean = isVectorLiveBoolean; exports.isVectorTextTarget = isVectorTextTarget; exports.joinSubpaths = joinSubpaths; exports.knifePath = knifePath; exports.lineSubpath = lineSubpath; exports.locateVectorNode = locateVectorNode; exports.matrixRotation = matrixRotation; exports.mergePaths = mergePaths; exports.mirrorWidthProfile = mirrorWidthProfile; exports.morphContourToSubpath = morphContourToSubpath; exports.morphPathsCross = morphPathsCross; exports.moveAnchorHandle = moveAnchorHandle; exports.moveVectorGradientHandle = moveVectorGradientHandle; exports.moveVectorGradientStop = moveVectorGradientStop; exports.multiplyMatrices = multiplyMatrices; exports.nearestSegment = nearestSegment; exports.nearestStrokePosition = nearestStrokePosition; exports.nextVectorCornerKind = nextVectorCornerKind; exports.nodeMatrix = nodeMatrix; exports.normalizeVectorEffectParams = normalizeVectorEffectParams; exports.offsetPaths = offsetPaths; exports.parseSvgTransform = parseSvgTransform; exports.parseVectorColor = parseVectorColor; exports.parseVectorSvg = parseVectorSvg; exports.pathsCenter = pathsCenter; exports.patternAttrs = patternAttrs; exports.periodicVectorGradientStops = periodicVectorGradientStops; exports.pinVectorGradient = pinVectorGradient; exports.planShapeBuilder = planShapeBuilder; exports.polygonSubpath = polygonSubpath; exports.polylineBounds = polylineBounds; exports.pressureWidthProfile = pressureWidthProfile; exports.puckerBloatPaths = puckerBloatPaths; exports.recognizeInkShape = recognizeInkShape; exports.rectSubpath = rectSubpath; exports.refineMorphContour = refineMorphContour; exports.refreshVectorBlends = refreshVectorBlends; exports.releaseVectorBlend = releaseVectorBlend; exports.removeAnchorKeepingShape = removeAnchorKeepingShape; exports.removeAnchors = removeAnchors; exports.removeAnchorsKeepingShape = removeAnchorsKeepingShape; exports.removeRedundantPoints = removeRedundantPoints; exports.removeVectorGradientStop = removeVectorGradientStop; exports.removeWidthPoints = removeWidthPoints; exports.repeatPaths = repeatPaths; exports.resampleGradientStops = resampleGradientStops; exports.resolveVectorBlendOptions = resolveVectorBlendOptions; exports.reverseMorphContour = reverseMorphContour; exports.reverseSubpath = reverseSubpath; exports.reverseVectorGradient = reverseVectorGradient; exports.reverseWidthProfile = reverseWidthProfile; exports.rotateMatrix = rotateMatrix; exports.roundCornerPaths = roundCornerPaths; exports.roundSubpaths = roundSubpaths; exports.samplePlainStops = samplePlainStops; exports.samplePolyline = samplePolyline; exports.sampleVectorGradient = sampleVectorGradient; exports.sampleVectorGradientAt = sampleVectorGradientAt; exports.sampleVectorPaintDefAt = sampleVectorPaintDefAt; exports.sanitizeVectorEffects = sanitizeVectorEffects; exports.sanitizeVectorGradient = sanitizeVectorGradient; exports.sanitizeWidthProfile = sanitizeWidthProfile; exports.scaleFor = scaleFor; exports.scaleMatrix = scaleMatrix; exports.setAnchorCorner = setAnchorCorner; exports.setSubpathCorners = setSubpathCorners; exports.setVectorGradientVector = setVectorGradientVector; exports.setWidthPoint = setWidthPoint; exports.simplifyPolyline = simplifyPolyline; exports.smoothSubpath = smoothSubpath; exports.sortedVectorGradientStops = sortedVectorGradientStops; exports.spanVectorGradientStops = spanVectorGradientStops; 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.subpathToMorphContour = subpathToMorphContour; exports.subpathsToBezier = subpathsToBezier; exports.taperWaveFactor = taperWaveFactor; exports.toVectorKeyInput = toVectorKeyInput; exports.toVectorModifiers = toVectorModifiers; exports.toVectorPointerInput = toVectorPointerInput; exports.transformVectorEffects = transformVectorEffects; exports.transformVectorGradient = transformVectorGradient; exports.transformVectorNode = transformVectorNode; exports.transformVectorPaint = transformVectorPaint; exports.translateAnchor = translateAnchor; exports.translateMatrix = translateMatrix; exports.trimIntervals = trimIntervals; exports.trimPaths = trimPaths; exports.trimPathsIndividually = trimPathsIndividually; exports.turnMorphContour = turnMorphContour; exports.twistPaths = twistPaths; exports.unionBounds = unionBounds; exports.variableStrokeOutline = variableStrokeOutline; exports.variableStrokeRings = variableStrokeRings; exports.vectorAppearanceNodes = vectorAppearanceNodes; exports.vectorAppearanceOutline = vectorAppearanceOutline; exports.vectorAppearanceShapes = vectorAppearanceShapes; exports.vectorBlendColorDistance = vectorBlendColorDistance; exports.vectorBlendKeyTargets = vectorBlendKeyTargets; exports.vectorBlendKeys = vectorBlendKeys; exports.vectorBlendRail = vectorBlendRail; exports.vectorBlendRailAt = vectorBlendRailAt; exports.vectorBlendSpine = vectorBlendSpine; exports.vectorBlendStepCount = vectorBlendStepCount; exports.vectorBoxMatrix = vectorBoxMatrix; exports.vectorBuilderErasedEdges = vectorBuilderErasedEdges; exports.vectorCornerAt = vectorCornerAt; exports.vectorCorners = vectorCorners; exports.vectorCornersAttribute = vectorCornersAttribute; exports.vectorDiamondPath = vectorDiamondPath; exports.vectorDocumentToSvg = vectorDocumentToSvg; exports.vectorEnteredGroups = vectorEnteredGroups; exports.vectorFillMap = vectorFillMap; exports.vectorGradientArea = vectorGradientArea; exports.vectorGradientAspect = vectorGradientAspect; exports.vectorGradientBarPosition = vectorGradientBarPosition; exports.vectorGradientFocalParam = vectorGradientFocalParam; exports.vectorGradientHandles = vectorGradientHandles; exports.vectorGradientMatrix = vectorGradientMatrix; exports.vectorGradientMidpointFromPosition = vectorGradientMidpointFromPosition; exports.vectorGradientMidpointPosition = vectorGradientMidpointPosition; exports.vectorGradientNeedsExpansion = vectorGradientNeedsExpansion; exports.vectorGradientParam = vectorGradientParam; exports.vectorGradientPoints = vectorGradientPoints; exports.vectorGradientRamp = vectorGradientRamp; exports.vectorGradientSvgDefs = vectorGradientSvgDefs; exports.vectorGradientTAt = vectorGradientTAt; exports.vectorGradientTargetPath = vectorGradientTargetPath; exports.vectorGradientUnitsMatrix = vectorGradientUnitsMatrix; exports.vectorInkShapeName = vectorInkShapeName; exports.vectorLiveBooleanSteps = vectorLiveBooleanSteps; exports.vectorNodeBounds = vectorNodeBounds; exports.vectorNodeRotation = vectorNodeRotation; exports.vectorNodeToBezier = vectorNodeToBezier; exports.vectorOperandOperation = vectorOperandOperation; exports.vectorPaintToHex = vectorPaintToHex; exports.vectorPaintToSvg = vectorPaintToSvg; exports.vectorParentMatrix = vectorParentMatrix; exports.vectorPathData = vectorPathData; exports.vectorPathEntries = vectorPathEntries; exports.vectorPathLocalBounds = vectorPathLocalBounds; exports.vectorPathWorldBezier = vectorPathWorldBezier; exports.vectorPathfinderShape = vectorPathfinderShape; exports.vectorRepeaterCopies = vectorRepeaterCopies; exports.vectorResizeCursor = vectorResizeCursor; exports.vectorResultStyle = vectorResultStyle; exports.vectorShapeBuilderHit = vectorShapeBuilderHit; exports.vectorShapeBuilderMap = vectorShapeBuilderMap; exports.vectorStrokeGradientDefs = vectorStrokeGradientDefs; 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; exports.wigglePaths = wigglePaths; exports.zigzagPaths = zigzagPaths;
|
|
14771
|
+
|
|
14772
|
+
|
|
14773
|
+
|
|
14774
|
+
|
|
14775
|
+
|
|
14776
|
+
|
|
14777
|
+
|
|
14778
|
+
|
|
14779
|
+
|
|
14780
|
+
|
|
14781
|
+
|
|
14782
|
+
|
|
14783
|
+
|
|
14784
|
+
|
|
14785
|
+
|
|
14786
|
+
|
|
14787
|
+
|
|
14788
|
+
|
|
14789
|
+
|
|
14790
|
+
|
|
14791
|
+
|
|
14792
|
+
|
|
14793
|
+
|
|
14794
|
+
|
|
14795
|
+
|
|
14796
|
+
|
|
14797
|
+
|
|
14798
|
+
|
|
14799
|
+
|
|
14800
|
+
|
|
14801
|
+
|
|
14802
|
+
|
|
14803
|
+
|
|
14804
|
+
|
|
14805
|
+
|
|
14806
|
+
|
|
14807
|
+
|
|
14808
|
+
|
|
14809
|
+
|
|
14810
|
+
|
|
14811
|
+
|
|
14812
|
+
|
|
14813
|
+
|
|
14814
|
+
|
|
14815
|
+
|
|
14816
|
+
|
|
14817
|
+
|
|
14818
|
+
|
|
14819
|
+
|
|
14820
|
+
exports.DEFAULT_VECTOR_BLEND_DISTANCE = DEFAULT_VECTOR_BLEND_DISTANCE; exports.DEFAULT_VECTOR_BLEND_STEPS = DEFAULT_VECTOR_BLEND_STEPS; 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_BLEND_MAX_SMOOTH_STEPS = VECTOR_BLEND_MAX_SMOOTH_STEPS; exports.VECTOR_BLEND_MAX_STEPS = VECTOR_BLEND_MAX_STEPS; exports.VECTOR_BLEND_SPACINGS = VECTOR_BLEND_SPACINGS; exports.VECTOR_BLEND_SPACING_LABELS = VECTOR_BLEND_SPACING_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_DISTORT_TOLERANCE = VECTOR_DISTORT_TOLERANCE; exports.VECTOR_EDIT_TOGGLES = VECTOR_EDIT_TOGGLES; exports.VECTOR_EFFECT_DEFAULTS = VECTOR_EFFECT_DEFAULTS; exports.VECTOR_EFFECT_LABELS = VECTOR_EFFECT_LABELS; exports.VECTOR_EFFECT_MENU = VECTOR_EFFECT_MENU; exports.VECTOR_EFFECT_PARAM_SPECS = VECTOR_EFFECT_PARAM_SPECS; exports.VECTOR_EFFECT_TYPES = VECTOR_EFFECT_TYPES; exports.VECTOR_ENVELOPE_STYLE_OPTIONS = VECTOR_ENVELOPE_STYLE_OPTIONS; exports.VECTOR_FILL_GAP = VECTOR_FILL_GAP; exports.VECTOR_GRADIENT_INTERPOLATIONS = VECTOR_GRADIENT_INTERPOLATIONS; exports.VECTOR_GRADIENT_INTERPOLATION_LABELS = VECTOR_GRADIENT_INTERPOLATION_LABELS; exports.VECTOR_GRADIENT_MAX_PERIODS = VECTOR_GRADIENT_MAX_PERIODS; exports.VECTOR_GRADIENT_MIDPOINT_GAP = VECTOR_GRADIENT_MIDPOINT_GAP; exports.VECTOR_GRADIENT_MIN_STOPS = VECTOR_GRADIENT_MIN_STOPS; exports.VECTOR_GRADIENT_OFF_BAR = VECTOR_GRADIENT_OFF_BAR; exports.VECTOR_GRADIENT_SPREADS = VECTOR_GRADIENT_SPREADS; exports.VECTOR_GRADIENT_SPREAD_LABELS = VECTOR_GRADIENT_SPREAD_LABELS; exports.VECTOR_GRADIENT_STOP_GAP = VECTOR_GRADIENT_STOP_GAP; exports.VECTOR_GRADIENT_TYPES = VECTOR_GRADIENT_TYPES; exports.VECTOR_GRADIENT_TYPE_LABELS = VECTOR_GRADIENT_TYPE_LABELS; exports.VECTOR_INK_MAX_CORNERS = VECTOR_INK_MAX_CORNERS; exports.VECTOR_MERGE_MODES = VECTOR_MERGE_MODES; 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_STROKE_GRADIENT_MODES = VECTOR_STROKE_GRADIENT_MODES; exports.VECTOR_STROKE_GRADIENT_MODE_LABELS = VECTOR_STROKE_GRADIENT_MODE_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_WARP_STYLES = VECTOR_WARP_STYLES; exports.VECTOR_WARP_STYLE_LABELS = VECTOR_WARP_STYLE_LABELS; 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.activeVectorEffects = activeVectorEffects; exports.addBuilderHit = addBuilderHit; exports.applyMatrix = applyMatrix; exports.applyMatrixLinear = applyMatrixLinear; exports.applyVectorBlendOptions = applyVectorBlendOptions; exports.applyVectorCornersAttribute = applyVectorCornersAttribute; exports.applyVectorEffects = applyVectorEffects; exports.applyVectorGradientPatch = applyVectorGradientPatch; exports.applyVectorGradientSpread = applyVectorGradientSpread; exports.applyVectorHomography = applyVectorHomography; exports.arrowheadInset = arrowheadInset; exports.arrowheadPath = arrowheadPath; exports.arrowheadWeight = arrowheadWeight; exports.bendSegment = bendSegment; exports.bezierToSubpaths = bezierToSubpaths; exports.boundsFromPoints = boundsFromPoints; exports.boundsIntersect = boundsIntersect; exports.clearVectorLiveBooleanCache = clearVectorLiveBooleanCache; exports.cloneAnchor = cloneAnchor; exports.cloneSubpath = cloneSubpath; exports.cloneVectorDocument = cloneVectorDocument; exports.cloneVectorNode = cloneVectorNode; exports.collectPathNodes = collectPathNodes; exports.constrainToLeave = constrainToLeave; exports.convertAnchor = convertAnchor; exports.convertVectorGradient = convertVectorGradient; exports.cornerBisectorPoint = cornerBisectorPoint; exports.cornerRadiusChange = cornerRadiusChange; exports.cornerSetback = cornerSetback; exports.correspondMorphContours = correspondMorphContours; exports.createVectorCommands = createVectorCommands; exports.createVectorEffect = createVectorEffect; exports.createVectorMorph = createVectorMorph; exports.curvatureMoveAnchor = curvatureMoveAnchor; exports.cutSubpathAt = cutSubpathAt; exports.dashIntervals = dashIntervals; exports.decomposeRigid = decomposeRigid; exports.defaultVectorGradient = defaultVectorGradient; exports.distortVectorNode = distortVectorNode; exports.dragVectorMeshPoint = dragVectorMeshPoint; exports.effectPathLength = effectPathLength; exports.effectPathVertexCount = effectPathVertexCount; exports.effectiveStrokeAlign = effectiveStrokeAlign; exports.ellipseSubpath = ellipseSubpath; exports.eraseFromFill = eraseFromFill; exports.eraseFromOutline = eraseFromOutline; exports.eraserRegion = eraserRegion; exports.evalVectorMesh = evalVectorMesh; exports.evaluateVectorPathKeyframes = evaluateVectorPathKeyframes; exports.expandVectorAppearance = expandVectorAppearance; exports.expandVectorAppearances = expandVectorAppearances; exports.expandVectorBlend = expandVectorBlend; exports.expandVectorCorners = expandVectorCorners; exports.expandVectorCornersOf = expandVectorCornersOf; exports.expandVectorGradientSpread = expandVectorGradientSpread; exports.expandVectorGradientStops = expandVectorGradientStops; exports.explicitVectorGradient = explicitVectorGradient; exports.findVectorNode = findVectorNode; exports.fitCornerRadius = fitCornerRadius; exports.fitVectorMesh = fitVectorMesh; exports.foldVectorBooleanOperands = foldVectorBooleanOperands; exports.generateVectorBlendChildren = generateVectorBlendChildren; exports.generateWidthProfile = generateWidthProfile; exports.getAnchor = getAnchor; exports.getAnchorWorld = getAnchorWorld; exports.getEditablePathIds = getEditablePathIds; exports.getTransformHandlePositions = getTransformHandlePositions; exports.getVectorBlendControls = getVectorBlendControls; exports.getVectorCornerWidgets = getVectorCornerWidgets; exports.getVectorEffectsPanel = getVectorEffectsPanel; exports.getVectorEnteredGroups = getVectorEnteredGroups; exports.getVectorEnvelopePanel = getVectorEnvelopePanel; exports.getVectorEnvelopeTarget = getVectorEnvelopeTarget; exports.getVectorGradientAnnotator = getVectorGradientAnnotator; exports.getVectorGradientEditor = getVectorGradientEditor; 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.gradientMidpointRemap = gradientMidpointRemap; exports.hasExplicitGradientGeometry = hasExplicitGradientGeometry; exports.hasOwnVectorAppearance = hasOwnVectorAppearance; exports.hasPaint = hasPaint; exports.hasStrokeExtras = hasStrokeExtras; exports.hasVectorAppearance = hasVectorAppearance; exports.hasVectorCorners = hasVectorCorners; exports.hitTestVectorNode = hitTestVectorNode; exports.hitTestVectorNodes = hitTestVectorNodes; exports.hitTestVectorStroke = hitTestVectorStroke; exports.hitVectorGradientAnnotator = hitVectorGradientAnnotator; exports.inferAnchorType = inferAnchorType; exports.insertAnchor = insertAnchor; exports.insertVectorGradientStop = insertVectorGradientStop; exports.insertWidthPoint = insertWidthPoint; exports.interpolateMorphContours = interpolateMorphContours; exports.interpolateRigidMatrix = interpolateRigidMatrix; exports.interpolateVectorColor = interpolateVectorColor; exports.interpolateVectorPaint = interpolateVectorPaint; exports.interpolateVectorPaths = interpolateVectorPaths; exports.interpolateVectorStyle = interpolateVectorStyle; exports.interpolateWidthProfiles = interpolateWidthProfiles; exports.invertMatrix = invertMatrix; exports.isCentredVectorGradient = isCentredVectorGradient; exports.isClosedBezierShape = isClosedBezierShape; exports.isIdentityMatrix = isIdentityMatrix; exports.isUniformWidthProfile = isUniformWidthProfile; exports.isValidVectorMesh = isValidVectorMesh; exports.isVectorBlendGroup = isVectorBlendGroup; exports.isVectorGradient = isVectorGradient; exports.isVectorLiveBoolean = isVectorLiveBoolean; exports.isVectorTextTarget = isVectorTextTarget; exports.joinSubpaths = joinSubpaths; exports.knifePath = knifePath; exports.lineSubpath = lineSubpath; exports.locateVectorNode = locateVectorNode; exports.mapBezierPath = mapBezierPath; exports.mapVectorGradient = mapVectorGradient; exports.mapVectorMeshPoints = mapVectorMeshPoints; exports.mapVectorPaint = mapVectorPaint; exports.mapVectorPoints = mapVectorPoints; exports.mapVectorSubpaths = mapVectorSubpaths; exports.matrixRotation = matrixRotation; exports.mergePaths = mergePaths; exports.mirrorWidthProfile = mirrorWidthProfile; exports.morphContourToSubpath = morphContourToSubpath; exports.morphPathsCross = morphPathsCross; exports.moveAnchorHandle = moveAnchorHandle; exports.moveVectorGradientHandle = moveVectorGradientHandle; exports.moveVectorGradientStop = moveVectorGradientStop; exports.multiplyMatrices = multiplyMatrices; exports.nearestSegment = nearestSegment; exports.nearestStrokePosition = nearestStrokePosition; exports.nextVectorCornerKind = nextVectorCornerKind; exports.nodeMatrix = nodeMatrix; exports.normalizeVectorEffectParams = normalizeVectorEffectParams; exports.offsetPaths = offsetPaths; exports.orderVectorQuad = orderVectorQuad; exports.parseSvgTransform = parseSvgTransform; exports.parseVectorColor = parseVectorColor; exports.parseVectorSvg = parseVectorSvg; exports.pathsCenter = pathsCenter; exports.patternAttrs = patternAttrs; exports.periodicVectorGradientStops = periodicVectorGradientStops; exports.pinVectorGradient = pinVectorGradient; exports.planShapeBuilder = planShapeBuilder; exports.polygonSubpath = polygonSubpath; exports.polylineBounds = polylineBounds; exports.pressureWidthProfile = pressureWidthProfile; exports.puckerBloatPaths = puckerBloatPaths; exports.pullVectorMesh = pullVectorMesh; exports.recognizeInkShape = recognizeInkShape; exports.rectSubpath = rectSubpath; exports.refineMorphContour = refineMorphContour; exports.refreshVectorBlends = refreshVectorBlends; exports.releaseVectorBlend = releaseVectorBlend; exports.removeAnchorKeepingShape = removeAnchorKeepingShape; exports.removeAnchors = removeAnchors; exports.removeAnchorsKeepingShape = removeAnchorsKeepingShape; exports.removeRedundantPoints = removeRedundantPoints; exports.removeVectorGradientStop = removeVectorGradientStop; exports.removeVectorMeshSplitU = removeVectorMeshSplitU; exports.removeVectorMeshSplitV = removeVectorMeshSplitV; exports.removeWidthPoints = removeWidthPoints; exports.repeatPaths = repeatPaths; exports.resampleGradientStops = resampleGradientStops; exports.resizeVectorMesh = resizeVectorMesh; exports.resolveVectorBlendOptions = resolveVectorBlendOptions; exports.reverseMorphContour = reverseMorphContour; exports.reverseSubpath = reverseSubpath; exports.reverseVectorGradient = reverseVectorGradient; exports.reverseWidthProfile = reverseWidthProfile; exports.rotateMatrix = rotateMatrix; exports.roundCornerPaths = roundCornerPaths; exports.roundSubpaths = roundSubpaths; exports.samplePlainStops = samplePlainStops; exports.samplePolyline = samplePolyline; exports.sampleVectorGradient = sampleVectorGradient; exports.sampleVectorGradientAt = sampleVectorGradientAt; exports.sampleVectorPaintDefAt = sampleVectorPaintDefAt; exports.sanitizeVectorEffects = sanitizeVectorEffects; exports.sanitizeVectorGradient = sanitizeVectorGradient; exports.sanitizeWidthProfile = sanitizeWidthProfile; exports.scaleFor = scaleFor; exports.scaleMatrix = scaleMatrix; exports.setAnchorCorner = setAnchorCorner; exports.setSubpathCorners = setSubpathCorners; exports.setVectorGradientVector = setVectorGradientVector; exports.setWidthPoint = setWidthPoint; exports.simplifyPolyline = simplifyPolyline; exports.smoothSubpath = smoothSubpath; exports.solve8 = solve8; exports.sortedVectorGradientStops = sortedVectorGradientStops; exports.spanVectorGradientStops = spanVectorGradientStops; exports.splitIntoFaces = splitIntoFaces; exports.splitSubpathAt = splitSubpathAt; exports.splitVectorMeshU = splitVectorMeshU; exports.splitVectorMeshV = splitVectorMeshV; exports.starSubpath = starSubpath; exports.strokePositionPoint = strokePositionPoint; exports.strokeWidthProfileOf = strokeWidthProfileOf; exports.subpathEnclosesArea = subpathEnclosesArea; exports.subpathPointAt = subpathPointAt; exports.subpathSegment = subpathSegment; exports.subpathSegmentCount = subpathSegmentCount; exports.subpathToMorphContour = subpathToMorphContour; exports.subpathsToBezier = subpathsToBezier; exports.taperWaveFactor = taperWaveFactor; exports.toVectorKeyInput = toVectorKeyInput; exports.toVectorModifiers = toVectorModifiers; exports.toVectorPointerInput = toVectorPointerInput; exports.transformVectorEffects = transformVectorEffects; exports.transformVectorGradient = transformVectorGradient; exports.transformVectorNode = transformVectorNode; exports.transformVectorPaint = transformVectorPaint; exports.translateAnchor = translateAnchor; exports.translateMatrix = translateMatrix; exports.trimIntervals = trimIntervals; exports.trimPaths = trimPaths; exports.trimPathsIndividually = trimPathsIndividually; exports.turnMorphContour = turnMorphContour; exports.twistPaths = twistPaths; exports.unionBounds = unionBounds; exports.variableStrokeOutline = variableStrokeOutline; exports.variableStrokeRings = variableStrokeRings; exports.vectorAppearanceNodes = vectorAppearanceNodes; exports.vectorAppearanceOutline = vectorAppearanceOutline; exports.vectorAppearanceShapes = vectorAppearanceShapes; exports.vectorBlendColorDistance = vectorBlendColorDistance; exports.vectorBlendKeyTargets = vectorBlendKeyTargets; exports.vectorBlendKeys = vectorBlendKeys; exports.vectorBlendRail = vectorBlendRail; exports.vectorBlendRailAt = vectorBlendRailAt; exports.vectorBlendSpine = vectorBlendSpine; exports.vectorBlendStepCount = vectorBlendStepCount; exports.vectorBoxCorners = vectorBoxCorners; exports.vectorBoxMatrix = vectorBoxMatrix; exports.vectorBuilderErasedEdges = vectorBuilderErasedEdges; exports.vectorCornerAt = vectorCornerAt; exports.vectorCorners = vectorCorners; exports.vectorCornersAttribute = vectorCornersAttribute; exports.vectorDiamondPath = vectorDiamondPath; exports.vectorDistortQuad = vectorDistortQuad; exports.vectorDocumentToSvg = vectorDocumentToSvg; exports.vectorEffectInputBounds = vectorEffectInputBounds; exports.vectorEffectInputPaths = vectorEffectInputPaths; exports.vectorEnteredGroups = vectorEnteredGroups; exports.vectorEnvelopeFrame = vectorEnvelopeFrame; exports.vectorEnvelopeMap = vectorEnvelopeMap; exports.vectorEnvelopeMesh = vectorEnvelopeMesh; exports.vectorFillMap = vectorFillMap; exports.vectorGradientArea = vectorGradientArea; exports.vectorGradientAspect = vectorGradientAspect; exports.vectorGradientBarPosition = vectorGradientBarPosition; exports.vectorGradientFocalParam = vectorGradientFocalParam; exports.vectorGradientHandles = vectorGradientHandles; exports.vectorGradientMatrix = vectorGradientMatrix; exports.vectorGradientMidpointFromPosition = vectorGradientMidpointFromPosition; exports.vectorGradientMidpointPosition = vectorGradientMidpointPosition; exports.vectorGradientNeedsExpansion = vectorGradientNeedsExpansion; exports.vectorGradientParam = vectorGradientParam; exports.vectorGradientPoints = vectorGradientPoints; exports.vectorGradientRamp = vectorGradientRamp; exports.vectorGradientSvgDefs = vectorGradientSvgDefs; exports.vectorGradientTAt = vectorGradientTAt; exports.vectorGradientTargetPath = vectorGradientTargetPath; exports.vectorGradientUnitsMatrix = vectorGradientUnitsMatrix; exports.vectorHomography = vectorHomography; exports.vectorHomographyKeepsQuad = vectorHomographyKeepsQuad; exports.vectorIdentityMesh = vectorIdentityMesh; exports.vectorInkShapeName = vectorInkShapeName; exports.vectorLiveBooleanSteps = vectorLiveBooleanSteps; exports.vectorMeshColumns = vectorMeshColumns; exports.vectorMeshControlBounds = vectorMeshControlBounds; exports.vectorMeshEditPoints = vectorMeshEditPoints; exports.vectorMeshFromOutline = vectorMeshFromOutline; exports.vectorMeshGridCurves = vectorMeshGridCurves; exports.vectorMeshOutline = vectorMeshOutline; exports.vectorMeshParamAt = vectorMeshParamAt; exports.vectorMeshRows = vectorMeshRows; exports.vectorNodeBounds = vectorNodeBounds; exports.vectorNodeEnvelope = vectorNodeEnvelope; exports.vectorNodeRotation = vectorNodeRotation; exports.vectorNodeToBezier = vectorNodeToBezier; exports.vectorOperandOperation = vectorOperandOperation; exports.vectorPaintToHex = vectorPaintToHex; exports.vectorPaintToSvg = vectorPaintToSvg; exports.vectorParentMatrix = vectorParentMatrix; exports.vectorPathData = vectorPathData; exports.vectorPathEntries = vectorPathEntries; exports.vectorPathLocalBounds = vectorPathLocalBounds; exports.vectorPathWorldBezier = vectorPathWorldBezier; exports.vectorPathfinderShape = vectorPathfinderShape; exports.vectorRepeaterCopies = vectorRepeaterCopies; exports.vectorResizeCursor = vectorResizeCursor; exports.vectorResultStyle = vectorResultStyle; exports.vectorShapeBuilderHit = vectorShapeBuilderHit; exports.vectorShapeBuilderMap = vectorShapeBuilderMap; exports.vectorShearForSide = vectorShearForSide; exports.vectorSkewMatrix = vectorSkewMatrix; exports.vectorStrokeGradientDefs = vectorStrokeGradientDefs; 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.vectorWarpPresetGrid = vectorWarpPresetGrid; exports.vectorWarpPresetMesh = vectorWarpPresetMesh; exports.vectorWorldMatrix = vectorWorldMatrix; exports.walkVectorNodes = walkVectorNodes; exports.widthProfileAt = widthProfileAt; exports.widthProfileFromAttribute = widthProfileFromAttribute; exports.widthProfileMaxScale = widthProfileMaxScale; exports.widthProfilePreset = widthProfilePreset; exports.widthProfilePresetId = widthProfilePresetId; exports.widthProfileToAttribute = widthProfileToAttribute; exports.wigglePaths = wigglePaths; exports.zigzagPaths = zigzagPaths;
|
|
13140
14821
|
//# sourceMappingURL=index.cjs.map
|