@pixldocs/canvas-renderer 0.5.240 → 0.5.241
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/{index-DBOS1ouN.cjs → index-BRI84Wy6.cjs} +224 -9
- package/dist/index-BRI84Wy6.cjs.map +1 -0
- package/dist/{index-B2H1tQ0S.js → index-DtyVze4W.js} +224 -9
- package/dist/index-DtyVze4W.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-CHVrwSi7.js → vectorPdfExport-BBY4avH9.js} +4 -4
- package/dist/{vectorPdfExport-CHVrwSi7.js.map → vectorPdfExport-BBY4avH9.js.map} +1 -1
- package/dist/{vectorPdfExport-D1yCN3sm.cjs → vectorPdfExport-BQhOl3Zh.cjs} +4 -4
- package/dist/{vectorPdfExport-D1yCN3sm.cjs.map → vectorPdfExport-BQhOl3Zh.cjs.map} +1 -1
- package/package.json +1 -1
- package/dist/index-B2H1tQ0S.js.map +0 -1
- package/dist/index-DBOS1ouN.cjs.map +0 -1
|
@@ -1009,7 +1009,7 @@ const defaultProjectSettings = {
|
|
|
1009
1009
|
snapToGrid: false,
|
|
1010
1010
|
gridSize: 20,
|
|
1011
1011
|
snapToGuides: true,
|
|
1012
|
-
snapThreshold:
|
|
1012
|
+
snapThreshold: 8
|
|
1013
1013
|
};
|
|
1014
1014
|
const defaultPageSettings = {
|
|
1015
1015
|
backgroundColor: "#ffffff"
|
|
@@ -5737,7 +5737,7 @@ function getObjectSnapPoints(obj) {
|
|
|
5737
5737
|
}
|
|
5738
5738
|
function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold) {
|
|
5739
5739
|
if (!snapToGuides) return { guides: [], snapDx: 0, snapDy: 0 };
|
|
5740
|
-
const threshold = snapThreshold ||
|
|
5740
|
+
const threshold = snapThreshold || 8;
|
|
5741
5741
|
const newGuides = [];
|
|
5742
5742
|
const horizontalSnaps = [];
|
|
5743
5743
|
const verticalSnaps = [];
|
|
@@ -5799,13 +5799,115 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5799
5799
|
verticalSnaps.sort((a, b) => a.distance - b.distance);
|
|
5800
5800
|
const bestSnap = verticalSnaps[0];
|
|
5801
5801
|
snapDx = bestSnap.delta;
|
|
5802
|
-
newGuides.push({ ...bestSnap.guide,
|
|
5802
|
+
newGuides.push({ ...bestSnap.guide, kind: "alignment" });
|
|
5803
5803
|
}
|
|
5804
5804
|
if (horizontalSnaps.length > 0) {
|
|
5805
5805
|
horizontalSnaps.sort((a, b) => a.distance - b.distance);
|
|
5806
5806
|
const bestSnap = horizontalSnaps[0];
|
|
5807
5807
|
snapDy = bestSnap.delta;
|
|
5808
|
-
newGuides.push({ ...bestSnap.guide,
|
|
5808
|
+
newGuides.push({ ...bestSnap.guide, kind: "alignment" });
|
|
5809
|
+
}
|
|
5810
|
+
const projectedLeft = moving.left + snapDx;
|
|
5811
|
+
const projectedRight = moving.right + snapDx;
|
|
5812
|
+
moving.centerX + snapDx;
|
|
5813
|
+
const projectedTop = moving.top + snapDy;
|
|
5814
|
+
const projectedBottom = moving.bottom + snapDy;
|
|
5815
|
+
moving.centerY + snapDy;
|
|
5816
|
+
if (snapDx === 0) {
|
|
5817
|
+
let bestPair = null;
|
|
5818
|
+
for (const a of allObjects) {
|
|
5819
|
+
const A = getObjectSnapPoints(a);
|
|
5820
|
+
if (A.right > projectedLeft) continue;
|
|
5821
|
+
if (A.bottom < projectedTop || A.top > projectedBottom) continue;
|
|
5822
|
+
for (const b of allObjects) {
|
|
5823
|
+
if (b === a) continue;
|
|
5824
|
+
const B = getObjectSnapPoints(b);
|
|
5825
|
+
if (B.left < projectedRight) continue;
|
|
5826
|
+
if (B.bottom < projectedTop || B.top > projectedBottom) continue;
|
|
5827
|
+
const gapL = projectedLeft - A.right;
|
|
5828
|
+
const gapR = B.left - projectedRight;
|
|
5829
|
+
const diff = gapR - gapL;
|
|
5830
|
+
const absDiff = Math.abs(diff);
|
|
5831
|
+
if (absDiff < threshold && (!bestPair || absDiff < bestPair.absDiff)) {
|
|
5832
|
+
bestPair = { A, B, delta: diff / 2, absDiff };
|
|
5833
|
+
}
|
|
5834
|
+
}
|
|
5835
|
+
}
|
|
5836
|
+
if (bestPair) {
|
|
5837
|
+
snapDx = bestPair.delta;
|
|
5838
|
+
const newLeft = moving.left + snapDx;
|
|
5839
|
+
const newRight = moving.right + snapDx;
|
|
5840
|
+
const equalGap = Math.round(newLeft - bestPair.A.right);
|
|
5841
|
+
const bracketY = (Math.max(bestPair.A.top, projectedTop, bestPair.B.top) + Math.min(bestPair.A.bottom, projectedBottom, bestPair.B.bottom)) / 2;
|
|
5842
|
+
if (equalGap > 0) {
|
|
5843
|
+
newGuides.push({
|
|
5844
|
+
type: "horizontal",
|
|
5845
|
+
position: bracketY,
|
|
5846
|
+
kind: "gap",
|
|
5847
|
+
gap: equalGap,
|
|
5848
|
+
start: bestPair.A.right,
|
|
5849
|
+
end: newLeft,
|
|
5850
|
+
bracketAt: bracketY
|
|
5851
|
+
});
|
|
5852
|
+
newGuides.push({
|
|
5853
|
+
type: "horizontal",
|
|
5854
|
+
position: bracketY,
|
|
5855
|
+
kind: "gap",
|
|
5856
|
+
gap: equalGap,
|
|
5857
|
+
start: newRight,
|
|
5858
|
+
end: bestPair.B.left,
|
|
5859
|
+
bracketAt: bracketY
|
|
5860
|
+
});
|
|
5861
|
+
}
|
|
5862
|
+
}
|
|
5863
|
+
}
|
|
5864
|
+
if (snapDy === 0) {
|
|
5865
|
+
let bestPair = null;
|
|
5866
|
+
for (const a of allObjects) {
|
|
5867
|
+
const A = getObjectSnapPoints(a);
|
|
5868
|
+
if (A.bottom > projectedTop) continue;
|
|
5869
|
+
if (A.right < projectedLeft || A.left > projectedRight) continue;
|
|
5870
|
+
for (const b of allObjects) {
|
|
5871
|
+
if (b === a) continue;
|
|
5872
|
+
const B = getObjectSnapPoints(b);
|
|
5873
|
+
if (B.top < projectedBottom) continue;
|
|
5874
|
+
if (B.right < projectedLeft || B.left > projectedRight) continue;
|
|
5875
|
+
const gapT = projectedTop - A.bottom;
|
|
5876
|
+
const gapB = B.top - projectedBottom;
|
|
5877
|
+
const diff = gapB - gapT;
|
|
5878
|
+
const absDiff = Math.abs(diff);
|
|
5879
|
+
if (absDiff < threshold && (!bestPair || absDiff < bestPair.absDiff)) {
|
|
5880
|
+
bestPair = { A, B, delta: diff / 2, absDiff };
|
|
5881
|
+
}
|
|
5882
|
+
}
|
|
5883
|
+
}
|
|
5884
|
+
if (bestPair) {
|
|
5885
|
+
snapDy = bestPair.delta;
|
|
5886
|
+
const newTop = moving.top + snapDy;
|
|
5887
|
+
const newBottom = moving.bottom + snapDy;
|
|
5888
|
+
const equalGap = Math.round(newTop - bestPair.A.bottom);
|
|
5889
|
+
const bracketX = (Math.max(bestPair.A.left, projectedLeft, bestPair.B.left) + Math.min(bestPair.A.right, projectedRight, bestPair.B.right)) / 2;
|
|
5890
|
+
if (equalGap > 0) {
|
|
5891
|
+
newGuides.push({
|
|
5892
|
+
type: "vertical",
|
|
5893
|
+
position: bracketX,
|
|
5894
|
+
kind: "gap",
|
|
5895
|
+
gap: equalGap,
|
|
5896
|
+
start: bestPair.A.bottom,
|
|
5897
|
+
end: newTop,
|
|
5898
|
+
bracketAt: bracketX
|
|
5899
|
+
});
|
|
5900
|
+
newGuides.push({
|
|
5901
|
+
type: "vertical",
|
|
5902
|
+
position: bracketX,
|
|
5903
|
+
kind: "gap",
|
|
5904
|
+
gap: equalGap,
|
|
5905
|
+
start: newBottom,
|
|
5906
|
+
end: bestPair.B.top,
|
|
5907
|
+
bracketAt: bracketX
|
|
5908
|
+
});
|
|
5909
|
+
}
|
|
5910
|
+
}
|
|
5809
5911
|
}
|
|
5810
5912
|
return { guides: newGuides, snapDx, snapDy };
|
|
5811
5913
|
}
|
|
@@ -9939,6 +10041,7 @@ const PageCanvas = forwardRef(
|
|
|
9939
10041
|
const hasClearedCachesBeforeFirstSyncRef = useRef(false);
|
|
9940
10042
|
const [guides, setGuides] = useState([]);
|
|
9941
10043
|
const [gridResizeLabel, setGridResizeLabel] = useState(null);
|
|
10044
|
+
const [hoverBounds, setHoverBounds] = useState(null);
|
|
9942
10045
|
const [rotationLabel, setRotationLabel] = useState(null);
|
|
9943
10046
|
const [sizeLabel, setSizeLabel] = useState(null);
|
|
9944
10047
|
const [ready, setReady] = useState(false);
|
|
@@ -11280,6 +11383,26 @@ const PageCanvas = forwardRef(
|
|
|
11280
11383
|
if (editLockRef.current) return;
|
|
11281
11384
|
const t = opt.target;
|
|
11282
11385
|
const tid = t ? getObjectId(t) : null;
|
|
11386
|
+
try {
|
|
11387
|
+
const activeIds = new Set(selectedIdsRef.current);
|
|
11388
|
+
const isHoveringSelected = !!(tid && activeIds.has(tid));
|
|
11389
|
+
if (t && tid && tid !== "__background__" && !isHoveringSelected) {
|
|
11390
|
+
const outer = t.group && !t.group.__pixldocsGroupSelection ? t.group : t;
|
|
11391
|
+
outer.setCoords();
|
|
11392
|
+
const br = outer.getBoundingRect();
|
|
11393
|
+
setHoverBounds({
|
|
11394
|
+
left: br.left,
|
|
11395
|
+
top: br.top,
|
|
11396
|
+
width: br.width,
|
|
11397
|
+
height: br.height,
|
|
11398
|
+
angle: 0
|
|
11399
|
+
});
|
|
11400
|
+
} else {
|
|
11401
|
+
setHoverBounds(null);
|
|
11402
|
+
}
|
|
11403
|
+
} catch {
|
|
11404
|
+
setHoverBounds(null);
|
|
11405
|
+
}
|
|
11283
11406
|
if (t && tid && tid !== "__background__") return;
|
|
11284
11407
|
try {
|
|
11285
11408
|
const pointer = fabricCanvas.getPointer(opt.e);
|
|
@@ -11292,6 +11415,9 @@ const PageCanvas = forwardRef(
|
|
|
11292
11415
|
fabricCanvas.defaultCursor = "default";
|
|
11293
11416
|
}
|
|
11294
11417
|
});
|
|
11418
|
+
fabricCanvas.on("mouse:out", () => {
|
|
11419
|
+
setHoverBounds(null);
|
|
11420
|
+
});
|
|
11295
11421
|
fabricCanvas.on("mouse:down", (ev) => {
|
|
11296
11422
|
if (fabricCanvas._currentTransform) {
|
|
11297
11423
|
lockEdits();
|
|
@@ -11655,6 +11781,7 @@ const PageCanvas = forwardRef(
|
|
|
11655
11781
|
const snapTarget = fabricCanvas.getActiveObject() ?? obj;
|
|
11656
11782
|
const { guides: newGuides, snapDx, snapDy } = calculateSnapGuidesCallback(snapTarget);
|
|
11657
11783
|
setGuides(newGuides);
|
|
11784
|
+
setHoverBounds(null);
|
|
11658
11785
|
if (snapDx !== 0 || snapDy !== 0) {
|
|
11659
11786
|
snapTarget.set({ left: (snapTarget.left ?? 0) + snapDx, top: (snapTarget.top ?? 0) + snapDy });
|
|
11660
11787
|
}
|
|
@@ -15142,6 +15269,59 @@ const PageCanvas = forwardRef(
|
|
|
15142
15269
|
),
|
|
15143
15270
|
sectionsOverlay,
|
|
15144
15271
|
groupBoundsOverlay,
|
|
15272
|
+
canvas.projectSettings.showGrid && (canvas.projectSettings.gridSize ?? 0) > 0 && /* @__PURE__ */ jsxs(
|
|
15273
|
+
"svg",
|
|
15274
|
+
{
|
|
15275
|
+
className: "absolute inset-0 pointer-events-none",
|
|
15276
|
+
style: { width: scaledWidth, height: scaledHeight },
|
|
15277
|
+
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
15278
|
+
children: [
|
|
15279
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
15280
|
+
"pattern",
|
|
15281
|
+
{
|
|
15282
|
+
id: `pixldocs-grid-${pageId}`,
|
|
15283
|
+
width: canvas.projectSettings.gridSize,
|
|
15284
|
+
height: canvas.projectSettings.gridSize,
|
|
15285
|
+
patternUnits: "userSpaceOnUse",
|
|
15286
|
+
children: /* @__PURE__ */ jsx(
|
|
15287
|
+
"path",
|
|
15288
|
+
{
|
|
15289
|
+
d: `M ${canvas.projectSettings.gridSize} 0 L 0 0 0 ${canvas.projectSettings.gridSize}`,
|
|
15290
|
+
fill: "none",
|
|
15291
|
+
stroke: "currentColor",
|
|
15292
|
+
strokeWidth: 0.5,
|
|
15293
|
+
opacity: 0.18,
|
|
15294
|
+
className: "text-foreground"
|
|
15295
|
+
}
|
|
15296
|
+
)
|
|
15297
|
+
}
|
|
15298
|
+
) }),
|
|
15299
|
+
/* @__PURE__ */ jsx("rect", { width: canvasWidth, height: canvasHeight, fill: `url(#pixldocs-grid-${pageId})` })
|
|
15300
|
+
]
|
|
15301
|
+
}
|
|
15302
|
+
),
|
|
15303
|
+
hoverBounds && !guides.length && /* @__PURE__ */ jsx(
|
|
15304
|
+
"svg",
|
|
15305
|
+
{
|
|
15306
|
+
className: "absolute inset-0 pointer-events-none",
|
|
15307
|
+
style: { width: scaledWidth, height: scaledHeight },
|
|
15308
|
+
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
15309
|
+
children: /* @__PURE__ */ jsx(
|
|
15310
|
+
"rect",
|
|
15311
|
+
{
|
|
15312
|
+
x: hoverBounds.left,
|
|
15313
|
+
y: hoverBounds.top,
|
|
15314
|
+
width: hoverBounds.width,
|
|
15315
|
+
height: hoverBounds.height,
|
|
15316
|
+
fill: "none",
|
|
15317
|
+
stroke: "hsl(256 80% 58%)",
|
|
15318
|
+
strokeWidth: 1,
|
|
15319
|
+
strokeDasharray: "0",
|
|
15320
|
+
opacity: 0.65
|
|
15321
|
+
}
|
|
15322
|
+
)
|
|
15323
|
+
}
|
|
15324
|
+
),
|
|
15145
15325
|
guides.length > 0 && /* @__PURE__ */ jsx(
|
|
15146
15326
|
"svg",
|
|
15147
15327
|
{
|
|
@@ -15151,11 +15331,46 @@ const PageCanvas = forwardRef(
|
|
|
15151
15331
|
children: (() => {
|
|
15152
15332
|
const seen = /* @__PURE__ */ new Set();
|
|
15153
15333
|
return guides.filter((guide) => {
|
|
15334
|
+
if (guide.kind === "gap") return true;
|
|
15154
15335
|
const key = `${guide.type}-${guide.position.toFixed(1)}`;
|
|
15155
15336
|
if (seen.has(key)) return false;
|
|
15156
15337
|
seen.add(key);
|
|
15157
15338
|
return true;
|
|
15158
15339
|
}).map((guide, i) => {
|
|
15340
|
+
if (guide.kind === "gap" && guide.gap != null && guide.start != null && guide.end != null) {
|
|
15341
|
+
const gapColor = "#ec4899";
|
|
15342
|
+
const label = `${guide.gap}`;
|
|
15343
|
+
const labelW2 = Math.max(22, label.length * 7 + 8);
|
|
15344
|
+
if (guide.type === "horizontal") {
|
|
15345
|
+
const y = guide.bracketAt ?? guide.position;
|
|
15346
|
+
const x1 = guide.start;
|
|
15347
|
+
const x2 = guide.end;
|
|
15348
|
+
const mid = (x1 + x2) / 2;
|
|
15349
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
15350
|
+
/* @__PURE__ */ jsx("line", { x1, y1: y, x2, y2: y, stroke: gapColor, strokeWidth: 1 }),
|
|
15351
|
+
/* @__PURE__ */ jsx("line", { x1, y1: y - 4, x2: x1, y2: y + 4, stroke: gapColor, strokeWidth: 1 }),
|
|
15352
|
+
/* @__PURE__ */ jsx("line", { x1: x2, y1: y - 4, x2, y2: y + 4, stroke: gapColor, strokeWidth: 1 }),
|
|
15353
|
+
/* @__PURE__ */ jsxs("g", { transform: `translate(${mid}, ${y - 12})`, children: [
|
|
15354
|
+
/* @__PURE__ */ jsx("rect", { x: -labelW2 / 2, y: -9, width: labelW2, height: 16, rx: 4, fill: gapColor }),
|
|
15355
|
+
/* @__PURE__ */ jsx("text", { x: 0, y: 3, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 600, children: label })
|
|
15356
|
+
] })
|
|
15357
|
+
] }, i);
|
|
15358
|
+
} else {
|
|
15359
|
+
const x = guide.bracketAt ?? guide.position;
|
|
15360
|
+
const y1 = guide.start;
|
|
15361
|
+
const y2 = guide.end;
|
|
15362
|
+
const mid = (y1 + y2) / 2;
|
|
15363
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
15364
|
+
/* @__PURE__ */ jsx("line", { x1: x, y1, x2: x, y2, stroke: gapColor, strokeWidth: 1 }),
|
|
15365
|
+
/* @__PURE__ */ jsx("line", { x1: x - 4, y1, x2: x + 4, y2: y1, stroke: gapColor, strokeWidth: 1 }),
|
|
15366
|
+
/* @__PURE__ */ jsx("line", { x1: x - 4, y1: y2, x2: x + 4, y2, stroke: gapColor, strokeWidth: 1 }),
|
|
15367
|
+
/* @__PURE__ */ jsxs("g", { transform: `translate(${x + 12}, ${mid})`, children: [
|
|
15368
|
+
/* @__PURE__ */ jsx("rect", { x: -labelW2 / 2, y: -9, width: labelW2, height: 16, rx: 4, fill: gapColor }),
|
|
15369
|
+
/* @__PURE__ */ jsx("text", { x: 0, y: 3, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 600, children: label })
|
|
15370
|
+
] })
|
|
15371
|
+
] }, i);
|
|
15372
|
+
}
|
|
15373
|
+
}
|
|
15159
15374
|
const isElementRelative = guide.start !== void 0 && guide.end !== void 0;
|
|
15160
15375
|
const isActive2 = guide.active === true;
|
|
15161
15376
|
const strokeColor = isActive2 ? "#22c55e" : isElementRelative ? "#f43f5e" : "#3b82f6";
|
|
@@ -21150,9 +21365,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
21150
21365
|
}
|
|
21151
21366
|
return svgString;
|
|
21152
21367
|
}
|
|
21153
|
-
const resolvedPackageVersion = "0.5.
|
|
21368
|
+
const resolvedPackageVersion = "0.5.241";
|
|
21154
21369
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
21155
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
21370
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.241";
|
|
21156
21371
|
const roundParityValue = (value) => {
|
|
21157
21372
|
if (typeof value !== "number") return value;
|
|
21158
21373
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -21899,7 +22114,7 @@ class PixldocsRenderer {
|
|
|
21899
22114
|
await this.waitForCanvasScene(container, cloned, i);
|
|
21900
22115
|
}
|
|
21901
22116
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
21902
|
-
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-
|
|
22117
|
+
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-BBY4avH9.js");
|
|
21903
22118
|
const prepared = preparePagesForExport(
|
|
21904
22119
|
cloned.pages,
|
|
21905
22120
|
canvasWidth,
|
|
@@ -24219,7 +24434,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
24219
24434
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
24220
24435
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
24221
24436
|
try {
|
|
24222
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-
|
|
24437
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-BBY4avH9.js");
|
|
24223
24438
|
try {
|
|
24224
24439
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
24225
24440
|
} catch {
|
|
@@ -24619,4 +24834,4 @@ export {
|
|
|
24619
24834
|
buildTeaserBlurFlatKeys as y,
|
|
24620
24835
|
collectFontDescriptorsFromConfig as z
|
|
24621
24836
|
};
|
|
24622
|
-
//# sourceMappingURL=index-
|
|
24837
|
+
//# sourceMappingURL=index-DtyVze4W.js.map
|