@pixldocs/canvas-renderer 0.5.394 → 0.5.396
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-CgnT1WJ6.js → index-BTGqkKaE.js} +272 -46
- package/dist/index-BTGqkKaE.js.map +1 -0
- package/dist/{index-mH5LwfhM.cjs → index-DQYnrYMM.cjs} +272 -46
- package/dist/index-DQYnrYMM.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-BUj20FDX.js → vectorPdfExport-RZWtHBw4.js} +4 -4
- package/dist/{vectorPdfExport-BUj20FDX.js.map → vectorPdfExport-RZWtHBw4.js.map} +1 -1
- package/dist/{vectorPdfExport-RJHpxl55.cjs → vectorPdfExport-oL70Zv8c.cjs} +4 -4
- package/dist/{vectorPdfExport-RJHpxl55.cjs.map → vectorPdfExport-oL70Zv8c.cjs.map} +1 -1
- package/package.json +1 -1
- package/dist/index-CgnT1WJ6.js.map +0 -1
- package/dist/index-mH5LwfhM.cjs.map +0 -1
|
@@ -125,6 +125,7 @@ const createDefaultGroup = (partial) => ({
|
|
|
125
125
|
locked: false,
|
|
126
126
|
left: 0,
|
|
127
127
|
top: 0,
|
|
128
|
+
angle: 0,
|
|
128
129
|
...partial
|
|
129
130
|
});
|
|
130
131
|
const PAGE_BACKGROUND_ELEMENT_ID = "__pageBackground__";
|
|
@@ -847,9 +848,17 @@ function getNodeBounds(node, pageChildren, options) {
|
|
|
847
848
|
let width;
|
|
848
849
|
let height;
|
|
849
850
|
if (isGroup(node) && (pageChildren == null ? void 0 : pageChildren.length) !== void 0) {
|
|
850
|
-
const
|
|
851
|
-
|
|
852
|
-
|
|
851
|
+
const group = node;
|
|
852
|
+
const storedWidth = Number(group.width);
|
|
853
|
+
const storedHeight = Number(group.height);
|
|
854
|
+
if (!isStackLayoutMode(group.layoutMode) && storedWidth > 0 && storedHeight > 0) {
|
|
855
|
+
width = storedWidth;
|
|
856
|
+
height = storedHeight;
|
|
857
|
+
} else {
|
|
858
|
+
const size = groupBoundsFromChildren(group, pageChildren ?? []);
|
|
859
|
+
width = size.width;
|
|
860
|
+
height = size.height;
|
|
861
|
+
}
|
|
853
862
|
} else {
|
|
854
863
|
width = simpleWidth(node);
|
|
855
864
|
height = simpleHeight(node);
|
|
@@ -10524,6 +10533,65 @@ const normalizeAngle180 = (angle) => {
|
|
|
10524
10533
|
const n = (angle % 360 + 360) % 360;
|
|
10525
10534
|
return n > 180 ? n - 360 : n;
|
|
10526
10535
|
};
|
|
10536
|
+
const isValidLogicalGroupFrame = (frame) => !!frame && Number.isFinite(frame.left) && Number.isFinite(frame.top) && Number.isFinite(frame.width) && frame.width > 0 && Number.isFinite(frame.height) && frame.height > 0;
|
|
10537
|
+
const frameFromStoredGroupNode = (group, pageChildren, options) => {
|
|
10538
|
+
const width = Number(group.width);
|
|
10539
|
+
const height = Number(group.height);
|
|
10540
|
+
if (!Number.isFinite(width) || width <= 0 || !Number.isFinite(height) || height <= 0) return null;
|
|
10541
|
+
try {
|
|
10542
|
+
const abs = getAbsoluteBounds(group, pageChildren, options);
|
|
10543
|
+
return { left: abs.left, top: abs.top, width, height };
|
|
10544
|
+
} catch {
|
|
10545
|
+
return null;
|
|
10546
|
+
}
|
|
10547
|
+
};
|
|
10548
|
+
const orientedFrameFromWorldPoints = (points, angle) => {
|
|
10549
|
+
if (points.length === 0 || !Number.isFinite(angle)) return null;
|
|
10550
|
+
const rad = -angle * Math.PI / 180;
|
|
10551
|
+
const cos = Math.cos(rad);
|
|
10552
|
+
const sin = Math.sin(rad);
|
|
10553
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
10554
|
+
for (const p of points) {
|
|
10555
|
+
const xr = p.x * cos - p.y * sin;
|
|
10556
|
+
const yr = p.x * sin + p.y * cos;
|
|
10557
|
+
minX = Math.min(minX, xr);
|
|
10558
|
+
minY = Math.min(minY, yr);
|
|
10559
|
+
maxX = Math.max(maxX, xr);
|
|
10560
|
+
maxY = Math.max(maxY, yr);
|
|
10561
|
+
}
|
|
10562
|
+
if (![minX, minY, maxX, maxY].every(Number.isFinite)) return null;
|
|
10563
|
+
const width = Math.max(1, maxX - minX);
|
|
10564
|
+
const height = Math.max(1, maxY - minY);
|
|
10565
|
+
const centerXRot = minX + width / 2;
|
|
10566
|
+
const centerYRot = minY + height / 2;
|
|
10567
|
+
const back = angle * Math.PI / 180;
|
|
10568
|
+
const c = Math.cos(back);
|
|
10569
|
+
const s = Math.sin(back);
|
|
10570
|
+
const centerX = centerXRot * c - centerYRot * s;
|
|
10571
|
+
const centerY = centerXRot * s + centerYRot * c;
|
|
10572
|
+
return { left: centerX - width / 2, top: centerY - height / 2, width, height };
|
|
10573
|
+
};
|
|
10574
|
+
const collectFabricObjectWorldPoints = (objects) => {
|
|
10575
|
+
const points = [];
|
|
10576
|
+
for (const obj of objects) {
|
|
10577
|
+
try {
|
|
10578
|
+
obj.setCoords();
|
|
10579
|
+
} catch {
|
|
10580
|
+
}
|
|
10581
|
+
const coords = typeof obj.getCoords === "function" ? obj.getCoords() : null;
|
|
10582
|
+
if (Array.isArray(coords) && coords.length) {
|
|
10583
|
+
points.push(...coords.map((p) => ({ x: p.x, y: p.y })));
|
|
10584
|
+
continue;
|
|
10585
|
+
}
|
|
10586
|
+
const aC = obj.aCoords;
|
|
10587
|
+
if (!aC) continue;
|
|
10588
|
+
for (const key of ["tl", "tr", "br", "bl"]) {
|
|
10589
|
+
const p = aC[key];
|
|
10590
|
+
if (p) points.push({ x: p.x, y: p.y });
|
|
10591
|
+
}
|
|
10592
|
+
}
|
|
10593
|
+
return points;
|
|
10594
|
+
};
|
|
10527
10595
|
let ensureCanvaControlRenders = () => {
|
|
10528
10596
|
};
|
|
10529
10597
|
try {
|
|
@@ -11454,7 +11522,7 @@ const bakeTextboxScaleIntoTypography = (obj, sourceElement) => {
|
|
|
11454
11522
|
};
|
|
11455
11523
|
return updates;
|
|
11456
11524
|
};
|
|
11457
|
-
function applyWarpAwareSelectionBorders(selection, preferredGroupAngle) {
|
|
11525
|
+
function applyWarpAwareSelectionBorders(selection, preferredGroupAngle, preferredGroupFrame) {
|
|
11458
11526
|
var _a2;
|
|
11459
11527
|
if (selection.__pixldocsOrigASHasBorders !== void 0) {
|
|
11460
11528
|
selection.hasBorders = selection.__pixldocsOrigASHasBorders;
|
|
@@ -11517,7 +11585,8 @@ function applyWarpAwareSelectionBorders(selection, preferredGroupAngle) {
|
|
|
11517
11585
|
for (const b of buckets) b.area = orientedAreaForAngle(b.angle);
|
|
11518
11586
|
buckets.sort((a, b) => b.count - a.count || a.area - b.area || Math.abs(b.angle) - Math.abs(a.angle));
|
|
11519
11587
|
const dominant = buckets[0];
|
|
11520
|
-
const
|
|
11588
|
+
const rawPreferredGroupAngle = typeof preferredGroupAngle === "number" && Number.isFinite(preferredGroupAngle) ? preferredGroupAngle : typeof selection.__pixldocsGroupAngle === "number" && Number.isFinite(selection.__pixldocsGroupAngle) ? selection.__pixldocsGroupAngle : null;
|
|
11589
|
+
const preferredAngle = rawPreferredGroupAngle != null ? normalizeAngle180(rawPreferredGroupAngle) : null;
|
|
11521
11590
|
let targetAngle = preferredAngle;
|
|
11522
11591
|
const isLogicalGroupSelection = !!selection.__pixldocsGroupSelection;
|
|
11523
11592
|
if (targetAngle == null && dominant && Math.abs(dominant.angle) > 0.5 && (isLogicalGroupSelection || kids.length === 1 || dominant.count >= 2 || dominant.count === kids.length)) {
|
|
@@ -11561,11 +11630,30 @@ function applyWarpAwareSelectionBorders(selection, preferredGroupAngle) {
|
|
|
11561
11630
|
targetAngle,
|
|
11562
11631
|
worldAngles
|
|
11563
11632
|
});
|
|
11633
|
+
const fixedFrame = preferredGroupFrame && Number.isFinite(preferredGroupFrame.left) && Number.isFinite(preferredGroupFrame.top) && Number.isFinite(preferredGroupFrame.width) && preferredGroupFrame.width > 0 && Number.isFinite(preferredGroupFrame.height) && preferredGroupFrame.height > 0 ? preferredGroupFrame : null;
|
|
11564
11634
|
selection.set({ angle: targetAngle, scaleX: 1, scaleY: 1, skewX: 0, skewY: 0 });
|
|
11635
|
+
if (fixedFrame) {
|
|
11636
|
+
selection.set({ width: fixedFrame.width, height: fixedFrame.height, originX: "center", originY: "center" });
|
|
11637
|
+
selection.setPositionByOrigin(
|
|
11638
|
+
new fabric__namespace.Point(fixedFrame.left + fixedFrame.width / 2, fixedFrame.top + fixedFrame.height / 2),
|
|
11639
|
+
"center",
|
|
11640
|
+
"center"
|
|
11641
|
+
);
|
|
11642
|
+
}
|
|
11565
11643
|
restoreKidsFromWorld();
|
|
11566
|
-
|
|
11567
|
-
|
|
11568
|
-
|
|
11644
|
+
if (!fixedFrame) {
|
|
11645
|
+
try {
|
|
11646
|
+
(_a2 = selection.triggerLayout) == null ? void 0 : _a2.call(selection);
|
|
11647
|
+
} catch {
|
|
11648
|
+
}
|
|
11649
|
+
}
|
|
11650
|
+
if (fixedFrame) {
|
|
11651
|
+
selection.set({ width: fixedFrame.width, height: fixedFrame.height, originX: "center", originY: "center" });
|
|
11652
|
+
selection.setPositionByOrigin(
|
|
11653
|
+
new fabric__namespace.Point(fixedFrame.left + fixedFrame.width / 2, fixedFrame.top + fixedFrame.height / 2),
|
|
11654
|
+
"center",
|
|
11655
|
+
"center"
|
|
11656
|
+
);
|
|
11569
11657
|
}
|
|
11570
11658
|
restoreKidsFromWorld();
|
|
11571
11659
|
selection.setCoords();
|
|
@@ -11654,16 +11742,84 @@ const PageCanvas = react.forwardRef(
|
|
|
11654
11742
|
const [ready, setReady] = react.useState(false);
|
|
11655
11743
|
const [unlockRequestId, setUnlockRequestId] = react.useState(0);
|
|
11656
11744
|
const applyLogicalGroupSelectionVisualState = react.useCallback((selection, groupId) => {
|
|
11657
|
-
var _a2;
|
|
11745
|
+
var _a2, _b2;
|
|
11658
11746
|
selection.__pixldocsGroupSelection = groupId;
|
|
11659
11747
|
delete selection.__pixldocsLogicalGroupIds;
|
|
11660
11748
|
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
11661
11749
|
const groupNode = pageNow ? findNodeById(pageNow.children ?? [], groupId) : null;
|
|
11662
|
-
|
|
11663
|
-
if (groupAngle !== void 0) selection.__pixldocsGroupAngle = groupAngle;
|
|
11664
|
-
else delete selection.__pixldocsGroupAngle;
|
|
11665
|
-
selection.hasBorders = true;
|
|
11750
|
+
let groupAngle = groupNode && isGroup(groupNode) && typeof groupNode.angle === "number" ? groupNode.angle : void 0;
|
|
11666
11751
|
const members = selection.getObjects();
|
|
11752
|
+
if (groupAngle === void 0 && groupNode && isGroup(groupNode)) {
|
|
11753
|
+
const storedW = Number(groupNode.width);
|
|
11754
|
+
const storedH = Number(groupNode.height);
|
|
11755
|
+
if (storedW > 0 && storedH > 0) {
|
|
11756
|
+
groupAngle = 0;
|
|
11757
|
+
}
|
|
11758
|
+
}
|
|
11759
|
+
if (groupAngle === void 0 && groupNode && isGroup(groupNode)) {
|
|
11760
|
+
try {
|
|
11761
|
+
const selectionMatrix = selection.calcTransformMatrix();
|
|
11762
|
+
const worldAngles = members.map((kid) => normalizeAngle180(fabric__namespace.util.qrDecompose(
|
|
11763
|
+
fabric__namespace.util.multiplyTransformMatrices(
|
|
11764
|
+
selectionMatrix,
|
|
11765
|
+
kid.calcOwnMatrix()
|
|
11766
|
+
)
|
|
11767
|
+
).angle ?? 0));
|
|
11768
|
+
const buckets = [];
|
|
11769
|
+
for (const angle of worldAngles) {
|
|
11770
|
+
const bucket = buckets.find((candidate) => Math.abs(normalizeAngle180(candidate.angle - angle)) <= 2);
|
|
11771
|
+
if (bucket) bucket.count += 1;
|
|
11772
|
+
else buckets.push({ angle, count: 1 });
|
|
11773
|
+
}
|
|
11774
|
+
buckets.sort((a, b) => b.count - a.count || Math.abs(b.angle) - Math.abs(a.angle));
|
|
11775
|
+
const inferredAngle = (_a2 = buckets[0]) == null ? void 0 : _a2.angle;
|
|
11776
|
+
if (typeof inferredAngle === "number" && Number.isFinite(inferredAngle) && Math.abs(inferredAngle) > 0.01) {
|
|
11777
|
+
groupAngle = inferredAngle;
|
|
11778
|
+
}
|
|
11779
|
+
} catch {
|
|
11780
|
+
}
|
|
11781
|
+
}
|
|
11782
|
+
let groupFrame = groupNode && isGroup(groupNode) ? frameFromStoredGroupNode(groupNode, (pageNow == null ? void 0 : pageNow.children) ?? []) : null;
|
|
11783
|
+
let groupFrameWasInferred = false;
|
|
11784
|
+
if (!groupFrame && groupNode && isGroup(groupNode) && typeof groupAngle === "number" && Number.isFinite(groupAngle)) {
|
|
11785
|
+
groupFrame = orientedFrameFromWorldPoints(collectFabricObjectWorldPoints(members), normalizeAngle180(groupAngle));
|
|
11786
|
+
groupFrameWasInferred = isValidLogicalGroupFrame(groupFrame);
|
|
11787
|
+
}
|
|
11788
|
+
if (groupNode && isGroup(groupNode)) {
|
|
11789
|
+
const updates = {};
|
|
11790
|
+
if (typeof groupAngle === "number" && Number.isFinite(groupAngle)) {
|
|
11791
|
+
const prevAngle = typeof groupNode.angle === "number" ? groupNode.angle : void 0;
|
|
11792
|
+
if (prevAngle === void 0 || Math.abs(normalizeAngle180(prevAngle - groupAngle)) > 0.01) {
|
|
11793
|
+
updates.angle = normalizeAngle180(groupAngle);
|
|
11794
|
+
}
|
|
11795
|
+
}
|
|
11796
|
+
if (isValidLogicalGroupFrame(groupFrame)) {
|
|
11797
|
+
const prevW = Number(groupNode.width);
|
|
11798
|
+
const prevH = Number(groupNode.height);
|
|
11799
|
+
if (!Number.isFinite(prevW) || Math.abs(prevW - groupFrame.width) > 0.5) updates.width = groupFrame.width;
|
|
11800
|
+
if (!Number.isFinite(prevH) || Math.abs(prevH - groupFrame.height) > 0.5) updates.height = groupFrame.height;
|
|
11801
|
+
if (groupFrameWasInferred) {
|
|
11802
|
+
const storePos = absoluteToStorePosition(groupFrame.left, groupFrame.top, groupId, (pageNow == null ? void 0 : pageNow.children) ?? []);
|
|
11803
|
+
const prevLeft = Number(groupNode.left ?? 0);
|
|
11804
|
+
const prevTop = Number(groupNode.top ?? 0);
|
|
11805
|
+
if (!Number.isFinite(prevLeft) || Math.abs(prevLeft - storePos.left) > 0.5) updates.left = storePos.left;
|
|
11806
|
+
if (!Number.isFinite(prevTop) || Math.abs(prevTop - storePos.top) > 0.5) updates.top = storePos.top;
|
|
11807
|
+
}
|
|
11808
|
+
}
|
|
11809
|
+
if (Object.keys(updates).length > 0) {
|
|
11810
|
+
useEditorStore.getState().updateNode(groupId, updates, { recordHistory: false, skipLayoutRecalc: true });
|
|
11811
|
+
}
|
|
11812
|
+
}
|
|
11813
|
+
if (groupAngle !== void 0) {
|
|
11814
|
+
selection.__pixldocsGroupAngle = groupAngle;
|
|
11815
|
+
const aligned = selection.__pixldocsAlignedAngle;
|
|
11816
|
+
if (typeof aligned === "number" && Math.abs(normalizeAngle180(aligned - groupAngle)) > 0.01) {
|
|
11817
|
+
delete selection.__pixldocsAlignedAngle;
|
|
11818
|
+
}
|
|
11819
|
+
} else {
|
|
11820
|
+
delete selection.__pixldocsGroupAngle;
|
|
11821
|
+
}
|
|
11822
|
+
selection.hasBorders = true;
|
|
11667
11823
|
for (const prev of suppressGroupMemberBordersRef.current) {
|
|
11668
11824
|
if (members.includes(prev)) continue;
|
|
11669
11825
|
const origBorders = prev.__pixldocsOrigHasBorders;
|
|
@@ -11686,7 +11842,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11686
11842
|
if (m.__pixldocsOrigHasControls === void 0) m.__pixldocsOrigHasControls = m.hasControls;
|
|
11687
11843
|
m.hasBorders = false;
|
|
11688
11844
|
m.hasControls = false;
|
|
11689
|
-
if (m.__cropGroup || ((
|
|
11845
|
+
if (m.__cropGroup || ((_b2 = m._ct) == null ? void 0 : _b2.isCropGroup)) {
|
|
11690
11846
|
if (m.__pixldocsOrigLockScalingX === void 0) {
|
|
11691
11847
|
m.__pixldocsOrigLockScalingX = m.lockScalingX;
|
|
11692
11848
|
m.__pixldocsOrigLockScalingY = m.lockScalingY;
|
|
@@ -11695,7 +11851,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11695
11851
|
m.lockScalingY = false;
|
|
11696
11852
|
}
|
|
11697
11853
|
}
|
|
11698
|
-
applyWarpAwareSelectionBorders(selection, groupAngle);
|
|
11854
|
+
applyWarpAwareSelectionBorders(selection, groupAngle, groupFrame);
|
|
11699
11855
|
}, [pageId]);
|
|
11700
11856
|
const pageBoundsOptions = react.useMemo(
|
|
11701
11857
|
() => ({ pageContentWidth: canvasWidth, pageContentHeight: canvasHeight }),
|
|
@@ -11798,7 +11954,11 @@ const PageCanvas = react.forwardRef(
|
|
|
11798
11954
|
const activeMembers = activeBeforeRestore.getObjects();
|
|
11799
11955
|
const sameMembers = activeMembers.length === members.length && members.every((member) => activeMembers.includes(member));
|
|
11800
11956
|
const sameGroup = activeBeforeRestore.__pixldocsGroupSelection === groupId;
|
|
11801
|
-
const
|
|
11957
|
+
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
11958
|
+
const groupNode = pageNow ? findNodeById(pageNow.children ?? [], groupId) : null;
|
|
11959
|
+
const savedAngle = groupNode && isGroup(groupNode) && typeof groupNode.angle === "number" ? groupNode.angle : null;
|
|
11960
|
+
const alignedAngle = activeBeforeRestore.__pixldocsAlignedAngle;
|
|
11961
|
+
const alreadyAligned = typeof alignedAngle === "number" && (savedAngle == null || Math.abs(normalizeAngle180(alignedAngle - savedAngle)) <= 0.01);
|
|
11802
11962
|
if (sameMembers && sameGroup && alreadyAligned) {
|
|
11803
11963
|
ensureCanvaControlRenders(activeBeforeRestore);
|
|
11804
11964
|
return;
|
|
@@ -11815,9 +11975,11 @@ const PageCanvas = react.forwardRef(
|
|
|
11815
11975
|
members.forEach((m) => m.setCoords());
|
|
11816
11976
|
} catch {
|
|
11817
11977
|
}
|
|
11818
|
-
|
|
11819
|
-
|
|
11820
|
-
|
|
11978
|
+
if (!selection.__pixldocsGroupSelection) {
|
|
11979
|
+
try {
|
|
11980
|
+
(_a2 = selection.triggerLayout) == null ? void 0 : _a2.call(selection);
|
|
11981
|
+
} catch {
|
|
11982
|
+
}
|
|
11821
11983
|
}
|
|
11822
11984
|
selection.setCoords();
|
|
11823
11985
|
fc.requestRenderAll();
|
|
@@ -13257,14 +13419,18 @@ const PageCanvas = react.forwardRef(
|
|
|
13257
13419
|
const groupNode = findNodeById(pageChildren2, groupId);
|
|
13258
13420
|
if (!groupNode) return;
|
|
13259
13421
|
const groupAbs = getAbsoluteBounds(groupNode, pageChildren2);
|
|
13422
|
+
const storedGroupFrame = groupNode && isGroup(groupNode) ? frameFromStoredGroupNode(groupNode, pageChildren2, pageBoundsOptions) : null;
|
|
13423
|
+
const groupFrame = storedGroupFrame ?? groupAbs;
|
|
13260
13424
|
const rect = active.getBoundingRect();
|
|
13261
13425
|
groupSelectionTransformStartRef.current = {
|
|
13262
13426
|
groupId,
|
|
13263
13427
|
selection: active,
|
|
13264
13428
|
selectionLeft: rect.left,
|
|
13265
13429
|
selectionTop: rect.top,
|
|
13266
|
-
groupLeft:
|
|
13267
|
-
groupTop:
|
|
13430
|
+
groupLeft: groupFrame.left,
|
|
13431
|
+
groupTop: groupFrame.top,
|
|
13432
|
+
groupWidth: groupFrame.width,
|
|
13433
|
+
groupHeight: groupFrame.height,
|
|
13268
13434
|
selectionAngle: ((active.angle ?? 0) % 360 + 360) % 360
|
|
13269
13435
|
};
|
|
13270
13436
|
logRotDriftSelectionSnapshot("transform-start", active, {
|
|
@@ -13432,7 +13598,11 @@ const PageCanvas = react.forwardRef(
|
|
|
13432
13598
|
const activeIds = active.getObjects().map((obj) => getObjectId(obj)).filter((id) => !!id && id !== "__background__");
|
|
13433
13599
|
const sameMembers = activeIds.length === snapshot.memberIds.length && snapshot.memberIds.every((id) => activeIds.includes(id));
|
|
13434
13600
|
const sameGroup = active.__pixldocsGroupSelection === snapshot.groupSelectionId;
|
|
13435
|
-
const
|
|
13601
|
+
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
13602
|
+
const groupNode = pageNow ? findNodeById(pageNow.children ?? [], snapshot.groupSelectionId) : null;
|
|
13603
|
+
const savedAngle = groupNode && isGroup(groupNode) && typeof groupNode.angle === "number" ? groupNode.angle : null;
|
|
13604
|
+
const alignedAngle = active.__pixldocsAlignedAngle;
|
|
13605
|
+
const alreadyAligned = typeof alignedAngle === "number" && (savedAngle == null || Math.abs(normalizeAngle180(alignedAngle - savedAngle)) <= 0.01);
|
|
13436
13606
|
if (sameMembers && sameGroup && alreadyAligned) {
|
|
13437
13607
|
ensureCanvaControlRenders(active);
|
|
13438
13608
|
return;
|
|
@@ -13589,6 +13759,31 @@ const PageCanvas = react.forwardRef(
|
|
|
13589
13759
|
}
|
|
13590
13760
|
if (members.length === 0) return null;
|
|
13591
13761
|
const savedGroupAngle = typeof g.angle === "number" && Number.isFinite(g.angle) ? normalizeAngle180(g.angle) : null;
|
|
13762
|
+
const savedGroupWidth = Number(g.width);
|
|
13763
|
+
const savedGroupHeight = Number(g.height);
|
|
13764
|
+
if (savedGroupAngle != null && savedGroupWidth > 0 && savedGroupHeight > 0) {
|
|
13765
|
+
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
13766
|
+
const pageChildrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
13767
|
+
const abs = getAbsoluteBounds(g, pageChildrenNow);
|
|
13768
|
+
const cx = abs.left + savedGroupWidth / 2;
|
|
13769
|
+
const cy = abs.top + savedGroupHeight / 2;
|
|
13770
|
+
const rad2 = savedGroupAngle * Math.PI / 180;
|
|
13771
|
+
const c = Math.cos(rad2), s = Math.sin(rad2);
|
|
13772
|
+
const rotate = (x, y) => {
|
|
13773
|
+
const dx = x - cx;
|
|
13774
|
+
const dy = y - cy;
|
|
13775
|
+
return { x: cx + dx * c - dy * s, y: cy + dx * s + dy * c };
|
|
13776
|
+
};
|
|
13777
|
+
return {
|
|
13778
|
+
corners: [
|
|
13779
|
+
rotate(abs.left, abs.top),
|
|
13780
|
+
rotate(abs.left + savedGroupWidth, abs.top),
|
|
13781
|
+
rotate(abs.left + savedGroupWidth, abs.top + savedGroupHeight),
|
|
13782
|
+
rotate(abs.left, abs.top + savedGroupHeight)
|
|
13783
|
+
],
|
|
13784
|
+
angle: savedGroupAngle
|
|
13785
|
+
};
|
|
13786
|
+
}
|
|
13592
13787
|
const worldPoints = [];
|
|
13593
13788
|
for (const m of members) {
|
|
13594
13789
|
(_a2 = m.setCoords) == null ? void 0 : _a2.call(m);
|
|
@@ -14828,6 +15023,7 @@ const PageCanvas = react.forwardRef(
|
|
|
14828
15023
|
fabricCanvas.on("object:rotating", (e) => {
|
|
14829
15024
|
var _a2, _b2;
|
|
14830
15025
|
markSimpleTransform(e);
|
|
15026
|
+
prepareGroupSelectionTransformStart(e.target);
|
|
14831
15027
|
didTransformRef.current = true;
|
|
14832
15028
|
const tr = e.target;
|
|
14833
15029
|
if (shouldLogRotDriftLiveTick(tr, "rotating")) {
|
|
@@ -15017,7 +15213,7 @@ const PageCanvas = react.forwardRef(
|
|
|
15017
15213
|
const groupLeft = fabricCenterX - w / 2;
|
|
15018
15214
|
const groupTop = fabricCenterY - h / 2;
|
|
15019
15215
|
const storePosGroup = absoluteToStorePosition(groupLeft, groupTop, movedGroupId, pageChildrenSec);
|
|
15020
|
-
useEditorStore.getState().updateNode(movedGroupId, { left: storePosGroup.left, top: storePosGroup.top }, { recordHistory: false, skipLayoutRecalc: true });
|
|
15216
|
+
useEditorStore.getState().updateNode(movedGroupId, { left: storePosGroup.left, top: storePosGroup.top, angle: fabricSectionGroup.angle ?? 0 }, { recordHistory: false, skipLayoutRecalc: true });
|
|
15021
15217
|
}
|
|
15022
15218
|
commitHistory();
|
|
15023
15219
|
unlockEditsSoon();
|
|
@@ -15160,7 +15356,7 @@ const PageCanvas = react.forwardRef(
|
|
|
15160
15356
|
const groupLeft = centerX - w / 2;
|
|
15161
15357
|
const groupTop = centerY - h / 2;
|
|
15162
15358
|
const storePosGroup = absoluteToStorePosition(groupLeft, groupTop, groupId, pageChildrenSec);
|
|
15163
|
-
useEditorStore.getState().updateNode(groupId, { left: storePosGroup.left, top: storePosGroup.top }, { recordHistory: false, skipLayoutRecalc: true });
|
|
15359
|
+
useEditorStore.getState().updateNode(groupId, { left: storePosGroup.left, top: storePosGroup.top, angle: active.angle ?? 0 }, { recordHistory: false, skipLayoutRecalc: true });
|
|
15164
15360
|
}
|
|
15165
15361
|
const node = findNodeById(pageChildrenSec, groupId);
|
|
15166
15362
|
if (isChildModified && node && !groupMoved) {
|
|
@@ -15189,7 +15385,7 @@ const PageCanvas = react.forwardRef(
|
|
|
15189
15385
|
const groupLeft = active.originX === "center" ? centerX - w / 2 : centerX;
|
|
15190
15386
|
const groupTop = active.originY === "center" ? centerY - h / 2 : centerY;
|
|
15191
15387
|
const storePos = absoluteToStorePosition(groupLeft, groupTop, groupId, pageChildren3);
|
|
15192
|
-
useEditorStore.getState().updateNode(groupId, { left: storePos.left, top: storePos.top }, { recordHistory: false, skipLayoutRecalc: true });
|
|
15388
|
+
useEditorStore.getState().updateNode(groupId, { left: storePos.left, top: storePos.top, angle: active.angle ?? 0 }, { recordHistory: false, skipLayoutRecalc: true });
|
|
15193
15389
|
commitHistory();
|
|
15194
15390
|
unlockEditsSoon();
|
|
15195
15391
|
return;
|
|
@@ -15371,13 +15567,37 @@ const PageCanvas = react.forwardRef(
|
|
|
15371
15567
|
360 - Math.abs(currentSelAngle - startSelAngle)
|
|
15372
15568
|
);
|
|
15373
15569
|
const hadRotation = isActiveSelection && activeObj && angleDelta > 0.01;
|
|
15374
|
-
if (hadRotation && activeObj instanceof fabric__namespace.ActiveSelection && activeGroupSelectionId === groupToMove.id) {
|
|
15375
|
-
|
|
15376
|
-
|
|
15377
|
-
|
|
15378
|
-
|
|
15379
|
-
|
|
15380
|
-
|
|
15570
|
+
if ((hadScale || hadRotation) && activeObj instanceof fabric__namespace.ActiveSelection && activeGroupSelectionId === groupToMove.id) {
|
|
15571
|
+
const groupTransformUpdates = {};
|
|
15572
|
+
if (hadRotation) {
|
|
15573
|
+
groupTransformUpdates.angle = normalizeAngle180(currentSelAngle);
|
|
15574
|
+
activeObj.__pixldocsGroupAngle = groupTransformUpdates.angle;
|
|
15575
|
+
}
|
|
15576
|
+
if (hadScale && (transformStart == null ? void 0 : transformStart.groupId) === groupToMove.id) {
|
|
15577
|
+
const center = activeObj.getCenterPoint();
|
|
15578
|
+
const nextWidth = Math.max(1, transformStart.groupWidth * Math.abs(activeObj.scaleX ?? 1));
|
|
15579
|
+
const nextHeight = Math.max(1, transformStart.groupHeight * Math.abs(activeObj.scaleY ?? 1));
|
|
15580
|
+
const storePos = absoluteToStorePosition(
|
|
15581
|
+
center.x - nextWidth / 2,
|
|
15582
|
+
center.y - nextHeight / 2,
|
|
15583
|
+
groupToMove.id,
|
|
15584
|
+
pageChildren2
|
|
15585
|
+
);
|
|
15586
|
+
groupTransformUpdates.left = storePos.left;
|
|
15587
|
+
groupTransformUpdates.top = storePos.top;
|
|
15588
|
+
groupTransformUpdates.width = nextWidth;
|
|
15589
|
+
groupTransformUpdates.height = nextHeight;
|
|
15590
|
+
} else if (!Number.isFinite(Number(groupToMove.width)) || !Number.isFinite(Number(groupToMove.height))) {
|
|
15591
|
+
groupTransformUpdates.width = (transformStart == null ? void 0 : transformStart.groupWidth) ?? groupAbs.width;
|
|
15592
|
+
groupTransformUpdates.height = (transformStart == null ? void 0 : transformStart.groupHeight) ?? groupAbs.height;
|
|
15593
|
+
}
|
|
15594
|
+
if (Object.keys(groupTransformUpdates).length > 0) {
|
|
15595
|
+
useEditorStore.getState().updateNode(
|
|
15596
|
+
groupToMove.id,
|
|
15597
|
+
groupTransformUpdates,
|
|
15598
|
+
{ recordHistory: false, skipLayoutRecalc: true }
|
|
15599
|
+
);
|
|
15600
|
+
}
|
|
15381
15601
|
}
|
|
15382
15602
|
if (!hadScale && !hadRotation && (Math.abs(deltaX) > 0.1 || Math.abs(deltaY) > 0.1)) {
|
|
15383
15603
|
const { updateNode: updateNodeStore, commitHistory: commitHistoryStore, getCurrentElements } = useEditorStore.getState();
|
|
@@ -16014,9 +16234,11 @@ const PageCanvas = react.forwardRef(
|
|
|
16014
16234
|
} catch {
|
|
16015
16235
|
}
|
|
16016
16236
|
fabricCanvas.setActiveObject(newSel);
|
|
16017
|
-
|
|
16018
|
-
|
|
16019
|
-
|
|
16237
|
+
if (!wasGroupSel) {
|
|
16238
|
+
try {
|
|
16239
|
+
(_j = newSel.triggerLayout) == null ? void 0 : _j.call(newSel);
|
|
16240
|
+
} catch {
|
|
16241
|
+
}
|
|
16020
16242
|
}
|
|
16021
16243
|
try {
|
|
16022
16244
|
for (const member of membersToReselect) member.setCoords();
|
|
@@ -16393,7 +16615,12 @@ const PageCanvas = react.forwardRef(
|
|
|
16393
16615
|
const prevAS = activeBeforeSync instanceof fabric__namespace.ActiveSelection ? activeBeforeSync : null;
|
|
16394
16616
|
const prevMembers = prevAS ? prevAS.getObjects() : [];
|
|
16395
16617
|
const sameMembers = !!prevAS && prevMembers.length === freshMembers.length && prevMembers.every((m) => freshMembers.includes(m));
|
|
16396
|
-
const
|
|
16618
|
+
const savedSnapshotAngle = activeSelectionSnapshot.groupSelectionId ? (() => {
|
|
16619
|
+
const groupNode = findNodeById(pageTree, activeSelectionSnapshot.groupSelectionId);
|
|
16620
|
+
return groupNode && isGroup(groupNode) && typeof groupNode.angle === "number" ? groupNode.angle : null;
|
|
16621
|
+
})() : null;
|
|
16622
|
+
const prevAlignedAngle = sameMembers ? prevAS.__pixldocsAlignedAngle : null;
|
|
16623
|
+
const alreadyAligned = sameMembers && typeof prevAlignedAngle === "number" && (savedSnapshotAngle == null || Math.abs(normalizeAngle180(prevAlignedAngle - savedSnapshotAngle)) <= 0.01);
|
|
16397
16624
|
if (sameMembers && alreadyAligned) {
|
|
16398
16625
|
try {
|
|
16399
16626
|
ensureCanvaControlRenders(prevAS);
|
|
@@ -17435,11 +17662,10 @@ const PageCanvas = react.forwardRef(
|
|
|
17435
17662
|
if (sameSelection && (isFlatGroupSelection || isPureSingleGroupSelection)) {
|
|
17436
17663
|
if (selectedGroupSelectionId && active instanceof fabric__namespace.ActiveSelection) {
|
|
17437
17664
|
if (isPureSingleGroupSelection) {
|
|
17438
|
-
active
|
|
17439
|
-
delete active.__pixldocsLogicalGroupIds;
|
|
17440
|
-
suppressGroupMemberBordersRef.current = active.getObjects();
|
|
17665
|
+
applyLogicalGroupSelectionVisualState(active, selectedGroupSelectionId);
|
|
17441
17666
|
} else {
|
|
17442
17667
|
delete active.__pixldocsGroupSelection;
|
|
17668
|
+
delete active.__pixldocsGroupAngle;
|
|
17443
17669
|
active.__pixldocsLogicalGroupIds = selectedGroupIds;
|
|
17444
17670
|
active.hasBorders = true;
|
|
17445
17671
|
suppressGroupMemberBordersRef.current = active.getObjects().filter((m) => {
|
|
@@ -17479,10 +17705,10 @@ const PageCanvas = react.forwardRef(
|
|
|
17479
17705
|
const selection = new fabric__namespace.ActiveSelection(toSelect, { canvas: fc });
|
|
17480
17706
|
if (selectedGroupSelectionId) {
|
|
17481
17707
|
if (isPureSingleGroupSelection) {
|
|
17482
|
-
selection
|
|
17483
|
-
suppressGroupMemberBordersRef.current = toSelect;
|
|
17708
|
+
applyLogicalGroupSelectionVisualState(selection, selectedGroupSelectionId);
|
|
17484
17709
|
} else {
|
|
17485
17710
|
selection.__pixldocsLogicalGroupIds = selectedGroupIds;
|
|
17711
|
+
delete selection.__pixldocsGroupAngle;
|
|
17486
17712
|
selection.hasBorders = true;
|
|
17487
17713
|
suppressGroupMemberBordersRef.current = toSelect.filter((m) => {
|
|
17488
17714
|
const id = getObjectId(m);
|
|
@@ -25125,9 +25351,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
25125
25351
|
}
|
|
25126
25352
|
return svgString;
|
|
25127
25353
|
}
|
|
25128
|
-
const resolvedPackageVersion = "0.5.
|
|
25354
|
+
const resolvedPackageVersion = "0.5.396";
|
|
25129
25355
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
25130
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
25356
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.396";
|
|
25131
25357
|
const roundParityValue = (value) => {
|
|
25132
25358
|
if (typeof value !== "number") return value;
|
|
25133
25359
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -25941,7 +26167,7 @@ class PixldocsRenderer {
|
|
|
25941
26167
|
await this.waitForCanvasScene(container, cloned, i);
|
|
25942
26168
|
}
|
|
25943
26169
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
25944
|
-
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
26170
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-oL70Zv8c.cjs"));
|
|
25945
26171
|
const prepared = preparePagesForExport(
|
|
25946
26172
|
cloned.pages,
|
|
25947
26173
|
canvasWidth,
|
|
@@ -28261,7 +28487,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
28261
28487
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
28262
28488
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
28263
28489
|
try {
|
|
28264
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
28490
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-oL70Zv8c.cjs"));
|
|
28265
28491
|
try {
|
|
28266
28492
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
28267
28493
|
} catch {
|
|
@@ -28658,4 +28884,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
28658
28884
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
28659
28885
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
28660
28886
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
28661
|
-
//# sourceMappingURL=index-
|
|
28887
|
+
//# sourceMappingURL=index-DQYnrYMM.cjs.map
|