@pixerate/editor 0.130.0 → 0.133.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/dist/animation-editor/index.cjs +55 -55
- package/dist/animation-editor/index.d.cts +4 -4
- package/dist/animation-editor/index.d.ts +4 -4
- package/dist/animation-editor/index.js +2 -2
- package/dist/{bezier-CigmusV_.d.ts → bezier-BAGdL89w.d.ts} +1 -1
- package/dist/{bezier-CdoGygwG.d.cts → bezier-DL2wPsFf.d.cts} +1 -1
- package/dist/canvas/index.d.cts +7 -7
- package/dist/canvas/index.d.ts +7 -7
- package/dist/{chunk-MZXQTKUM.cjs → chunk-24ATT2PE.cjs} +10 -6
- package/dist/chunk-24ATT2PE.cjs.map +1 -0
- package/dist/{chunk-AHUYMDYW.js → chunk-2HC4DRF4.js} +10 -6
- package/dist/chunk-2HC4DRF4.js.map +1 -0
- package/dist/{chunk-2PXRKMOH.cjs → chunk-2QKUD3E2.cjs} +36 -36
- package/dist/{chunk-2PXRKMOH.cjs.map → chunk-2QKUD3E2.cjs.map} +1 -1
- package/dist/{chunk-PMHPXCJC.cjs → chunk-65GNHOD4.cjs} +268 -199
- package/dist/chunk-65GNHOD4.cjs.map +1 -0
- package/dist/{chunk-YRZ6NVE3.js → chunk-6CTZAGZ2.js} +235 -4
- package/dist/chunk-6CTZAGZ2.js.map +1 -0
- package/dist/{chunk-ERYGCA72.js → chunk-AOCFL7L7.js} +88 -19
- package/dist/chunk-AOCFL7L7.js.map +1 -0
- package/dist/{chunk-LXGOYRPE.cjs → chunk-F7GGEAO2.cjs} +322 -75
- package/dist/chunk-F7GGEAO2.cjs.map +1 -0
- package/dist/{chunk-PRYMC442.js → chunk-FOBB6AIO.js} +257 -10
- package/dist/chunk-FOBB6AIO.js.map +1 -0
- package/dist/{chunk-W6M7C7R3.cjs → chunk-NVTHUPJ6.cjs} +236 -5
- package/dist/chunk-NVTHUPJ6.cjs.map +1 -0
- package/dist/{chunk-L5OTIYOO.js → chunk-VGZSIXX3.js} +2 -2
- package/dist/effects/index.d.cts +4 -4
- package/dist/effects/index.d.ts +4 -4
- package/dist/{export-CejjC2iI.d.cts → export-BICOEM9d.d.cts} +33 -11
- package/dist/{export-5WDKJqTy.d.cts → export-CeFplzAW.d.cts} +1 -1
- package/dist/{export-B4r8b9Ft.d.ts → export-XnuX8FZ2.d.ts} +33 -11
- package/dist/{export-CU_ARP3A.d.ts → export-zB4HITwP.d.ts} +1 -1
- package/dist/{helpers-CzZu51eI.d.cts → helpers-BuKdqUlM.d.cts} +56 -1
- package/dist/{helpers-X_rycLNJ.d.ts → helpers-cssRNUzH.d.ts} +56 -1
- package/dist/image-editor/index.cjs +1064 -903
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +32 -13
- package/dist/image-editor/index.d.ts +32 -13
- package/dist/image-editor/index.js +180 -19
- package/dist/image-editor/index.js.map +1 -1
- package/dist/index.cjs +11 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/dist/{opentype-DlRMYcCW.d.cts → opentype-C3iyIFRx.d.cts} +1 -1
- package/dist/{opentype-CrHAsKh3.d.ts → opentype-DG5Lkwul.d.ts} +1 -1
- package/dist/paint/index.cjs +8 -2
- package/dist/paint/index.cjs.map +1 -1
- package/dist/paint/index.d.cts +14 -3
- package/dist/paint/index.d.ts +14 -3
- package/dist/paint/index.js +7 -1
- package/dist/paint-editor/index.cjs +78 -78
- package/dist/paint-editor/index.d.cts +7 -7
- package/dist/paint-editor/index.d.ts +7 -7
- package/dist/paint-editor/index.js +3 -3
- package/dist/{pathfinder-CKfKOVP4.d.cts → pathfinder-8vXik95z.d.cts} +1 -1
- package/dist/{pathfinder-Dlss70hL.d.ts → pathfinder-DKLt4UDG.d.ts} +1 -1
- package/dist/{pool-DDOo0xJH.d.ts → pool-C69pkWRz.d.ts} +1 -1
- package/dist/{pool-DKic69LD.d.cts → pool-VAWcYUbs.d.cts} +1 -1
- package/dist/{rand-pQQ2sJTk.d.ts → rand-BaqEOs1Y.d.ts} +17 -4
- package/dist/{rand-DTXAssW1.d.cts → rand-DdpFzCo6.d.cts} +17 -4
- package/dist/raster/index.cjs +2 -2
- package/dist/raster/index.d.cts +4 -4
- package/dist/raster/index.d.ts +4 -4
- package/dist/raster/index.js +1 -1
- package/dist/{svg-BRaii3pI.d.cts → svg-BThlZmja.d.cts} +2 -2
- package/dist/{svg-BYVZeVo0.d.ts → svg-CEYpvsgH.d.ts} +2 -2
- package/dist/{tools-CtheDLDr.d.cts → tools-CRnZJXXr.d.cts} +1 -1
- package/dist/{tools-D8bZ-7YG.d.ts → tools-CVGqEpO8.d.ts} +1 -1
- package/dist/vector/index.cjs +1493 -1032
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +155 -12
- package/dist/vector/index.d.ts +155 -12
- package/dist/vector/index.js +469 -8
- package/dist/vector/index.js.map +1 -1
- package/dist/video-editor/index.d.cts +4 -4
- package/dist/video-editor/index.d.ts +4 -4
- package/dist/{warp-BFoYxy_s.d.cts → warp-ChcFDdlT.d.cts} +1 -1
- package/dist/{warp-CZVC8pB5.d.ts → warp-mKylbLiF.d.ts} +1 -1
- package/package.json +2 -2
- package/skills/pixerate-image-editor/SKILL.md +7 -3
- package/skills/pixerate-image-editor/references/color-management.md +1 -1
- package/skills/pixerate-image-editor/references/photoshop-files.md +2 -2
- package/skills/pixerate-image-editor/references/retouching.md +12 -3
- package/skills/pixerate-vector/SKILL.md +17 -0
- package/skills/pixerate-vector/references/commands.md +19 -0
- package/dist/chunk-AHUYMDYW.js.map +0 -1
- package/dist/chunk-ERYGCA72.js.map +0 -1
- package/dist/chunk-LXGOYRPE.cjs.map +0 -1
- package/dist/chunk-MZXQTKUM.cjs.map +0 -1
- package/dist/chunk-PMHPXCJC.cjs.map +0 -1
- package/dist/chunk-PRYMC442.js.map +0 -1
- package/dist/chunk-W6M7C7R3.cjs.map +0 -1
- package/dist/chunk-YRZ6NVE3.js.map +0 -1
- /package/dist/{chunk-L5OTIYOO.js.map → chunk-VGZSIXX3.js.map} +0 -0
package/dist/vector/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
applyHomography,
|
|
13
13
|
homographyFromPoints,
|
|
14
14
|
homographyKeepsQuad,
|
|
15
|
+
invertHomography,
|
|
15
16
|
orderQuad,
|
|
16
17
|
solve8
|
|
17
18
|
} from "../chunk-GX332W2C.js";
|
|
@@ -42,7 +43,7 @@ import {
|
|
|
42
43
|
reverseMorphContour,
|
|
43
44
|
subpathToMorphContour,
|
|
44
45
|
turnMorphContour
|
|
45
|
-
} from "../chunk-
|
|
46
|
+
} from "../chunk-VGZSIXX3.js";
|
|
46
47
|
import {
|
|
47
48
|
DEFAULT_VECTOR_FONT,
|
|
48
49
|
IDENTITY_MATRIX,
|
|
@@ -74,12 +75,16 @@ import {
|
|
|
74
75
|
VECTOR_GRADIENT_TYPES,
|
|
75
76
|
VECTOR_HORIZONTAL_RESIZING,
|
|
76
77
|
VECTOR_HORIZONTAL_RESIZING_LABELS,
|
|
78
|
+
VECTOR_LENS_LABELS,
|
|
79
|
+
VECTOR_LENS_SPECS,
|
|
80
|
+
VECTOR_LENS_TYPES,
|
|
77
81
|
VECTOR_MASK_TYPES,
|
|
78
82
|
VECTOR_MERGE_MODES,
|
|
79
83
|
VECTOR_MESH_MAX,
|
|
80
84
|
VECTOR_PARAGRAPH_STYLE_KEYS,
|
|
81
85
|
VECTOR_PATHFINDER_OPERATIONS,
|
|
82
86
|
VECTOR_PATH_TEXT_BASELINES,
|
|
87
|
+
VECTOR_PERSPECTIVE_PLANES,
|
|
83
88
|
VECTOR_PRESSURE_NOMINAL,
|
|
84
89
|
VECTOR_SPATIAL_MIN,
|
|
85
90
|
VECTOR_STROKE_GRADIENT_MODES,
|
|
@@ -198,6 +203,7 @@ import {
|
|
|
198
203
|
isVectorFrame,
|
|
199
204
|
isVectorFreeformGradient,
|
|
200
205
|
isVectorGradient,
|
|
206
|
+
isVectorLens,
|
|
201
207
|
isVectorLiveBoolean,
|
|
202
208
|
isVectorMaskActive,
|
|
203
209
|
isVectorMaskGroup,
|
|
@@ -212,6 +218,7 @@ import {
|
|
|
212
218
|
mapBezierPath,
|
|
213
219
|
mapVectorGradient,
|
|
214
220
|
mapVectorPaint,
|
|
221
|
+
mapVectorPaintColors,
|
|
215
222
|
mapVectorPoints,
|
|
216
223
|
mapVectorShadedPaint,
|
|
217
224
|
mapVectorSubpaths,
|
|
@@ -265,6 +272,7 @@ import {
|
|
|
265
272
|
replaceVectorText,
|
|
266
273
|
rerouteVectorConnectors,
|
|
267
274
|
resizeWarpMesh,
|
|
275
|
+
resolveVectorLenses,
|
|
268
276
|
resolveVectorSymbols,
|
|
269
277
|
reverseSubpath,
|
|
270
278
|
reverseVectorGradient,
|
|
@@ -284,6 +292,7 @@ import {
|
|
|
284
292
|
sanitizeVectorFilters,
|
|
285
293
|
sanitizeVectorFrame,
|
|
286
294
|
sanitizeVectorGradient,
|
|
295
|
+
sanitizeVectorLens,
|
|
287
296
|
sanitizeVectorMask,
|
|
288
297
|
sanitizeVectorResizing,
|
|
289
298
|
sanitizeVectorShadedPaint,
|
|
@@ -309,6 +318,7 @@ import {
|
|
|
309
318
|
splitWarpMeshU,
|
|
310
319
|
splitWarpMeshV,
|
|
311
320
|
starSubpath,
|
|
321
|
+
stripVectorLensViews,
|
|
312
322
|
stripVectorSymbolArt,
|
|
313
323
|
strokePositionPoint,
|
|
314
324
|
strokeWidthProfileOf,
|
|
@@ -387,6 +397,8 @@ import {
|
|
|
387
397
|
vectorGradientUnitsMatrix,
|
|
388
398
|
vectorInstanceDrawn,
|
|
389
399
|
vectorInstanceGroup,
|
|
400
|
+
vectorLensColorMap,
|
|
401
|
+
vectorLensDrawn,
|
|
390
402
|
vectorLiveBooleanSteps,
|
|
391
403
|
vectorMaskContains,
|
|
392
404
|
vectorMaskContentBounds,
|
|
@@ -483,7 +495,7 @@ import {
|
|
|
483
495
|
withVectorStrokes,
|
|
484
496
|
withVectorTargetPaint,
|
|
485
497
|
zigzagPaths
|
|
486
|
-
} from "../chunk-
|
|
498
|
+
} from "../chunk-FOBB6AIO.js";
|
|
487
499
|
import {
|
|
488
500
|
bezierPathBounds,
|
|
489
501
|
bezierPathToSvg,
|
|
@@ -824,6 +836,131 @@ function releaseVectorBlend(group, newId) {
|
|
|
824
836
|
return [...keys, group.transform ? transformVectorNode(path, m) : path];
|
|
825
837
|
}
|
|
826
838
|
|
|
839
|
+
// src/vector/perspective.ts
|
|
840
|
+
function vectorPerspectivePlanes(p) {
|
|
841
|
+
return p.vanishingPoints.length <= 1 ? ["floor", "side", "front"] : ["floor", "left", "right"];
|
|
842
|
+
}
|
|
843
|
+
function sanitizeVectorPerspective(value) {
|
|
844
|
+
if (!value || typeof value !== "object") return null;
|
|
845
|
+
const r = value;
|
|
846
|
+
const isPt = (v) => !!v && typeof v === "object" && Number.isFinite(v.x) && Number.isFinite(v.y);
|
|
847
|
+
if (!Array.isArray(r.vanishingPoints) || r.vanishingPoints.length < 1 || r.vanishingPoints.length > 3 || !r.vanishingPoints.every(isPt) || !isPt(r.origin)) return null;
|
|
848
|
+
const origin = { x: r.origin.x, y: r.origin.y };
|
|
849
|
+
const vps = r.vanishingPoints.map((v) => ({ x: v.x, y: v.y }));
|
|
850
|
+
if (vps.some((v) => Math.hypot(v.x - origin.x, v.y - origin.y) < 1e-6)) return null;
|
|
851
|
+
const out = { vanishingPoints: vps, origin };
|
|
852
|
+
if (typeof r.gridSize === "number" && r.gridSize > 0 && Number.isFinite(r.gridSize)) out.gridSize = Math.min(1e3, r.gridSize);
|
|
853
|
+
if (typeof r.extent === "number" && Number.isFinite(r.extent)) out.extent = Math.min(100, Math.max(1, Math.round(r.extent)));
|
|
854
|
+
if (r.visible === false) out.visible = false;
|
|
855
|
+
return out;
|
|
856
|
+
}
|
|
857
|
+
function towards(o, vp, want) {
|
|
858
|
+
const d = Math.hypot(vp.x - o.x, vp.y - o.y);
|
|
859
|
+
let a = 1 / d;
|
|
860
|
+
if (want === "right" ? vp.x - o.x < 0 : vp.y - o.y > 0) a = -a;
|
|
861
|
+
return [a * vp.x, a * vp.y, a];
|
|
862
|
+
}
|
|
863
|
+
function vectorPerspectivePlaneMap(p, plane) {
|
|
864
|
+
if (!vectorPerspectivePlanes(p).includes(plane)) return null;
|
|
865
|
+
const o = p.origin;
|
|
866
|
+
const [v1, v2, v3] = p.vanishingPoints;
|
|
867
|
+
const right = [1, 0, 0];
|
|
868
|
+
const up = v3 ? towards(o, v3, "up") : [0, -1, 0];
|
|
869
|
+
let x;
|
|
870
|
+
let y;
|
|
871
|
+
if (p.vanishingPoints.length <= 1) {
|
|
872
|
+
if (plane === "floor") [x, y] = [right, towards(o, v1, "up")];
|
|
873
|
+
else if (plane === "side") [x, y] = [towards(o, v1, "right"), up];
|
|
874
|
+
else [x, y] = [right, up];
|
|
875
|
+
} else if (plane === "floor") [x, y] = [towards(o, v2, "right"), towards(o, v1, "up")];
|
|
876
|
+
else if (plane === "left") [x, y] = [towards(o, v1, "right"), up];
|
|
877
|
+
else [x, y] = [towards(o, v2, "right"), up];
|
|
878
|
+
return [x[0], y[0], o.x, x[1], y[1], o.y, x[2], y[2], 1];
|
|
879
|
+
}
|
|
880
|
+
function vectorPerspectiveFlatToPlane(p, plane) {
|
|
881
|
+
const h = vectorPerspectivePlaneMap(p, plane);
|
|
882
|
+
if (!h) return null;
|
|
883
|
+
const o = p.origin;
|
|
884
|
+
return (q) => {
|
|
885
|
+
const u = q.x - o.x;
|
|
886
|
+
const v = o.y - q.y;
|
|
887
|
+
const w = h[6] * u + h[7] * v + h[8];
|
|
888
|
+
if (!(w > 1e-6)) return null;
|
|
889
|
+
return applyHomography(h, { x: u, y: v });
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
function vectorPerspectivePlaneToFlat(p, plane) {
|
|
893
|
+
const h = vectorPerspectivePlaneMap(p, plane);
|
|
894
|
+
const inv = h ? invertHomography(h) : null;
|
|
895
|
+
if (!inv) return null;
|
|
896
|
+
const o = p.origin;
|
|
897
|
+
return (q) => {
|
|
898
|
+
const f = applyHomography(inv, q);
|
|
899
|
+
if (!f) return null;
|
|
900
|
+
const w = h[6] * f.x + h[7] * f.y + h[8];
|
|
901
|
+
if (!(w > 1e-6)) return null;
|
|
902
|
+
return { x: o.x + f.x, y: o.y - f.y };
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
function vectorPerspectiveMapPath(p, plane, path) {
|
|
906
|
+
const f = vectorPerspectiveFlatToPlane(p, plane);
|
|
907
|
+
if (!f) return null;
|
|
908
|
+
let behind = false;
|
|
909
|
+
const out = mapBezierPath(
|
|
910
|
+
path,
|
|
911
|
+
(q) => {
|
|
912
|
+
const r = f(q);
|
|
913
|
+
if (!r) {
|
|
914
|
+
behind = true;
|
|
915
|
+
return q;
|
|
916
|
+
}
|
|
917
|
+
return r;
|
|
918
|
+
},
|
|
919
|
+
0.1
|
|
920
|
+
);
|
|
921
|
+
return behind ? null : out;
|
|
922
|
+
}
|
|
923
|
+
function vectorPerspectiveGridLines(p, plane) {
|
|
924
|
+
const h = vectorPerspectivePlaneMap(p, plane);
|
|
925
|
+
if (!h) return [];
|
|
926
|
+
const g = p.gridSize ?? 20;
|
|
927
|
+
const n2 = p.extent ?? 12;
|
|
928
|
+
const max = n2 * g;
|
|
929
|
+
const lo = (axis) => axis === "y" && plane !== "floor" ? 0 : -max;
|
|
930
|
+
const w = (u, v) => h[6] * u + h[7] * v + h[8];
|
|
931
|
+
const at = (u, v) => applyHomography(h, { x: u, y: v });
|
|
932
|
+
const segment = (u0, v0, u1, v1) => {
|
|
933
|
+
const wa = w(u0, v0);
|
|
934
|
+
const wb = w(u1, v1);
|
|
935
|
+
const min = 0.05;
|
|
936
|
+
if (wa < min && wb < min) return null;
|
|
937
|
+
let t0 = 0;
|
|
938
|
+
let t1 = 1;
|
|
939
|
+
if (wa < min) t0 = (min - wa) / (wb - wa);
|
|
940
|
+
if (wb < min) t1 = (min - wa) / (wb - wa);
|
|
941
|
+
const a = at(u0 + (u1 - u0) * t0, v0 + (v1 - v0) * t0);
|
|
942
|
+
const b = at(u0 + (u1 - u0) * t1, v0 + (v1 - v0) * t1);
|
|
943
|
+
return a && b ? { a, b } : null;
|
|
944
|
+
};
|
|
945
|
+
const out = [];
|
|
946
|
+
for (let k = lo("x") / g; k <= n2; k++) {
|
|
947
|
+
const s = segment(k * g, lo("y"), k * g, max);
|
|
948
|
+
if (s) out.push(s);
|
|
949
|
+
}
|
|
950
|
+
for (let k = lo("y") / g; k <= n2; k++) {
|
|
951
|
+
const s = segment(lo("x"), k * g, max, k * g);
|
|
952
|
+
if (s) out.push(s);
|
|
953
|
+
}
|
|
954
|
+
return out;
|
|
955
|
+
}
|
|
956
|
+
function vectorPerspectivePreset(points, width, height) {
|
|
957
|
+
const horizon = height * 0.35;
|
|
958
|
+
const origin = { x: width / 2, y: height * 0.8 };
|
|
959
|
+
const vps = points === 1 ? [{ x: width / 2, y: horizon }] : [{ x: -width * 0.3, y: horizon }, { x: width * 1.3, y: horizon }];
|
|
960
|
+
if (points === 3) vps.push({ x: width / 2, y: height * 3 });
|
|
961
|
+
return { vanishingPoints: vps, origin, gridSize: Math.max(4, Math.round(Math.min(width, height) / 20)), extent: 12 };
|
|
962
|
+
}
|
|
963
|
+
|
|
827
964
|
// src/vector/constraints/lm.ts
|
|
828
965
|
var MAX_ROWS = 800;
|
|
829
966
|
var maxAbs = (v) => v.reduce((m, a) => Number.isFinite(a) ? Math.max(m, Math.abs(a)) : Infinity, 0);
|
|
@@ -2296,12 +2433,20 @@ function collapsedNode(node, box, prefix) {
|
|
|
2296
2433
|
byPrefix.set(prefix, out);
|
|
2297
2434
|
return out;
|
|
2298
2435
|
}
|
|
2436
|
+
var lensResolved = /* @__PURE__ */ new WeakMap();
|
|
2437
|
+
function resolvedLensNodes(doc) {
|
|
2438
|
+
const hit = lensResolved.get(doc.nodes);
|
|
2439
|
+
if (hit) return hit;
|
|
2440
|
+
const nodes = resolveVectorLenses(doc).nodes;
|
|
2441
|
+
lensResolved.set(doc.nodes, nodes);
|
|
2442
|
+
return nodes;
|
|
2443
|
+
}
|
|
2299
2444
|
function getVectorSceneRenderData(state, options = {}) {
|
|
2300
2445
|
const defs = [];
|
|
2301
2446
|
const filters = [];
|
|
2302
2447
|
const prefix = options.idPrefix ?? "ve-";
|
|
2303
2448
|
const v = state.viewport;
|
|
2304
|
-
const all = state.document
|
|
2449
|
+
const all = resolvedLensNodes(state.document);
|
|
2305
2450
|
const stats = { nodes: all.length, culled: 0, collapsed: 0 };
|
|
2306
2451
|
let nodes;
|
|
2307
2452
|
const size = options.viewportSize;
|
|
@@ -2396,6 +2541,21 @@ function shadingOverlay(state) {
|
|
|
2396
2541
|
}
|
|
2397
2542
|
return out;
|
|
2398
2543
|
}
|
|
2544
|
+
function perspectiveOverlay(state) {
|
|
2545
|
+
const grid = state.document.perspective;
|
|
2546
|
+
if (!grid || grid.visible === false) return null;
|
|
2547
|
+
const r = (n2) => Math.round(n2 * 10) / 10;
|
|
2548
|
+
const planes = vectorPerspectivePlanes(grid).map((plane) => ({
|
|
2549
|
+
plane,
|
|
2550
|
+
active: state.perspectivePlane === plane,
|
|
2551
|
+
d: vectorPerspectiveGridLines(grid, plane).map(({ a, b }) => {
|
|
2552
|
+
const p = toScreen(state, a);
|
|
2553
|
+
const q = toScreen(state, b);
|
|
2554
|
+
return `M${r(p.x)} ${r(p.y)}L${r(q.x)} ${r(q.y)}`;
|
|
2555
|
+
}).join("")
|
|
2556
|
+
}));
|
|
2557
|
+
return { planes, vanishingPoints: grid.vanishingPoints.map((v) => toScreen(state, v)), origin: toScreen(state, grid.origin) };
|
|
2558
|
+
}
|
|
2399
2559
|
function symmetryOverlay(state) {
|
|
2400
2560
|
const ids = /* @__PURE__ */ new Set([...state.selection, ...state.symmetryTarget ? [state.symmetryTarget] : []]);
|
|
2401
2561
|
const out = [];
|
|
@@ -2709,6 +2869,7 @@ function getVectorOverlayRenderData(state) {
|
|
|
2709
2869
|
connectorSites: connectorSiteOverlay(state),
|
|
2710
2870
|
shading: shadingOverlay(state),
|
|
2711
2871
|
symmetry: symmetryOverlay(state),
|
|
2872
|
+
perspective: perspectiveOverlay(state),
|
|
2712
2873
|
trackingPoints: (state.trackingPoints ?? []).map((p) => toScreen(state, p)),
|
|
2713
2874
|
typedEntry: state.typedEntry ? { text: state.typedEntry, ...state.pointer ? toScreen(state, state.pointer) : { x: 0, y: 0 } } : null
|
|
2714
2875
|
};
|
|
@@ -3517,6 +3678,7 @@ ${offset}
|
|
|
3517
3678
|
var pdfString = (s) => `(${s.replace(/[\\()]/g, (c) => `\\${c}`).replace(/[^\x20-\x7e]/g, "?")})`;
|
|
3518
3679
|
function vectorDocumentToPdf(doc, options = {}) {
|
|
3519
3680
|
const notes = /* @__PURE__ */ new Set();
|
|
3681
|
+
doc = resolveVectorLenses(doc);
|
|
3520
3682
|
const scale = options.scale ?? 1;
|
|
3521
3683
|
const compress = options.compress !== false;
|
|
3522
3684
|
const frames = options.pages === "artboards" ? vectorArtboards(doc) : [];
|
|
@@ -3730,8 +3892,9 @@ function nodeGroup(node, notes) {
|
|
|
3730
3892
|
const m = nodeMatrix(node);
|
|
3731
3893
|
let items = [];
|
|
3732
3894
|
const live = (node.effects ?? []).some((e) => e.enabled !== false && (e.type === "wiggle" || e.type === "envelope" || e.type === "contour" || e.type === "blockShadow" || e.type === "extrude" || e.type === "bevel"));
|
|
3733
|
-
if (node.type === "text" || node.type === "instance" || live || isVectorMaskGroup(node) || isVectorFrame(node) || isVectorSymmetryGroup(node)) {
|
|
3895
|
+
if (node.type === "text" || node.type === "instance" || live || isVectorMaskGroup(node) || isVectorFrame(node) || isVectorSymmetryGroup(node) || isVectorLens(node)) {
|
|
3734
3896
|
if (live) notes.push(`${label(node)}: wiggle, envelope, contour, block shadow, extrude and bevel effects have no Lottie equivalent (exported as drawn).`);
|
|
3897
|
+
if (isVectorLens(node)) notes.push(`${label(node)}: a lens exports as drawn (what it shows now, clipped by its outline).`);
|
|
3735
3898
|
if (isVectorMaskGroup(node) && node.mask?.type !== "clip") notes.push(`${label(node)}: opacity masks are not exported (the contents are drawn whole).`);
|
|
3736
3899
|
const drawn = isVectorFrame(node) ? vectorFrameDrawn(node) : node;
|
|
3737
3900
|
const shapes = isVectorMaskGroup(drawn) && drawn.mask?.type === "clip" ? vectorAppearanceShapes({ ...drawn, transform: void 0 }) : null;
|
|
@@ -3785,6 +3948,7 @@ function vectorDocumentToLottie(doc, options = {}) {
|
|
|
3785
3948
|
const fps = options.fps ?? 30;
|
|
3786
3949
|
const op = Math.max(1, Math.round(options.frames ?? 1));
|
|
3787
3950
|
const shapes = [];
|
|
3951
|
+
if (!options.nodes) doc = resolveVectorLenses(doc);
|
|
3788
3952
|
for (const n2 of [...options.nodes ?? doc.nodes].reverse()) {
|
|
3789
3953
|
const g = nodeGroup(n2, notes);
|
|
3790
3954
|
if (g) shapes.push(g);
|
|
@@ -6966,6 +7130,7 @@ var VectorEditorController = class _VectorEditorController {
|
|
|
6966
7130
|
typedEntry: this.typed,
|
|
6967
7131
|
shadingPoint: this.getShadingSelection(),
|
|
6968
7132
|
symmetryTarget: this.symmetryTarget && this.doc.nodes.some((n2) => n2.id === this.symmetryTarget) ? this.symmetryTarget : null,
|
|
7133
|
+
perspectivePlane: this.perspectivePlane && this.doc.perspective && vectorPerspectivePlanes(this.doc.perspective).includes(this.perspectivePlane) ? this.perspectivePlane : null,
|
|
6969
7134
|
canUndo: h.canUndo,
|
|
6970
7135
|
canRedo: h.canRedo,
|
|
6971
7136
|
undoLabel: h.undoName,
|
|
@@ -6982,7 +7147,7 @@ var VectorEditorController = class _VectorEditorController {
|
|
|
6982
7147
|
out = { ...out, symbols: out.symbols.map((s) => s.id === edit.symbolId ? { ...s, nodes: out.nodes } : s) };
|
|
6983
7148
|
}
|
|
6984
7149
|
out = resolveVectorSymbols(out);
|
|
6985
|
-
return rerouteVectorConnectors(this.solved(out));
|
|
7150
|
+
return resolveVectorLenses(rerouteVectorConnectors(this.solved(out)));
|
|
6986
7151
|
}
|
|
6987
7152
|
/**
|
|
6988
7153
|
* `doc` with its constraints solved (geometry edited since the last solve moving least) and
|
|
@@ -7476,7 +7641,7 @@ var VectorEditorController = class _VectorEditorController {
|
|
|
7476
7641
|
return vectorDocumentToSvg(this.storedDocument(), options);
|
|
7477
7642
|
}
|
|
7478
7643
|
toJSON() {
|
|
7479
|
-
return cloneVectorDocument(stripVectorSymbolArt(this.storedDocument()));
|
|
7644
|
+
return cloneVectorDocument(stripVectorLensViews(stripVectorSymbolArt(this.storedDocument())));
|
|
7480
7645
|
}
|
|
7481
7646
|
/** Adds a node (ids are kept unless taken). Returns its id. */
|
|
7482
7647
|
addNode(node, options = {}) {
|
|
@@ -9493,6 +9658,109 @@ var VectorEditorController = class _VectorEditorController {
|
|
|
9493
9658
|
this.notify();
|
|
9494
9659
|
}
|
|
9495
9660
|
// -----------------------------------------------------------------------------------------
|
|
9661
|
+
// Perspective drawing
|
|
9662
|
+
perspectivePlane = null;
|
|
9663
|
+
/** The document's perspective grid, or null. */
|
|
9664
|
+
getPerspective() {
|
|
9665
|
+
return this.doc.perspective ?? null;
|
|
9666
|
+
}
|
|
9667
|
+
/**
|
|
9668
|
+
* Sets the document's perspective grid (CorelDRAW's Perspective Drawing): 1 to 3 vanishing
|
|
9669
|
+
* points, the origin where its planes meet, the cell size and extent, and whether it shows;
|
|
9670
|
+
* `null` removes it. One undo step.
|
|
9671
|
+
*/
|
|
9672
|
+
setPerspective(grid) {
|
|
9673
|
+
let next = null;
|
|
9674
|
+
if (grid) {
|
|
9675
|
+
next = sanitizeVectorPerspective(grid);
|
|
9676
|
+
if (!next) return { ok: false, message: "A perspective grid needs 1 to 3 vanishing points { x, y } away from an origin { x, y }." };
|
|
9677
|
+
}
|
|
9678
|
+
this.change(next ? "Perspective Grid" : "Remove Perspective Grid", () => {
|
|
9679
|
+
const { perspective: _p, ...rest } = this.doc;
|
|
9680
|
+
this.doc = next ? { ...rest, perspective: next } : rest;
|
|
9681
|
+
});
|
|
9682
|
+
if (!next) this.perspectivePlane = null;
|
|
9683
|
+
return { ok: true, perspective: next };
|
|
9684
|
+
}
|
|
9685
|
+
/**
|
|
9686
|
+
* Draws new rectangles, ellipses, polygons and stars on a plane of the perspective grid (their
|
|
9687
|
+
* drag box is taken on the plane, so they recede with it), or flat again with `null`.
|
|
9688
|
+
*/
|
|
9689
|
+
setPerspectivePlane(plane) {
|
|
9690
|
+
if (plane !== null) {
|
|
9691
|
+
const grid = this.doc.perspective;
|
|
9692
|
+
if (!grid) return { ok: false, message: "There is no perspective grid: set one with vector.setPerspective first." };
|
|
9693
|
+
const planes = vectorPerspectivePlanes(grid);
|
|
9694
|
+
if (!planes.includes(plane)) return { ok: false, message: `This grid's planes are ${planes.join(", ")}.` };
|
|
9695
|
+
}
|
|
9696
|
+
this.perspectivePlane = plane;
|
|
9697
|
+
this.notify();
|
|
9698
|
+
return { ok: true };
|
|
9699
|
+
}
|
|
9700
|
+
/**
|
|
9701
|
+
* Lays objects onto a plane of the perspective grid: each is read flat, relative to the grid's
|
|
9702
|
+
* origin (right and up), and projected onto the plane, so art near the origin keeps its size and
|
|
9703
|
+
* art further along recedes. Paths and groups are mapped in document space (their transforms
|
|
9704
|
+
* baked in); text and instances must be converted to outlines first. One undo step. Returns
|
|
9705
|
+
* the ids changed.
|
|
9706
|
+
*/
|
|
9707
|
+
attachToPerspective(plane, options = {}) {
|
|
9708
|
+
const grid = this.doc.perspective;
|
|
9709
|
+
if (!grid) return { ok: false, message: "There is no perspective grid: set one with vector.setPerspective first." };
|
|
9710
|
+
const planes = vectorPerspectivePlanes(grid);
|
|
9711
|
+
if (!planes.includes(plane)) return { ok: false, message: `This grid's planes are ${planes.join(", ")}.` };
|
|
9712
|
+
const ids = [...new Set(options.ids ?? this.selectedRoots())];
|
|
9713
|
+
if (!ids.length) return { ok: false, message: "Select objects to put on the plane first." };
|
|
9714
|
+
const next = /* @__PURE__ */ new Map();
|
|
9715
|
+
const project = (n2, m) => {
|
|
9716
|
+
const own = n2.transform ? multiplyMatrices(m, n2.transform) : m;
|
|
9717
|
+
if (n2.type === "text" || n2.type === "instance") return `"${n2.id}" is ${n2.type === "text" ? "text" : "a symbol instance"}: convert it to outlines first (vector.createOutlines${n2.type === "instance" ? " after vector.detachInstance" : ""}).`;
|
|
9718
|
+
if (n2.type === "group") {
|
|
9719
|
+
const children = [];
|
|
9720
|
+
for (const c of n2.children) {
|
|
9721
|
+
const r = project(c, own);
|
|
9722
|
+
if (typeof r === "string") return r;
|
|
9723
|
+
children.push(r);
|
|
9724
|
+
}
|
|
9725
|
+
const { transform: _t2, ...rest2 } = n2;
|
|
9726
|
+
return { ...rest2, children };
|
|
9727
|
+
}
|
|
9728
|
+
const flat = transformBezierPath(subpathsToBezier(n2.subpaths), own);
|
|
9729
|
+
const mapped = vectorPerspectiveMapPath(grid, plane, flat);
|
|
9730
|
+
if (!mapped) return `"${n2.id}" reaches beyond the plane's horizon: move it nearer the origin, or the vanishing points further out.`;
|
|
9731
|
+
const { transform: _t, ...rest } = n2;
|
|
9732
|
+
return { ...rest, subpaths: bezierToSubpaths(mapped) };
|
|
9733
|
+
};
|
|
9734
|
+
for (const id of ids) {
|
|
9735
|
+
const loc = locateVectorNode(this.doc.nodes, id);
|
|
9736
|
+
if (!loc) return { ok: false, message: `There is no node "${id}".` };
|
|
9737
|
+
const node = loc.list[loc.index];
|
|
9738
|
+
if (node.locked) return { ok: false, message: `"${id}" is locked; unlock it first.` };
|
|
9739
|
+
const parentM = this.parentMatrixOf(id);
|
|
9740
|
+
const r = project(node, parentM);
|
|
9741
|
+
if (typeof r === "string") return { ok: false, message: r };
|
|
9742
|
+
const inv = invertMatrix(parentM);
|
|
9743
|
+
next.set(id, isIdentityMatrix(inv) ? r : transformVectorNode(r, inv));
|
|
9744
|
+
}
|
|
9745
|
+
this.change(`Attach to ${plane[0].toUpperCase()}${plane.slice(1)} Plane`, () => {
|
|
9746
|
+
this.setDoc(mapTree(this.doc.nodes, (n2) => next.get(n2.id) ?? n2));
|
|
9747
|
+
});
|
|
9748
|
+
return { ok: true, ids };
|
|
9749
|
+
}
|
|
9750
|
+
/** A shape's subpaths drawn on the active perspective plane from its flat drag box, or null to keep it flat. */
|
|
9751
|
+
perspectiveShape(kind, start, end) {
|
|
9752
|
+
const grid = this.doc.perspective;
|
|
9753
|
+
const plane = this.perspectivePlane;
|
|
9754
|
+
if (!grid || !plane || kind === "line" || !vectorPerspectivePlanes(grid).includes(plane)) return null;
|
|
9755
|
+
const toFlat = vectorPerspectivePlaneToFlat(grid, plane);
|
|
9756
|
+
const a = toFlat?.(start);
|
|
9757
|
+
const b = toFlat?.(end);
|
|
9758
|
+
if (!a || !b) return null;
|
|
9759
|
+
const flat = this.createShapeNode({ kind, ...boundsFromPoints(a, b) });
|
|
9760
|
+
const mapped = vectorPerspectiveMapPath(grid, plane, subpathsToBezier(flat.subpaths));
|
|
9761
|
+
return mapped ? bezierToSubpaths(mapped) : null;
|
|
9762
|
+
}
|
|
9763
|
+
// -----------------------------------------------------------------------------------------
|
|
9496
9764
|
// PDF
|
|
9497
9765
|
/**
|
|
9498
9766
|
* The document as a vector PDF (see `vectorDocumentToPdf`): one page of the artboard, or a page
|
|
@@ -10134,6 +10402,51 @@ var VectorEditorController = class _VectorEditorController {
|
|
|
10134
10402
|
* (`{ nodeId, side? }`) or unglue it (`null`, the end staying where it is), and `route`,
|
|
10135
10403
|
* `radius`, `gap` set how they run. Plain open paths given by id become connectors. One undo step.
|
|
10136
10404
|
*/
|
|
10405
|
+
/**
|
|
10406
|
+
* Makes closed paths lenses (CorelDRAW's Lens) or changes their lens: `lens` is merged over the
|
|
10407
|
+
* current settings (a different `type` starts from that type's defaults), and `null` makes
|
|
10408
|
+
* them plain paths again. One undo step. Returns each path's id and resulting lens.
|
|
10409
|
+
*/
|
|
10410
|
+
setLens(lens, options = {}) {
|
|
10411
|
+
const ids = options.ids ?? this.selection;
|
|
10412
|
+
if (!ids.length) return { ok: false, message: "Select a closed path to make a lens first." };
|
|
10413
|
+
if (lens && lens.type !== void 0 && !VECTOR_LENS_TYPES.includes(lens.type)) return { ok: false, message: `Unknown lens "${lens.type}": use ${VECTOR_LENS_TYPES.join(", ")}.` };
|
|
10414
|
+
if (lens?.color !== void 0 && lens.color !== null && !parseVectorColor(lens.color)) return { ok: false, message: `"${lens.color}" is not a colour: use a CSS colour such as #ff0000.` };
|
|
10415
|
+
const next = /* @__PURE__ */ new Map();
|
|
10416
|
+
for (const id of ids) {
|
|
10417
|
+
const n2 = this.getNode(id);
|
|
10418
|
+
if (!n2) return { ok: false, message: `There is no node "${id}".` };
|
|
10419
|
+
if (n2.locked) return { ok: false, message: `"${id}" is locked; unlock it first.` };
|
|
10420
|
+
if (lens === null) {
|
|
10421
|
+
if (n2.type === "path" && n2.lens) next.set(id, null);
|
|
10422
|
+
continue;
|
|
10423
|
+
}
|
|
10424
|
+
if (n2.type !== "path" || !n2.subpaths.some((sp) => sp.closed) || isVectorConnector(n2)) return { ok: false, message: `"${id}" is not a closed path: only closed paths can be lenses.` };
|
|
10425
|
+
const type = lens.type ?? n2.lens?.type;
|
|
10426
|
+
if (!type) return { ok: false, message: `"${id}" is not a lens yet: pass a type (${VECTOR_LENS_TYPES.join(", ")}).` };
|
|
10427
|
+
const spec = VECTOR_LENS_SPECS[type];
|
|
10428
|
+
if (lens.amount !== void 0 && !(Number.isFinite(lens.amount) && lens.amount >= spec.min && lens.amount <= spec.max)) return { ok: false, message: `amount for a ${type} lens must be from ${spec.min} to ${spec.max} (${spec.unit}).` };
|
|
10429
|
+
const base = n2.lens && n2.lens.type === type ? n2.lens : { type };
|
|
10430
|
+
next.set(id, sanitizeVectorLens({ ...base, ...lens, type }));
|
|
10431
|
+
}
|
|
10432
|
+
if (!next.size) return { ok: true, lenses: [] };
|
|
10433
|
+
this.change(
|
|
10434
|
+
lens === null ? "Remove Lens" : "Lens",
|
|
10435
|
+
() => {
|
|
10436
|
+
this.setDoc(
|
|
10437
|
+
mapTree(this.doc.nodes, (n2) => {
|
|
10438
|
+
if (!next.has(n2.id) || n2.type !== "path") return n2;
|
|
10439
|
+
const l = next.get(n2.id);
|
|
10440
|
+
if (l) return { ...n2, lens: l };
|
|
10441
|
+
const { lens: _l, lensView: _v, ...rest } = n2;
|
|
10442
|
+
return rest;
|
|
10443
|
+
})
|
|
10444
|
+
);
|
|
10445
|
+
},
|
|
10446
|
+
options.merge
|
|
10447
|
+
);
|
|
10448
|
+
return { ok: true, lenses: [...next].map(([id, l]) => ({ id, lens: l })) };
|
|
10449
|
+
}
|
|
10137
10450
|
setConnector(patch, options = {}) {
|
|
10138
10451
|
const ids = options.ids ?? this.selection;
|
|
10139
10452
|
if (!ids.length) return { ok: false, message: "Select a connector first." };
|
|
@@ -12239,7 +12552,9 @@ var VectorEditorController = class _VectorEditorController {
|
|
|
12239
12552
|
const y2 = drag.start.y + h;
|
|
12240
12553
|
bounds = boundsFromPoints(start, { x: x2, y: y2 });
|
|
12241
12554
|
}
|
|
12242
|
-
const
|
|
12555
|
+
const kind = drag.tool === "frame" ? "rect" : drag.tool;
|
|
12556
|
+
const onPlane = drag.tool !== "frame" ? this.perspectiveShape(kind, start, { x: bounds.x === start.x ? bounds.x + bounds.width : bounds.x, y: bounds.y === start.y ? bounds.y + bounds.height : bounds.y }) : null;
|
|
12557
|
+
const shaped = onPlane ? { subpaths: onPlane } : this.createShapeNode({ kind, ...bounds });
|
|
12243
12558
|
this.replaceNode(drag.nodeId, { ...node, subpaths: shaped.subpaths });
|
|
12244
12559
|
this.interaction = { type: "draw", tool: drag.tool, nodeId: drag.nodeId, bounds };
|
|
12245
12560
|
this.notify(true);
|
|
@@ -14091,7 +14406,8 @@ function createVectorCommands(controller, options = {}) {
|
|
|
14091
14406
|
...isVectorFrame(n2) ? { frameRect: n2.frame } : {},
|
|
14092
14407
|
...n2.resizing ? { resizing: n2.resizing } : {},
|
|
14093
14408
|
...n2.type === "path" && n2.connector ? { connector: n2.connector } : {},
|
|
14094
|
-
...n2.type === "group" && n2.symmetry ? { symmetry: n2.symmetry } : {}
|
|
14409
|
+
...n2.type === "group" && n2.symmetry ? { symmetry: n2.symmetry } : {},
|
|
14410
|
+
...n2.type === "path" && n2.lens ? { lens: n2.lens } : {}
|
|
14095
14411
|
});
|
|
14096
14412
|
if (n2.type === "group") visit(n2.children, depth + 1);
|
|
14097
14413
|
}
|
|
@@ -15055,6 +15371,130 @@ function createVectorCommands(controller, options = {}) {
|
|
|
15055
15371
|
}
|
|
15056
15372
|
}
|
|
15057
15373
|
];
|
|
15374
|
+
const LENS_AMOUNTS = VECTOR_LENS_TYPES.map((t) => `${t} ${VECTOR_LENS_SPECS[t].min}\u2026${VECTOR_LENS_SPECS[t].max} ${VECTOR_LENS_SPECS[t].unit} (default ${VECTOR_LENS_SPECS[t].amount})`).join("; ");
|
|
15375
|
+
const lensCommands = () => [
|
|
15376
|
+
{
|
|
15377
|
+
...base,
|
|
15378
|
+
id: `${prefix}setLens`,
|
|
15379
|
+
label: "Lens\u2026",
|
|
15380
|
+
keywords: ["lens", "magnify", "fisheye", "fish eye", "invert", "brighten", "grayscale", "heat map", "wireframe", "transparency", "tint", "loupe"],
|
|
15381
|
+
description: "Makes closed paths (`ids`, default the selection) lenses, or changes their lens: inside its outline, what is drawn below shows changed (magnify, fisheye, brighten, invert, tintedGrayscale, colorAdd, colorLimit, heatMap, wireframe, or the lens's own fill see-through for transparency). The lens follows every edit below it; its bounds stay its own shape. Pass type to make or switch a lens (missing values take that type's defaults); omit it to change amount or color of existing lenses. One undo step. Returns { lenses: [{ id, lens }] }.",
|
|
15382
|
+
params: {
|
|
15383
|
+
type: "object",
|
|
15384
|
+
properties: {
|
|
15385
|
+
ids: { ...IDS, description: "Closed paths to make or change (default: the selection)." },
|
|
15386
|
+
type: { type: "string", enum: [...VECTOR_LENS_TYPES], description: "What the lens does. Required for a path that is not a lens yet." },
|
|
15387
|
+
amount: { type: "number", description: `Strength, by type: ${LENS_AMOUNTS}.` },
|
|
15388
|
+
color: { type: ["string", "null"], description: "CSS colour for tintedGrayscale, colorAdd, colorLimit and wireframe (default per type; ignored by the others)." }
|
|
15389
|
+
},
|
|
15390
|
+
additionalProperties: false
|
|
15391
|
+
},
|
|
15392
|
+
undoable: true,
|
|
15393
|
+
enabled: enabledFor,
|
|
15394
|
+
run: (_ctx, params) => {
|
|
15395
|
+
const { ids: list2, ...patch } = params ?? {};
|
|
15396
|
+
if (!Object.keys(patch).length) fail("Pass at least one of type, amount, color.");
|
|
15397
|
+
const r = controller.setLens(patch, list2 ? { ids: list2 } : {});
|
|
15398
|
+
check(r);
|
|
15399
|
+
return { lenses: r.lenses ?? [] };
|
|
15400
|
+
}
|
|
15401
|
+
},
|
|
15402
|
+
{
|
|
15403
|
+
...base,
|
|
15404
|
+
id: `${prefix}removeLens`,
|
|
15405
|
+
label: "Remove Lens",
|
|
15406
|
+
keywords: ["lens", "remove", "plain"],
|
|
15407
|
+
description: "Makes lenses (`ids`, default the selection) plain paths again; ids that are not lenses are skipped. One undo step. Returns { ids } of the paths that stopped being lenses.",
|
|
15408
|
+
params: { type: "object", properties: { ids: { ...IDS, description: "Lens ids (default: the selection)." } }, additionalProperties: false },
|
|
15409
|
+
undoable: true,
|
|
15410
|
+
enabled: enabledFor,
|
|
15411
|
+
run: (_ctx, params) => {
|
|
15412
|
+
const r = controller.setLens(null, params?.ids ? { ids: params.ids } : {});
|
|
15413
|
+
check(r);
|
|
15414
|
+
return { ids: (r.lenses ?? []).map((l) => l.id) };
|
|
15415
|
+
}
|
|
15416
|
+
}
|
|
15417
|
+
];
|
|
15418
|
+
const PLANE = { type: "string", enum: [...VECTOR_PERSPECTIVE_PLANES], description: "A plane of the grid: floor, left and right (2 or 3 vanishing points), or floor, side and front (1 point)." };
|
|
15419
|
+
const perspectiveResult = () => {
|
|
15420
|
+
const grid = controller.getPerspective();
|
|
15421
|
+
return { perspective: grid, planes: grid ? vectorPerspectivePlanes(grid) : [], drawingOn: controller.getState().perspectivePlane };
|
|
15422
|
+
};
|
|
15423
|
+
const perspectiveCommands = () => [
|
|
15424
|
+
{
|
|
15425
|
+
...base,
|
|
15426
|
+
id: `${prefix}getPerspective`,
|
|
15427
|
+
label: "Perspective Grid",
|
|
15428
|
+
keywords: ["perspective", "grid", "vanishing point", "horizon"],
|
|
15429
|
+
description: "Reads the document's perspective grid: { perspective: { vanishingPoints, origin, gridSize, extent, visible } or null, planes (the planes it has), drawingOn (the plane new shapes are drawn on, or null) }.",
|
|
15430
|
+
params: { type: "object", properties: {}, additionalProperties: false },
|
|
15431
|
+
run: () => perspectiveResult()
|
|
15432
|
+
},
|
|
15433
|
+
{
|
|
15434
|
+
...base,
|
|
15435
|
+
id: `${prefix}setPerspective`,
|
|
15436
|
+
label: "Perspective Grid\u2026",
|
|
15437
|
+
keywords: ["perspective", "grid", "vanishing point", "one point", "two point", "three point", "horizon", "drawing in perspective"],
|
|
15438
|
+
description: "Sets the document's perspective grid (CorelDRAW's Perspective Drawing): 1 vanishing point (planes floor, side, front), 2 (floor, left, right; walls recede to the first and second) or 3 (the third is where the walls' verticals meet). Put the vanishing points on the horizon line and the origin below it, where the planes meet. One undo step. Returns the grid as vector.getPerspective does.",
|
|
15439
|
+
params: {
|
|
15440
|
+
type: "object",
|
|
15441
|
+
properties: {
|
|
15442
|
+
vanishingPoints: { type: "array", minItems: 1, maxItems: 3, items: { ...POINT, description: "A vanishing point (document units)." }, description: "1 to 3 vanishing points, document units." },
|
|
15443
|
+
origin: { ...POINT, description: "Where the planes meet (document units), not on a vanishing point." },
|
|
15444
|
+
gridSize: { type: "number", exclusiveMinimum: 0, description: "Grid cell size at the origin, document units (default 20)." },
|
|
15445
|
+
extent: { type: "integer", minimum: 1, maximum: 100, description: "Cells drawn out from the origin along each axis (default 12)." },
|
|
15446
|
+
visible: { type: "boolean", description: "Show the grid on the canvas (default true)." }
|
|
15447
|
+
},
|
|
15448
|
+
required: ["vanishingPoints", "origin"],
|
|
15449
|
+
additionalProperties: false
|
|
15450
|
+
},
|
|
15451
|
+
undoable: true,
|
|
15452
|
+
run: (_ctx, params) => {
|
|
15453
|
+
check(controller.setPerspective(params));
|
|
15454
|
+
return perspectiveResult();
|
|
15455
|
+
}
|
|
15456
|
+
},
|
|
15457
|
+
{
|
|
15458
|
+
...base,
|
|
15459
|
+
id: `${prefix}removePerspective`,
|
|
15460
|
+
label: "Remove Perspective Grid",
|
|
15461
|
+
keywords: ["perspective", "grid", "remove"],
|
|
15462
|
+
description: "Removes the perspective grid (art already on its planes stays as drawn). One undo step. Returns { perspective: null }.",
|
|
15463
|
+
params: { type: "object", properties: {}, additionalProperties: false },
|
|
15464
|
+
undoable: true,
|
|
15465
|
+
run: () => {
|
|
15466
|
+
check(controller.setPerspective(null));
|
|
15467
|
+
return { perspective: null };
|
|
15468
|
+
}
|
|
15469
|
+
},
|
|
15470
|
+
{
|
|
15471
|
+
...base,
|
|
15472
|
+
id: `${prefix}setPerspectivePlane`,
|
|
15473
|
+
label: "Draw on Perspective Plane",
|
|
15474
|
+
keywords: ["perspective", "plane", "draw", "floor", "wall"],
|
|
15475
|
+
description: "Makes the Rectangle, Ellipse, Polygon and Star tools draw on a plane of the grid (their drag box is taken on the plane, so shapes recede with it), or flat again with plane null. Not an undo step. Returns the grid as vector.getPerspective does.",
|
|
15476
|
+
params: { type: "object", properties: { plane: { ...PLANE, type: ["string", "null"], enum: [...VECTOR_PERSPECTIVE_PLANES, null], description: `${PLANE.description} null draws flat.` } }, required: ["plane"], additionalProperties: false },
|
|
15477
|
+
run: (_ctx, params) => {
|
|
15478
|
+
check(controller.setPerspectivePlane(params.plane));
|
|
15479
|
+
return perspectiveResult();
|
|
15480
|
+
}
|
|
15481
|
+
},
|
|
15482
|
+
{
|
|
15483
|
+
...base,
|
|
15484
|
+
id: `${prefix}attachToPerspective`,
|
|
15485
|
+
label: "Attach to Perspective",
|
|
15486
|
+
keywords: ["perspective", "attach", "plane", "project", "wall", "floor", "sign"],
|
|
15487
|
+
description: "Lays objects (`ids`, default the selection) onto a plane of the grid: each is read flat relative to the grid origin (right and up) and projected, so art near the origin keeps its size and further art recedes. Draw or place the flat art beside the origin first. Text and instances must be outlines (vector.createOutlines). One undo step. Returns { ids }.",
|
|
15488
|
+
params: { type: "object", properties: { ids: { ...IDS, description: "Objects to project (default: the selection)." }, plane: PLANE }, required: ["plane"], additionalProperties: false },
|
|
15489
|
+
undoable: true,
|
|
15490
|
+
enabled: enabledFor,
|
|
15491
|
+
run: (_ctx, params) => {
|
|
15492
|
+
const r = controller.attachToPerspective(params.plane, params.ids ? { ids: params.ids } : {});
|
|
15493
|
+
check(r);
|
|
15494
|
+
return { ids: r.ids ?? [] };
|
|
15495
|
+
}
|
|
15496
|
+
}
|
|
15497
|
+
];
|
|
15058
15498
|
const pdfCommands = () => [
|
|
15059
15499
|
{
|
|
15060
15500
|
...base,
|
|
@@ -15891,6 +16331,8 @@ function createVectorCommands(controller, options = {}) {
|
|
|
15891
16331
|
...lottieCommands(),
|
|
15892
16332
|
...pdfCommands(),
|
|
15893
16333
|
...symmetryCommands(),
|
|
16334
|
+
...perspectiveCommands(),
|
|
16335
|
+
...lensCommands(),
|
|
15894
16336
|
{
|
|
15895
16337
|
...base,
|
|
15896
16338
|
id: `${prefix}setCorners`,
|
|
@@ -16922,6 +17364,9 @@ export {
|
|
|
16922
17364
|
VECTOR_HORIZONTAL_RESIZING,
|
|
16923
17365
|
VECTOR_HORIZONTAL_RESIZING_LABELS,
|
|
16924
17366
|
VECTOR_INK_MAX_CORNERS,
|
|
17367
|
+
VECTOR_LENS_LABELS,
|
|
17368
|
+
VECTOR_LENS_SPECS,
|
|
17369
|
+
VECTOR_LENS_TYPES,
|
|
16925
17370
|
VECTOR_MASK_TYPES,
|
|
16926
17371
|
VECTOR_MASK_TYPE_LABELS,
|
|
16927
17372
|
VECTOR_MASK_TYPE_OPTIONS,
|
|
@@ -16937,6 +17382,7 @@ export {
|
|
|
16937
17382
|
VECTOR_PATH_ACTIONS,
|
|
16938
17383
|
VECTOR_PATH_TEXT_BASELINES,
|
|
16939
17384
|
VECTOR_PENCIL_STRING_PX,
|
|
17385
|
+
VECTOR_PERSPECTIVE_PLANES,
|
|
16940
17386
|
VECTOR_PRESSURE_NOMINAL,
|
|
16941
17387
|
VECTOR_ROTATE_HANDLE_OFFSET,
|
|
16942
17388
|
VECTOR_SPATIAL_MIN,
|
|
@@ -17128,6 +17574,7 @@ export {
|
|
|
17128
17574
|
isVectorFrame,
|
|
17129
17575
|
isVectorFreeformGradient,
|
|
17130
17576
|
isVectorGradient,
|
|
17577
|
+
isVectorLens,
|
|
17131
17578
|
isVectorLiveBoolean,
|
|
17132
17579
|
isVectorMaskActive,
|
|
17133
17580
|
isVectorMaskGroup,
|
|
@@ -17147,6 +17594,7 @@ export {
|
|
|
17147
17594
|
mapVectorGradient,
|
|
17148
17595
|
mapWarpMeshPoints as mapVectorMeshPoints,
|
|
17149
17596
|
mapVectorPaint,
|
|
17597
|
+
mapVectorPaintColors,
|
|
17150
17598
|
mapVectorPoints,
|
|
17151
17599
|
mapVectorShadedPaint,
|
|
17152
17600
|
mapVectorSubpaths,
|
|
@@ -17217,6 +17665,7 @@ export {
|
|
|
17217
17665
|
resampleGradientStops,
|
|
17218
17666
|
resizeWarpMesh as resizeVectorMesh,
|
|
17219
17667
|
resolveVectorBlendOptions,
|
|
17668
|
+
resolveVectorLenses,
|
|
17220
17669
|
resolveVectorSymbols,
|
|
17221
17670
|
reverseMorphContour,
|
|
17222
17671
|
reverseSubpath,
|
|
@@ -17238,7 +17687,9 @@ export {
|
|
|
17238
17687
|
sanitizeVectorFilters,
|
|
17239
17688
|
sanitizeVectorFrame,
|
|
17240
17689
|
sanitizeVectorGradient,
|
|
17690
|
+
sanitizeVectorLens,
|
|
17241
17691
|
sanitizeVectorMask,
|
|
17692
|
+
sanitizeVectorPerspective,
|
|
17242
17693
|
sanitizeVectorResizing,
|
|
17243
17694
|
sanitizeVectorShadedPaint,
|
|
17244
17695
|
sanitizeVectorStrokeSettings,
|
|
@@ -17267,6 +17718,7 @@ export {
|
|
|
17267
17718
|
splitWarpMeshU as splitVectorMeshU,
|
|
17268
17719
|
splitWarpMeshV as splitVectorMeshV,
|
|
17269
17720
|
starSubpath,
|
|
17721
|
+
stripVectorLensViews,
|
|
17270
17722
|
stripVectorSymbolArt,
|
|
17271
17723
|
strokePositionPoint,
|
|
17272
17724
|
strokeWidthProfileOf,
|
|
@@ -17383,6 +17835,8 @@ export {
|
|
|
17383
17835
|
vectorInkShapeName,
|
|
17384
17836
|
vectorInstanceDrawn,
|
|
17385
17837
|
vectorInstanceGroup,
|
|
17838
|
+
vectorLensColorMap,
|
|
17839
|
+
vectorLensDrawn,
|
|
17386
17840
|
vectorLiveBooleanSteps,
|
|
17387
17841
|
vectorMaskContains,
|
|
17388
17842
|
vectorMaskContentBounds,
|
|
@@ -17432,6 +17886,13 @@ export {
|
|
|
17432
17886
|
vectorPathTextPositions,
|
|
17433
17887
|
vectorPathWorldBezier,
|
|
17434
17888
|
vectorPathfinderShape,
|
|
17889
|
+
vectorPerspectiveFlatToPlane,
|
|
17890
|
+
vectorPerspectiveGridLines,
|
|
17891
|
+
vectorPerspectiveMapPath,
|
|
17892
|
+
vectorPerspectivePlaneMap,
|
|
17893
|
+
vectorPerspectivePlaneToFlat,
|
|
17894
|
+
vectorPerspectivePlanes,
|
|
17895
|
+
vectorPerspectivePreset,
|
|
17435
17896
|
vectorPolarAngles,
|
|
17436
17897
|
vectorPolarIncrementOf,
|
|
17437
17898
|
vectorRepeaterCopies,
|