@pixldocs/canvas-renderer 0.5.240 → 0.5.242
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-B2H1tQ0S.js → index-BQ5V2uT8.js} +2429 -278
- package/dist/index-BQ5V2uT8.js.map +1 -0
- package/dist/{index-DBOS1ouN.cjs → index-YCh9sTg1.cjs} +2429 -278
- package/dist/index-YCh9sTg1.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-CHVrwSi7.js → vectorPdfExport-CsrQStE8.js} +4 -4
- package/dist/{vectorPdfExport-CHVrwSi7.js.map → vectorPdfExport-CsrQStE8.js.map} +1 -1
- package/dist/{vectorPdfExport-D1yCN3sm.cjs → vectorPdfExport-De9vylBF.cjs} +4 -4
- package/dist/{vectorPdfExport-D1yCN3sm.cjs.map → vectorPdfExport-De9vylBF.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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
-
var _a;
|
|
5
|
+
var _a, _b;
|
|
6
6
|
const jsxRuntime = require("react/jsx-runtime");
|
|
7
7
|
const react = require("react");
|
|
8
8
|
const reactDom = require("react-dom");
|
|
@@ -291,13 +291,13 @@ function lineToString(line) {
|
|
|
291
291
|
return Array.isArray(line) ? line.join("") : String(line ?? "");
|
|
292
292
|
}
|
|
293
293
|
function measureTextLineWithCanvas(textbox, lineText, lineIndex) {
|
|
294
|
-
var _a2,
|
|
294
|
+
var _a2, _b2, _c, _d, _e;
|
|
295
295
|
if (!lineText) return 0;
|
|
296
296
|
const ctx = getMeasureContext();
|
|
297
297
|
if (!ctx) return null;
|
|
298
298
|
const tb = textbox;
|
|
299
299
|
const fontSize = Number(((_a2 = tb.getValueOfPropertyAt) == null ? void 0 : _a2.call(tb, lineIndex, 0, "fontSize")) ?? textbox.fontSize ?? 16);
|
|
300
|
-
const fontStyle = String(((
|
|
300
|
+
const fontStyle = String(((_b2 = tb.getValueOfPropertyAt) == null ? void 0 : _b2.call(tb, lineIndex, 0, "fontStyle")) ?? textbox.fontStyle ?? "normal");
|
|
301
301
|
const fontWeight = String(((_c = tb.getValueOfPropertyAt) == null ? void 0 : _c.call(tb, lineIndex, 0, "fontWeight")) ?? textbox.fontWeight ?? "400");
|
|
302
302
|
const fontFamily = String(((_d = tb.getValueOfPropertyAt) == null ? void 0 : _d.call(tb, lineIndex, 0, "fontFamily")) ?? textbox.fontFamily ?? "Open Sans");
|
|
303
303
|
const charSpacing = Number(((_e = tb.getValueOfPropertyAt) == null ? void 0 : _e.call(tb, lineIndex, 0, "charSpacing")) ?? textbox.charSpacing ?? 0);
|
|
@@ -786,7 +786,7 @@ function resolveStackGroupEffectivePositions(group, pageChildren, options) {
|
|
|
786
786
|
return out;
|
|
787
787
|
}
|
|
788
788
|
function groupBoundsFromChildren(group, pageChildren, options) {
|
|
789
|
-
var _a2,
|
|
789
|
+
var _a2, _b2;
|
|
790
790
|
const kids = group.children ?? [];
|
|
791
791
|
if (kids.length === 0) {
|
|
792
792
|
const w = group.width;
|
|
@@ -802,7 +802,7 @@ function groupBoundsFromChildren(group, pageChildren, options) {
|
|
|
802
802
|
return { width: b.width, height: b.height };
|
|
803
803
|
})();
|
|
804
804
|
const cl = positions ? ((_a2 = positions.get(child.id)) == null ? void 0 : _a2.left) ?? getNodeLeft(child) : getNodeLeft(child);
|
|
805
|
-
const ct = positions ? ((
|
|
805
|
+
const ct = positions ? ((_b2 = positions.get(child.id)) == null ? void 0 : _b2.top) ?? getNodeTop(child) : getNodeTop(child);
|
|
806
806
|
minX = Math.min(minX, cl);
|
|
807
807
|
minY = Math.min(minY, ct);
|
|
808
808
|
maxX = Math.max(maxX, cl + sz.width);
|
|
@@ -840,14 +840,14 @@ function getNodeBoundsFromChildren(node) {
|
|
|
840
840
|
return getNodeBounds(node);
|
|
841
841
|
}
|
|
842
842
|
function absoluteBoundsRecur(node, pageChildren, options) {
|
|
843
|
-
var _a2,
|
|
843
|
+
var _a2, _b2;
|
|
844
844
|
const parent = pageChildren ? findParentGroup(pageChildren, node.id) : null;
|
|
845
845
|
const b = getNodeBounds(node, pageChildren);
|
|
846
846
|
if (!parent) return b;
|
|
847
847
|
const parentAbs = absoluteBoundsRecur(parent, pageChildren);
|
|
848
848
|
const isStackParent = isStackLayoutMode(parent.layoutMode);
|
|
849
849
|
const inParentLeft = isStackParent ? ((_a2 = resolveStackGroupEffectivePositions(parent, pageChildren).get(node.id)) == null ? void 0 : _a2.left) ?? b.left : b.left;
|
|
850
|
-
const inParentTop = isStackParent ? ((
|
|
850
|
+
const inParentTop = isStackParent ? ((_b2 = resolveStackGroupEffectivePositions(parent, pageChildren).get(node.id)) == null ? void 0 : _b2.top) ?? b.top : b.top;
|
|
851
851
|
return {
|
|
852
852
|
left: parentAbs.left + inParentLeft,
|
|
853
853
|
top: parentAbs.top + inParentTop,
|
|
@@ -1027,7 +1027,7 @@ const defaultProjectSettings = {
|
|
|
1027
1027
|
snapToGrid: false,
|
|
1028
1028
|
gridSize: 20,
|
|
1029
1029
|
snapToGuides: true,
|
|
1030
|
-
snapThreshold:
|
|
1030
|
+
snapThreshold: 8
|
|
1031
1031
|
};
|
|
1032
1032
|
const defaultPageSettings = {
|
|
1033
1033
|
backgroundColor: "#ffffff"
|
|
@@ -3565,7 +3565,7 @@ const clearFontCacheAndRerender = (canvas, options = {}) => {
|
|
|
3565
3565
|
}
|
|
3566
3566
|
};
|
|
3567
3567
|
const collectUnderlineMetrics = (obj) => {
|
|
3568
|
-
var _a2,
|
|
3568
|
+
var _a2, _b2;
|
|
3569
3569
|
if (obj instanceof fabric__namespace.Textbox) {
|
|
3570
3570
|
if (!obj.underline) return [];
|
|
3571
3571
|
const lineWidths = obj.__lineWidths;
|
|
@@ -3580,7 +3580,7 @@ const clearFontCacheAndRerender = (canvas, options = {}) => {
|
|
|
3580
3580
|
height: obj.height ?? null,
|
|
3581
3581
|
scaleX: obj.scaleX,
|
|
3582
3582
|
scaleY: obj.scaleY,
|
|
3583
|
-
lineCount: ((
|
|
3583
|
+
lineCount: ((_b2 = obj.textLines) == null ? void 0 : _b2.length) ?? 0,
|
|
3584
3584
|
maxLineWidth: lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : null
|
|
3585
3585
|
}];
|
|
3586
3586
|
}
|
|
@@ -3610,13 +3610,13 @@ const clearFontCacheAndRerender = (canvas, options = {}) => {
|
|
|
3610
3610
|
canvas.requestRenderAll();
|
|
3611
3611
|
};
|
|
3612
3612
|
const ensureFontLoaded = async (fontFamily) => {
|
|
3613
|
-
var _a2,
|
|
3613
|
+
var _a2, _b2, _c;
|
|
3614
3614
|
if (!fontFamily) return;
|
|
3615
3615
|
if (LOCAL_FONTS.has(fontFamily)) {
|
|
3616
3616
|
try {
|
|
3617
3617
|
const isLoaded = (_a2 = document.fonts) == null ? void 0 : _a2.check(`16px "${fontFamily}"`);
|
|
3618
3618
|
if (isLoaded) return;
|
|
3619
|
-
await ((
|
|
3619
|
+
await ((_b2 = document.fonts) == null ? void 0 : _b2.load(`16px "${fontFamily}"`));
|
|
3620
3620
|
await ((_c = document.fonts) == null ? void 0 : _c.load(`bold 16px "${fontFamily}"`));
|
|
3621
3621
|
} catch (e) {
|
|
3622
3622
|
console.warn(`Failed to ensure local font loaded: ${fontFamily}`, e);
|
|
@@ -4111,7 +4111,7 @@ function createImageClipPath(element, imgWidth, imgHeight) {
|
|
|
4111
4111
|
}
|
|
4112
4112
|
}
|
|
4113
4113
|
async function loadImageAsync(element, placeholder, fc, fabricRef, syncLockedRef, isTransforming) {
|
|
4114
|
-
var _a2,
|
|
4114
|
+
var _a2, _b2, _c, _d;
|
|
4115
4115
|
const imageUrl = element.src || element.imageUrl;
|
|
4116
4116
|
if (!imageUrl) return;
|
|
4117
4117
|
const nextSvgColorMap = element.svgColorMap ? JSON.stringify(element.svgColorMap) : "";
|
|
@@ -4275,7 +4275,7 @@ async function loadImageAsync(element, placeholder, fc, fabricRef, syncLockedRef
|
|
|
4275
4275
|
if (existingCropGroup) {
|
|
4276
4276
|
const existingImg = (_a2 = existingCropGroup.__cropData) == null ? void 0 : _a2._img;
|
|
4277
4277
|
if (existingImg) {
|
|
4278
|
-
panX = ((
|
|
4278
|
+
panX = ((_b2 = existingImg._ct) == null ? void 0 : _b2.panX) ?? existingImg.__panX ?? 0.5;
|
|
4279
4279
|
panY = ((_c = existingImg._ct) == null ? void 0 : _c.panY) ?? existingImg.__panY ?? 0.5;
|
|
4280
4280
|
zoom = ((_d = existingImg._ct) == null ? void 0 : _d.zoom) ?? 1;
|
|
4281
4281
|
}
|
|
@@ -4483,11 +4483,11 @@ function isLuminanceMaskClipPath(clipPath) {
|
|
|
4483
4483
|
return Boolean(clipPath && clipPath.__svgMaskType === "luminance");
|
|
4484
4484
|
}
|
|
4485
4485
|
function syncSvgMaskClipPath(cropGroup) {
|
|
4486
|
-
var _a2,
|
|
4486
|
+
var _a2, _b2;
|
|
4487
4487
|
const clipPath = cropGroup.clipPath;
|
|
4488
4488
|
if (!isCropGroup(cropGroup)) return;
|
|
4489
4489
|
const frameW = ((_a2 = cropGroup._ct) == null ? void 0 : _a2.frameW) ?? cropGroup.width ?? 0;
|
|
4490
|
-
const frameH = ((
|
|
4490
|
+
const frameH = ((_b2 = cropGroup._ct) == null ? void 0 : _b2.frameH) ?? cropGroup.height ?? 0;
|
|
4491
4491
|
if (frameW <= 0 || frameH <= 0) return;
|
|
4492
4492
|
if (isSvgMaskClipPath(clipPath)) {
|
|
4493
4493
|
fitMaskGroupToFrame(clipPath, frameW, frameH);
|
|
@@ -4511,12 +4511,12 @@ async function detectMaskType(svgUrl) {
|
|
|
4511
4511
|
}
|
|
4512
4512
|
}
|
|
4513
4513
|
async function applySvgMaskToCropGroup(cropGroup, svgUrl) {
|
|
4514
|
-
var _a2,
|
|
4514
|
+
var _a2, _b2, _c;
|
|
4515
4515
|
if (!isCropGroup(cropGroup)) {
|
|
4516
4516
|
throw new Error("Selected object is not a crop group / image");
|
|
4517
4517
|
}
|
|
4518
4518
|
const frameW = ((_a2 = cropGroup._ct) == null ? void 0 : _a2.frameW) ?? cropGroup.width ?? 0;
|
|
4519
|
-
const frameH = ((
|
|
4519
|
+
const frameH = ((_b2 = cropGroup._ct) == null ? void 0 : _b2.frameH) ?? cropGroup.height ?? 0;
|
|
4520
4520
|
if (frameW <= 0 || frameH <= 0) {
|
|
4521
4521
|
throw new Error("Crop group has no frame dimensions");
|
|
4522
4522
|
}
|
|
@@ -4602,12 +4602,12 @@ async function buildLuminanceAlphaCanvas(svgUrl, frameW, frameH) {
|
|
|
4602
4602
|
return canvas;
|
|
4603
4603
|
}
|
|
4604
4604
|
async function applyLuminanceMaskToCropGroup(cropGroup, svgUrl) {
|
|
4605
|
-
var _a2,
|
|
4605
|
+
var _a2, _b2, _c;
|
|
4606
4606
|
if (!isCropGroup(cropGroup)) {
|
|
4607
4607
|
throw new Error("Selected object is not a crop group / image");
|
|
4608
4608
|
}
|
|
4609
4609
|
const frameW = ((_a2 = cropGroup._ct) == null ? void 0 : _a2.frameW) ?? cropGroup.width ?? 0;
|
|
4610
|
-
const frameH = ((
|
|
4610
|
+
const frameH = ((_b2 = cropGroup._ct) == null ? void 0 : _b2.frameH) ?? cropGroup.height ?? 0;
|
|
4611
4611
|
if (frameW <= 0 || frameH <= 0) {
|
|
4612
4612
|
throw new Error("Crop group has no frame dimensions");
|
|
4613
4613
|
}
|
|
@@ -4656,10 +4656,10 @@ function getAppliedSvgMaskType(obj) {
|
|
|
4656
4656
|
return t === "luminance" || t === "shape" ? t : null;
|
|
4657
4657
|
}
|
|
4658
4658
|
function clearSvgMaskFromCropGroup(cropGroup) {
|
|
4659
|
-
var _a2,
|
|
4659
|
+
var _a2, _b2, _c;
|
|
4660
4660
|
if (!isCropGroup(cropGroup)) return;
|
|
4661
4661
|
const frameW = ((_a2 = cropGroup._ct) == null ? void 0 : _a2.frameW) ?? cropGroup.width ?? 0;
|
|
4662
|
-
const frameH = ((
|
|
4662
|
+
const frameH = ((_b2 = cropGroup._ct) == null ? void 0 : _b2.frameH) ?? cropGroup.height ?? 0;
|
|
4663
4663
|
const rect = new fabric__namespace.Rect({
|
|
4664
4664
|
width: frameW,
|
|
4665
4665
|
height: frameH,
|
|
@@ -4693,17 +4693,16 @@ const svgMaskApply = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.define
|
|
|
4693
4693
|
isSvgMaskClipPath,
|
|
4694
4694
|
syncSvgMaskClipPath
|
|
4695
4695
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
4696
|
+
const SELECTION_BORDER_SCALE$1 = 2;
|
|
4696
4697
|
function clamp$1(v, min, max) {
|
|
4697
4698
|
return Math.max(min, Math.min(max, v));
|
|
4698
4699
|
}
|
|
4699
4700
|
function applyControlSizeForZoom(canvas, obj) {
|
|
4700
4701
|
if (!canvas || !obj) return;
|
|
4701
|
-
const z = canvas.getZoom() || 1;
|
|
4702
|
-
const size = Math.max(6, Math.round(8 * z));
|
|
4703
4702
|
obj.set({
|
|
4704
|
-
cornerSize:
|
|
4705
|
-
|
|
4706
|
-
borderScaleFactor:
|
|
4703
|
+
cornerSize: 10,
|
|
4704
|
+
touchCornerSize: 20,
|
|
4705
|
+
borderScaleFactor: SELECTION_BORDER_SCALE$1
|
|
4707
4706
|
});
|
|
4708
4707
|
obj.setCoords();
|
|
4709
4708
|
}
|
|
@@ -5080,6 +5079,21 @@ function resizeFrameFromSide(g, side, localDx, localDy) {
|
|
|
5080
5079
|
function installCanvaMaskControls(g) {
|
|
5081
5080
|
const ct = g.__cropData;
|
|
5082
5081
|
if (ct) ct.fit = ct.fit ?? "cover";
|
|
5082
|
+
const controlStyle = {
|
|
5083
|
+
cornerSize: 10,
|
|
5084
|
+
touchCornerSize: 20,
|
|
5085
|
+
borderScaleFactor: SELECTION_BORDER_SCALE$1,
|
|
5086
|
+
transparentCorners: false,
|
|
5087
|
+
cornerStyle: "circle",
|
|
5088
|
+
cornerColor: "hsl(217, 91%, 60%)",
|
|
5089
|
+
cornerStrokeColor: "#ffffff",
|
|
5090
|
+
borderColor: "hsl(217, 91%, 60%)"
|
|
5091
|
+
};
|
|
5092
|
+
g.set(controlStyle);
|
|
5093
|
+
const notifyResizeSnap = (target, corner) => {
|
|
5094
|
+
const handler = target.__resizeSnapHandler;
|
|
5095
|
+
if (typeof handler === "function") handler(target, corner);
|
|
5096
|
+
};
|
|
5083
5097
|
g.setControlsVisibility({
|
|
5084
5098
|
mt: true,
|
|
5085
5099
|
mb: true,
|
|
@@ -5109,6 +5123,7 @@ function installCanvaMaskControls(g) {
|
|
|
5109
5123
|
const { localDx, localDy } = getLocalDeltaStable(t, eventData);
|
|
5110
5124
|
t.__lockScaleDuringCrop = true;
|
|
5111
5125
|
resizeFrameFromSide(t, side, localDx, localDy);
|
|
5126
|
+
notifyResizeSnap(t, side);
|
|
5112
5127
|
(_a2 = t.canvas) == null ? void 0 : _a2.requestRenderAll();
|
|
5113
5128
|
return true;
|
|
5114
5129
|
}
|
|
@@ -5133,7 +5148,9 @@ function installCanvaMaskControls(g) {
|
|
|
5133
5148
|
if (canvas && canvas.__editLockRef) {
|
|
5134
5149
|
canvas.__editLockRef.current = true;
|
|
5135
5150
|
}
|
|
5136
|
-
|
|
5151
|
+
const resized = resizeFrameFromCornerUniform(eventData, transform);
|
|
5152
|
+
if (resized) notifyResizeSnap(t, key);
|
|
5153
|
+
return resized;
|
|
5137
5154
|
}
|
|
5138
5155
|
});
|
|
5139
5156
|
};
|
|
@@ -5142,6 +5159,8 @@ function installCanvaMaskControls(g) {
|
|
|
5142
5159
|
g.controls.bl = makeCornerControl("bl", -0.5, 0.5, "nesw-resize");
|
|
5143
5160
|
g.controls.br = makeCornerControl("br", 0.5, 0.5, "nwse-resize");
|
|
5144
5161
|
g.__hasCustomControls = true;
|
|
5162
|
+
g.set(controlStyle);
|
|
5163
|
+
g.setCoords();
|
|
5145
5164
|
}
|
|
5146
5165
|
async function createMaskedImageElement({
|
|
5147
5166
|
url,
|
|
@@ -5712,12 +5731,15 @@ function exitCropMode(g, commit = true) {
|
|
|
5712
5731
|
g.hasControls = true;
|
|
5713
5732
|
g.borderDashArray = void 0;
|
|
5714
5733
|
installCanvaMaskControls(g);
|
|
5715
|
-
g.borderColor = "
|
|
5734
|
+
g.borderColor = "hsl(217, 91%, 60%)";
|
|
5716
5735
|
g.borderDashArray = void 0;
|
|
5717
|
-
g.cornerColor = "
|
|
5718
|
-
g.cornerStrokeColor = "#
|
|
5719
|
-
g.cornerStyle = "
|
|
5736
|
+
g.cornerColor = "hsl(217, 91%, 60%)";
|
|
5737
|
+
g.cornerStrokeColor = "#ffffff";
|
|
5738
|
+
g.cornerStyle = "circle";
|
|
5720
5739
|
g.transparentCorners = false;
|
|
5740
|
+
g.cornerSize = 10;
|
|
5741
|
+
g.touchCornerSize = 20;
|
|
5742
|
+
g.borderScaleFactor = 2;
|
|
5721
5743
|
g[CROP_MODE_FLAG] = false;
|
|
5722
5744
|
g.__cropZoomLastPointer = void 0;
|
|
5723
5745
|
g.__lastPointerForCrop = void 0;
|
|
@@ -5726,6 +5748,16 @@ function exitCropMode(g, commit = true) {
|
|
|
5726
5748
|
}
|
|
5727
5749
|
canvas == null ? void 0 : canvas.requestRenderAll();
|
|
5728
5750
|
}
|
|
5751
|
+
function boundsToSnapPoints(bounds) {
|
|
5752
|
+
return {
|
|
5753
|
+
left: bounds.left,
|
|
5754
|
+
right: bounds.left + bounds.width,
|
|
5755
|
+
top: bounds.top,
|
|
5756
|
+
bottom: bounds.top + bounds.height,
|
|
5757
|
+
centerX: bounds.left + bounds.width / 2,
|
|
5758
|
+
centerY: bounds.top + bounds.height / 2
|
|
5759
|
+
};
|
|
5760
|
+
}
|
|
5729
5761
|
function getObjectSnapPoints(obj) {
|
|
5730
5762
|
try {
|
|
5731
5763
|
obj.setCoords();
|
|
@@ -5755,7 +5787,8 @@ function getObjectSnapPoints(obj) {
|
|
|
5755
5787
|
}
|
|
5756
5788
|
function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold) {
|
|
5757
5789
|
if (!snapToGuides) return { guides: [], snapDx: 0, snapDy: 0 };
|
|
5758
|
-
const threshold = snapThreshold ||
|
|
5790
|
+
const threshold = snapThreshold || 8;
|
|
5791
|
+
const centerThreshold = threshold * 1.75;
|
|
5759
5792
|
const newGuides = [];
|
|
5760
5793
|
const horizontalSnaps = [];
|
|
5761
5794
|
const verticalSnaps = [];
|
|
@@ -5775,12 +5808,24 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5775
5808
|
horizontalSnaps.push({ delta: targetPoint - objPoint, distance, guide });
|
|
5776
5809
|
}
|
|
5777
5810
|
};
|
|
5811
|
+
const addCanvasCenterVerticalSnap = (objPoint, targetPoint, guide) => {
|
|
5812
|
+
const distance = Math.abs(objPoint - targetPoint);
|
|
5813
|
+
if (distance < centerThreshold) {
|
|
5814
|
+
verticalSnaps.push({ delta: targetPoint - objPoint, distance: distance * 0.85, guide });
|
|
5815
|
+
}
|
|
5816
|
+
};
|
|
5817
|
+
const addCanvasCenterHorizontalSnap = (objPoint, targetPoint, guide) => {
|
|
5818
|
+
const distance = Math.abs(objPoint - targetPoint);
|
|
5819
|
+
if (distance < centerThreshold) {
|
|
5820
|
+
horizontalSnaps.push({ delta: targetPoint - objPoint, distance: distance * 0.85, guide });
|
|
5821
|
+
}
|
|
5822
|
+
};
|
|
5778
5823
|
addVerticalSnap(moving.left, 0, { type: "vertical", position: 0 });
|
|
5779
5824
|
addVerticalSnap(moving.right, canvasWidth, { type: "vertical", position: canvasWidth });
|
|
5780
5825
|
addHorizontalSnap(moving.top, 0, { type: "horizontal", position: 0 });
|
|
5781
5826
|
addHorizontalSnap(moving.bottom, canvasHeight, { type: "horizontal", position: canvasHeight });
|
|
5782
|
-
|
|
5783
|
-
|
|
5827
|
+
addCanvasCenterVerticalSnap(moving.centerX, canvasCenterX, { type: "vertical", position: canvasCenterX });
|
|
5828
|
+
addCanvasCenterHorizontalSnap(moving.centerY, canvasCenterY, { type: "horizontal", position: canvasCenterY });
|
|
5784
5829
|
const rawObjects = canvas.getObjects();
|
|
5785
5830
|
const allObjects = [];
|
|
5786
5831
|
for (const obj of rawObjects) {
|
|
@@ -5800,16 +5845,22 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5800
5845
|
}
|
|
5801
5846
|
for (const otherObj of allObjects) {
|
|
5802
5847
|
const other = getObjectSnapPoints(otherObj);
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5848
|
+
const tb = {
|
|
5849
|
+
left: other.left,
|
|
5850
|
+
top: other.top,
|
|
5851
|
+
width: other.right - other.left,
|
|
5852
|
+
height: other.bottom - other.top
|
|
5853
|
+
};
|
|
5854
|
+
addVerticalSnap(moving.left, other.left, { type: "vertical", position: other.left, start: Math.min(moving.top, other.top), end: Math.max(moving.bottom, other.bottom), targetBounds: tb });
|
|
5855
|
+
addVerticalSnap(moving.right, other.right, { type: "vertical", position: other.right, start: Math.min(moving.top, other.top), end: Math.max(moving.bottom, other.bottom), targetBounds: tb });
|
|
5856
|
+
addVerticalSnap(moving.left, other.right, { type: "vertical", position: other.right, start: Math.min(moving.top, other.top), end: Math.max(moving.bottom, other.bottom), targetBounds: tb });
|
|
5857
|
+
addVerticalSnap(moving.right, other.left, { type: "vertical", position: other.left, start: Math.min(moving.top, other.top), end: Math.max(moving.bottom, other.bottom), targetBounds: tb });
|
|
5858
|
+
addVerticalSnap(moving.centerX, other.centerX, { type: "vertical", position: other.centerX, start: Math.min(moving.top, other.top), end: Math.max(moving.bottom, other.bottom), targetBounds: tb });
|
|
5859
|
+
addHorizontalSnap(moving.top, other.top, { type: "horizontal", position: other.top, start: Math.min(moving.left, other.left), end: Math.max(moving.right, other.right), targetBounds: tb });
|
|
5860
|
+
addHorizontalSnap(moving.bottom, other.bottom, { type: "horizontal", position: other.bottom, start: Math.min(moving.left, other.left), end: Math.max(moving.right, other.right), targetBounds: tb });
|
|
5861
|
+
addHorizontalSnap(moving.top, other.bottom, { type: "horizontal", position: other.bottom, start: Math.min(moving.left, other.left), end: Math.max(moving.right, other.right), targetBounds: tb });
|
|
5862
|
+
addHorizontalSnap(moving.bottom, other.top, { type: "horizontal", position: other.top, start: Math.min(moving.left, other.left), end: Math.max(moving.right, other.right), targetBounds: tb });
|
|
5863
|
+
addHorizontalSnap(moving.centerY, other.centerY, { type: "horizontal", position: other.centerY, start: Math.min(moving.left, other.left), end: Math.max(moving.right, other.right), targetBounds: tb });
|
|
5813
5864
|
}
|
|
5814
5865
|
let snapDx = 0;
|
|
5815
5866
|
let snapDy = 0;
|
|
@@ -5817,19 +5868,129 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5817
5868
|
verticalSnaps.sort((a, b) => a.distance - b.distance);
|
|
5818
5869
|
const bestSnap = verticalSnaps[0];
|
|
5819
5870
|
snapDx = bestSnap.delta;
|
|
5820
|
-
newGuides.push({ ...bestSnap.guide,
|
|
5871
|
+
newGuides.push({ ...bestSnap.guide, kind: "alignment" });
|
|
5821
5872
|
}
|
|
5822
5873
|
if (horizontalSnaps.length > 0) {
|
|
5823
5874
|
horizontalSnaps.sort((a, b) => a.distance - b.distance);
|
|
5824
5875
|
const bestSnap = horizontalSnaps[0];
|
|
5825
5876
|
snapDy = bestSnap.delta;
|
|
5826
|
-
newGuides.push({ ...bestSnap.guide,
|
|
5877
|
+
newGuides.push({ ...bestSnap.guide, kind: "alignment" });
|
|
5878
|
+
}
|
|
5879
|
+
const projectedLeft = moving.left + snapDx;
|
|
5880
|
+
const projectedRight = moving.right + snapDx;
|
|
5881
|
+
moving.centerX + snapDx;
|
|
5882
|
+
const projectedTop = moving.top + snapDy;
|
|
5883
|
+
const projectedBottom = moving.bottom + snapDy;
|
|
5884
|
+
moving.centerY + snapDy;
|
|
5885
|
+
if (snapDx === 0) {
|
|
5886
|
+
let bestPair = null;
|
|
5887
|
+
for (const a of allObjects) {
|
|
5888
|
+
const A = getObjectSnapPoints(a);
|
|
5889
|
+
if (A.right > projectedLeft) continue;
|
|
5890
|
+
if (A.bottom < projectedTop || A.top > projectedBottom) continue;
|
|
5891
|
+
for (const b of allObjects) {
|
|
5892
|
+
if (b === a) continue;
|
|
5893
|
+
const B = getObjectSnapPoints(b);
|
|
5894
|
+
if (B.left < projectedRight) continue;
|
|
5895
|
+
if (B.bottom < projectedTop || B.top > projectedBottom) continue;
|
|
5896
|
+
const gapL = projectedLeft - A.right;
|
|
5897
|
+
const gapR = B.left - projectedRight;
|
|
5898
|
+
const diff = gapR - gapL;
|
|
5899
|
+
const absDiff = Math.abs(diff);
|
|
5900
|
+
if (absDiff < threshold && (!bestPair || absDiff < bestPair.absDiff)) {
|
|
5901
|
+
bestPair = { A, B, delta: diff / 2, absDiff };
|
|
5902
|
+
}
|
|
5903
|
+
}
|
|
5904
|
+
}
|
|
5905
|
+
if (bestPair) {
|
|
5906
|
+
snapDx = bestPair.delta;
|
|
5907
|
+
const newLeft = moving.left + snapDx;
|
|
5908
|
+
const newRight = moving.right + snapDx;
|
|
5909
|
+
const equalGap = Math.round(newLeft - bestPair.A.right);
|
|
5910
|
+
const bracketY = (Math.max(bestPair.A.top, projectedTop, bestPair.B.top) + Math.min(bestPair.A.bottom, projectedBottom, bestPair.B.bottom)) / 2;
|
|
5911
|
+
if (equalGap > 0) {
|
|
5912
|
+
const aTb = { left: bestPair.A.left, top: bestPair.A.top, width: bestPair.A.right - bestPair.A.left, height: bestPair.A.bottom - bestPair.A.top };
|
|
5913
|
+
const bTb = { left: bestPair.B.left, top: bestPair.B.top, width: bestPair.B.right - bestPair.B.left, height: bestPair.B.bottom - bestPair.B.top };
|
|
5914
|
+
newGuides.push({
|
|
5915
|
+
type: "horizontal",
|
|
5916
|
+
position: bracketY,
|
|
5917
|
+
kind: "gap",
|
|
5918
|
+
gap: equalGap,
|
|
5919
|
+
start: bestPair.A.right,
|
|
5920
|
+
end: newLeft,
|
|
5921
|
+
bracketAt: bracketY,
|
|
5922
|
+
targetBoundsList: [aTb, bTb]
|
|
5923
|
+
});
|
|
5924
|
+
newGuides.push({
|
|
5925
|
+
type: "horizontal",
|
|
5926
|
+
position: bracketY,
|
|
5927
|
+
kind: "gap",
|
|
5928
|
+
gap: equalGap,
|
|
5929
|
+
start: newRight,
|
|
5930
|
+
end: bestPair.B.left,
|
|
5931
|
+
bracketAt: bracketY,
|
|
5932
|
+
targetBoundsList: [aTb, bTb]
|
|
5933
|
+
});
|
|
5934
|
+
}
|
|
5935
|
+
}
|
|
5936
|
+
}
|
|
5937
|
+
if (snapDy === 0) {
|
|
5938
|
+
let bestPair = null;
|
|
5939
|
+
for (const a of allObjects) {
|
|
5940
|
+
const A = getObjectSnapPoints(a);
|
|
5941
|
+
if (A.bottom > projectedTop) continue;
|
|
5942
|
+
if (A.right < projectedLeft || A.left > projectedRight) continue;
|
|
5943
|
+
for (const b of allObjects) {
|
|
5944
|
+
if (b === a) continue;
|
|
5945
|
+
const B = getObjectSnapPoints(b);
|
|
5946
|
+
if (B.top < projectedBottom) continue;
|
|
5947
|
+
if (B.right < projectedLeft || B.left > projectedRight) continue;
|
|
5948
|
+
const gapT = projectedTop - A.bottom;
|
|
5949
|
+
const gapB = B.top - projectedBottom;
|
|
5950
|
+
const diff = gapB - gapT;
|
|
5951
|
+
const absDiff = Math.abs(diff);
|
|
5952
|
+
if (absDiff < threshold && (!bestPair || absDiff < bestPair.absDiff)) {
|
|
5953
|
+
bestPair = { A, B, delta: diff / 2, absDiff };
|
|
5954
|
+
}
|
|
5955
|
+
}
|
|
5956
|
+
}
|
|
5957
|
+
if (bestPair) {
|
|
5958
|
+
snapDy = bestPair.delta;
|
|
5959
|
+
const newTop = moving.top + snapDy;
|
|
5960
|
+
const newBottom = moving.bottom + snapDy;
|
|
5961
|
+
const equalGap = Math.round(newTop - bestPair.A.bottom);
|
|
5962
|
+
const bracketX = (Math.max(bestPair.A.left, projectedLeft, bestPair.B.left) + Math.min(bestPair.A.right, projectedRight, bestPair.B.right)) / 2;
|
|
5963
|
+
if (equalGap > 0) {
|
|
5964
|
+
const aTb = { left: bestPair.A.left, top: bestPair.A.top, width: bestPair.A.right - bestPair.A.left, height: bestPair.A.bottom - bestPair.A.top };
|
|
5965
|
+
const bTb = { left: bestPair.B.left, top: bestPair.B.top, width: bestPair.B.right - bestPair.B.left, height: bestPair.B.bottom - bestPair.B.top };
|
|
5966
|
+
newGuides.push({
|
|
5967
|
+
type: "vertical",
|
|
5968
|
+
position: bracketX,
|
|
5969
|
+
kind: "gap",
|
|
5970
|
+
gap: equalGap,
|
|
5971
|
+
start: bestPair.A.bottom,
|
|
5972
|
+
end: newTop,
|
|
5973
|
+
bracketAt: bracketX,
|
|
5974
|
+
targetBoundsList: [aTb, bTb]
|
|
5975
|
+
});
|
|
5976
|
+
newGuides.push({
|
|
5977
|
+
type: "vertical",
|
|
5978
|
+
position: bracketX,
|
|
5979
|
+
kind: "gap",
|
|
5980
|
+
gap: equalGap,
|
|
5981
|
+
start: newBottom,
|
|
5982
|
+
end: bestPair.B.top,
|
|
5983
|
+
bracketAt: bracketX,
|
|
5984
|
+
targetBoundsList: [aTb, bTb]
|
|
5985
|
+
});
|
|
5986
|
+
}
|
|
5987
|
+
}
|
|
5827
5988
|
}
|
|
5828
5989
|
return { guides: newGuides, snapDx, snapDy };
|
|
5829
5990
|
}
|
|
5830
|
-
function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold) {
|
|
5991
|
+
function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold, additionalBounds = []) {
|
|
5831
5992
|
if (!snapToGuides) return [];
|
|
5832
|
-
const threshold = snapThreshold
|
|
5993
|
+
const threshold = snapThreshold;
|
|
5833
5994
|
const newGuides = [];
|
|
5834
5995
|
const scaling = getObjectSnapPoints(scalingObj);
|
|
5835
5996
|
const scalingId = getObjectId(scalingObj);
|
|
@@ -5842,7 +6003,7 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5842
6003
|
const checkVerticalSnap = (edgePosition, targetPosition, guide) => {
|
|
5843
6004
|
const dist = Math.abs(edgePosition - targetPosition);
|
|
5844
6005
|
if (dist < threshold) {
|
|
5845
|
-
newGuides.push({ ...guide,
|
|
6006
|
+
newGuides.push({ ...guide, kind: "alignment" });
|
|
5846
6007
|
return true;
|
|
5847
6008
|
}
|
|
5848
6009
|
return false;
|
|
@@ -5850,7 +6011,7 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5850
6011
|
const checkHorizontalSnap = (edgePosition, targetPosition, guide) => {
|
|
5851
6012
|
const dist = Math.abs(edgePosition - targetPosition);
|
|
5852
6013
|
if (dist < threshold) {
|
|
5853
|
-
newGuides.push({ ...guide,
|
|
6014
|
+
newGuides.push({ ...guide, kind: "alignment" });
|
|
5854
6015
|
return true;
|
|
5855
6016
|
}
|
|
5856
6017
|
return false;
|
|
@@ -5872,12 +6033,39 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5872
6033
|
checkHorizontalSnap(scaling.bottom, canvasCenterY, { type: "horizontal", position: canvasCenterY });
|
|
5873
6034
|
}
|
|
5874
6035
|
const rawObjects = canvas.getObjects();
|
|
6036
|
+
const objectBounds = [];
|
|
5875
6037
|
for (const obj of rawObjects) {
|
|
5876
6038
|
if (obj === scalingObj) continue;
|
|
5877
6039
|
const objId = getObjectId(obj);
|
|
5878
6040
|
if (objId === "__background__") continue;
|
|
5879
6041
|
if (objId && objId === scalingId) continue;
|
|
5880
|
-
|
|
6042
|
+
if (scalingObj instanceof fabric__namespace.ActiveSelection && scalingObj.contains(obj)) continue;
|
|
6043
|
+
if (scalingObj instanceof fabric__namespace.Group && typeof scalingObj.getObjects === "function") {
|
|
6044
|
+
const inner = scalingObj.getObjects();
|
|
6045
|
+
if (inner.includes(obj)) continue;
|
|
6046
|
+
}
|
|
6047
|
+
objectBounds.push(getObjectSnapPoints(obj));
|
|
6048
|
+
}
|
|
6049
|
+
for (const bounds of additionalBounds) {
|
|
6050
|
+
objectBounds.push(boundsToSnapPoints(bounds));
|
|
6051
|
+
}
|
|
6052
|
+
let bestWidthMatch = null;
|
|
6053
|
+
let bestWidthDiff = threshold + 1;
|
|
6054
|
+
let bestHeightMatch = null;
|
|
6055
|
+
let bestHeightDiff = threshold + 1;
|
|
6056
|
+
for (const other of objectBounds) {
|
|
6057
|
+
const otherWidth = other.right - other.left;
|
|
6058
|
+
const otherHeight = other.bottom - other.top;
|
|
6059
|
+
const widthDiff = Math.abs(scaling.right - scaling.left - otherWidth);
|
|
6060
|
+
const heightDiff = Math.abs(scaling.bottom - scaling.top - otherHeight);
|
|
6061
|
+
if (resizingLeft !== resizingRight && widthDiff < bestWidthDiff) {
|
|
6062
|
+
bestWidthDiff = widthDiff;
|
|
6063
|
+
bestWidthMatch = other;
|
|
6064
|
+
}
|
|
6065
|
+
if (resizingTop !== resizingBottom && heightDiff < bestHeightDiff) {
|
|
6066
|
+
bestHeightDiff = heightDiff;
|
|
6067
|
+
bestHeightMatch = other;
|
|
6068
|
+
}
|
|
5881
6069
|
if (resizingLeft) {
|
|
5882
6070
|
checkVerticalSnap(scaling.left, other.left, {
|
|
5883
6071
|
type: "vertical",
|
|
@@ -5959,6 +6147,18 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5959
6147
|
});
|
|
5960
6148
|
}
|
|
5961
6149
|
}
|
|
6150
|
+
if (bestWidthMatch && bestWidthDiff < threshold) {
|
|
6151
|
+
newGuides.push(
|
|
6152
|
+
{ type: "horizontal", position: scaling.top, start: scaling.left, end: scaling.right, kind: "alignment" },
|
|
6153
|
+
{ type: "horizontal", position: bestWidthMatch.top, start: bestWidthMatch.left, end: bestWidthMatch.right, kind: "alignment" }
|
|
6154
|
+
);
|
|
6155
|
+
}
|
|
6156
|
+
if (bestHeightMatch && bestHeightDiff < threshold) {
|
|
6157
|
+
newGuides.push(
|
|
6158
|
+
{ type: "vertical", position: scaling.left, start: scaling.top, end: scaling.bottom, kind: "alignment" },
|
|
6159
|
+
{ type: "vertical", position: bestHeightMatch.left, start: bestHeightMatch.top, end: bestHeightMatch.bottom, kind: "alignment" }
|
|
6160
|
+
);
|
|
6161
|
+
}
|
|
5962
6162
|
const seen = /* @__PURE__ */ new Set();
|
|
5963
6163
|
return newGuides.filter((guide) => {
|
|
5964
6164
|
const key = `${guide.type}-${guide.position.toFixed(1)}`;
|
|
@@ -5967,6 +6167,349 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5967
6167
|
return true;
|
|
5968
6168
|
});
|
|
5969
6169
|
}
|
|
6170
|
+
const MIN_SNAP_BOX = 20;
|
|
6171
|
+
const SNAP_HYSTERESIS_PX = 6;
|
|
6172
|
+
function applyScaleSnapToBox(box, corner, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold, excludeObjectId, options) {
|
|
6173
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h;
|
|
6174
|
+
const hysteresis = (options == null ? void 0 : options.hysteresis) ?? SNAP_HYSTERESIS_PX;
|
|
6175
|
+
const activeSnapRef = options == null ? void 0 : options.activeSnapRef;
|
|
6176
|
+
const roundSnappedOnly = (options == null ? void 0 : options.roundSnappedOnly) ?? false;
|
|
6177
|
+
if (!snapToGuides || !canvas) {
|
|
6178
|
+
if (roundSnappedOnly) return { ...box };
|
|
6179
|
+
return {
|
|
6180
|
+
left: Math.round(box.left),
|
|
6181
|
+
top: Math.round(box.top),
|
|
6182
|
+
width: Math.round(box.width),
|
|
6183
|
+
height: Math.round(box.height)
|
|
6184
|
+
};
|
|
6185
|
+
}
|
|
6186
|
+
const threshold = snapThreshold || 5;
|
|
6187
|
+
const releaseDist = threshold + hysteresis;
|
|
6188
|
+
const matchDimensions = (options == null ? void 0 : options.matchDimensions) ?? true;
|
|
6189
|
+
const excludedIds = new Set((options == null ? void 0 : options.excludeObjectIds) ?? []);
|
|
6190
|
+
if (excludeObjectId) excludedIds.add(excludeObjectId);
|
|
6191
|
+
const right = box.left + box.width;
|
|
6192
|
+
const bottom = box.top + box.height;
|
|
6193
|
+
const canvasCenterX = canvasWidth / 2;
|
|
6194
|
+
const canvasCenterY = canvasHeight / 2;
|
|
6195
|
+
const resizingLeft = corner.includes("l");
|
|
6196
|
+
const resizingRight = corner.includes("r");
|
|
6197
|
+
const resizingTop = corner.includes("t");
|
|
6198
|
+
const resizingBottom = corner.includes("b");
|
|
6199
|
+
const verticalTargets = [0, canvasWidth, canvasCenterX];
|
|
6200
|
+
const horizontalTargets = [0, canvasHeight, canvasCenterY];
|
|
6201
|
+
const widthTargets = [];
|
|
6202
|
+
const heightTargets = [];
|
|
6203
|
+
if ((_a2 = options == null ? void 0 : options.verticalTargetsExtra) == null ? void 0 : _a2.length) verticalTargets.push(...options.verticalTargetsExtra);
|
|
6204
|
+
if ((_b2 = options == null ? void 0 : options.horizontalTargetsExtra) == null ? void 0 : _b2.length) horizontalTargets.push(...options.horizontalTargetsExtra);
|
|
6205
|
+
const rawObjects = canvas.getObjects();
|
|
6206
|
+
for (const obj of rawObjects) {
|
|
6207
|
+
const objId = getObjectId(obj);
|
|
6208
|
+
if (objId === "__background__") continue;
|
|
6209
|
+
if (objId && excludedIds.has(objId)) continue;
|
|
6210
|
+
const pts = getObjectSnapPoints(obj);
|
|
6211
|
+
verticalTargets.push(pts.left, pts.right, pts.centerX);
|
|
6212
|
+
horizontalTargets.push(pts.top, pts.bottom, pts.centerY);
|
|
6213
|
+
widthTargets.push(Math.max(1, pts.right - pts.left));
|
|
6214
|
+
heightTargets.push(Math.max(1, pts.bottom - pts.top));
|
|
6215
|
+
}
|
|
6216
|
+
for (const bounds of (options == null ? void 0 : options.additionalBounds) ?? []) {
|
|
6217
|
+
const pts = boundsToSnapPoints(bounds);
|
|
6218
|
+
verticalTargets.push(pts.left, pts.right, pts.centerX);
|
|
6219
|
+
horizontalTargets.push(pts.top, pts.bottom, pts.centerY);
|
|
6220
|
+
widthTargets.push(Math.max(1, bounds.width));
|
|
6221
|
+
heightTargets.push(Math.max(1, bounds.height));
|
|
6222
|
+
}
|
|
6223
|
+
const matchAsEdgeEnabled = (options == null ? void 0 : options.matchDimensions) ?? true;
|
|
6224
|
+
if (matchAsEdgeEnabled) {
|
|
6225
|
+
if (resizingLeft && !resizingRight) {
|
|
6226
|
+
for (const w of widthTargets) verticalTargets.push(right - w);
|
|
6227
|
+
} else if (resizingRight && !resizingLeft) {
|
|
6228
|
+
for (const w of widthTargets) verticalTargets.push(box.left + w);
|
|
6229
|
+
}
|
|
6230
|
+
if (resizingTop && !resizingBottom) {
|
|
6231
|
+
for (const h of heightTargets) horizontalTargets.push(bottom - h);
|
|
6232
|
+
} else if (resizingBottom && !resizingTop) {
|
|
6233
|
+
for (const h of heightTargets) horizontalTargets.push(box.top + h);
|
|
6234
|
+
}
|
|
6235
|
+
}
|
|
6236
|
+
const findBestSnap = (edgePos, targets) => {
|
|
6237
|
+
let best = edgePos;
|
|
6238
|
+
let bestDist = threshold + 1;
|
|
6239
|
+
for (const t of targets) {
|
|
6240
|
+
const d = Math.abs(edgePos - t);
|
|
6241
|
+
if (d < bestDist) {
|
|
6242
|
+
bestDist = d;
|
|
6243
|
+
best = t;
|
|
6244
|
+
}
|
|
6245
|
+
}
|
|
6246
|
+
return { value: best, dist: bestDist };
|
|
6247
|
+
};
|
|
6248
|
+
const findBestDimensionSnap = (size, targets) => {
|
|
6249
|
+
let best = size;
|
|
6250
|
+
let bestDist = threshold + 1;
|
|
6251
|
+
for (const t of targets) {
|
|
6252
|
+
const d = Math.abs(size - t);
|
|
6253
|
+
if (d < bestDist) {
|
|
6254
|
+
bestDist = d;
|
|
6255
|
+
best = t;
|
|
6256
|
+
}
|
|
6257
|
+
}
|
|
6258
|
+
return { value: best, dist: bestDist };
|
|
6259
|
+
};
|
|
6260
|
+
let left = box.left;
|
|
6261
|
+
let top = box.top;
|
|
6262
|
+
let width = box.width;
|
|
6263
|
+
let height = box.height;
|
|
6264
|
+
let snappedLeft = false;
|
|
6265
|
+
let snappedRight = false;
|
|
6266
|
+
let snappedTop = false;
|
|
6267
|
+
let snappedBottom = false;
|
|
6268
|
+
if (resizingLeft) {
|
|
6269
|
+
const stick = (_c = activeSnapRef == null ? void 0 : activeSnapRef.current) == null ? void 0 : _c.left;
|
|
6270
|
+
if (stick !== void 0) {
|
|
6271
|
+
const dist = Math.abs(box.left - stick);
|
|
6272
|
+
if (dist <= releaseDist) {
|
|
6273
|
+
left = stick;
|
|
6274
|
+
width = right - left;
|
|
6275
|
+
snappedLeft = true;
|
|
6276
|
+
} else if (dist > releaseDist) {
|
|
6277
|
+
if (activeSnapRef.current) delete activeSnapRef.current.left;
|
|
6278
|
+
const { value, dist: d } = findBestSnap(box.left, verticalTargets);
|
|
6279
|
+
if (d <= threshold) {
|
|
6280
|
+
if (!(activeSnapRef == null ? void 0 : activeSnapRef.current)) activeSnapRef.current = {};
|
|
6281
|
+
activeSnapRef.current.left = value;
|
|
6282
|
+
left = value;
|
|
6283
|
+
width = right - left;
|
|
6284
|
+
snappedLeft = true;
|
|
6285
|
+
} else {
|
|
6286
|
+
left = box.left;
|
|
6287
|
+
width = right - left;
|
|
6288
|
+
}
|
|
6289
|
+
} else {
|
|
6290
|
+
left = box.left;
|
|
6291
|
+
width = right - left;
|
|
6292
|
+
}
|
|
6293
|
+
} else {
|
|
6294
|
+
const { value, dist } = findBestSnap(box.left, verticalTargets);
|
|
6295
|
+
if (dist <= threshold) {
|
|
6296
|
+
if (activeSnapRef) {
|
|
6297
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6298
|
+
activeSnapRef.current.left = value;
|
|
6299
|
+
}
|
|
6300
|
+
left = value;
|
|
6301
|
+
width = right - left;
|
|
6302
|
+
snappedLeft = true;
|
|
6303
|
+
} else {
|
|
6304
|
+
left = box.left;
|
|
6305
|
+
width = right - left;
|
|
6306
|
+
}
|
|
6307
|
+
}
|
|
6308
|
+
}
|
|
6309
|
+
if (resizingRight) {
|
|
6310
|
+
const stick = (_d = activeSnapRef == null ? void 0 : activeSnapRef.current) == null ? void 0 : _d.right;
|
|
6311
|
+
if (stick !== void 0) {
|
|
6312
|
+
const dist = Math.abs(right - stick);
|
|
6313
|
+
if (dist <= releaseDist) {
|
|
6314
|
+
width = stick - left;
|
|
6315
|
+
snappedRight = true;
|
|
6316
|
+
} else if (dist > releaseDist) {
|
|
6317
|
+
if (activeSnapRef == null ? void 0 : activeSnapRef.current) delete activeSnapRef.current.right;
|
|
6318
|
+
const { value, dist: d } = findBestSnap(right, verticalTargets);
|
|
6319
|
+
if (d <= threshold) {
|
|
6320
|
+
if (!(activeSnapRef == null ? void 0 : activeSnapRef.current)) activeSnapRef.current = {};
|
|
6321
|
+
activeSnapRef.current.right = value;
|
|
6322
|
+
width = value - left;
|
|
6323
|
+
snappedRight = true;
|
|
6324
|
+
} else {
|
|
6325
|
+
width = box.width;
|
|
6326
|
+
}
|
|
6327
|
+
} else {
|
|
6328
|
+
width = box.width;
|
|
6329
|
+
}
|
|
6330
|
+
} else {
|
|
6331
|
+
const { value, dist } = findBestSnap(right, verticalTargets);
|
|
6332
|
+
if (dist <= threshold) {
|
|
6333
|
+
if (activeSnapRef) {
|
|
6334
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6335
|
+
activeSnapRef.current.right = value;
|
|
6336
|
+
}
|
|
6337
|
+
width = value - left;
|
|
6338
|
+
snappedRight = true;
|
|
6339
|
+
} else {
|
|
6340
|
+
width = box.width;
|
|
6341
|
+
}
|
|
6342
|
+
}
|
|
6343
|
+
}
|
|
6344
|
+
if (resizingTop) {
|
|
6345
|
+
const stick = (_e = activeSnapRef == null ? void 0 : activeSnapRef.current) == null ? void 0 : _e.top;
|
|
6346
|
+
if (stick !== void 0) {
|
|
6347
|
+
const dist = Math.abs(box.top - stick);
|
|
6348
|
+
if (dist <= releaseDist) {
|
|
6349
|
+
top = stick;
|
|
6350
|
+
height = bottom - top;
|
|
6351
|
+
snappedTop = true;
|
|
6352
|
+
} else if (dist > releaseDist) {
|
|
6353
|
+
if (activeSnapRef == null ? void 0 : activeSnapRef.current) delete activeSnapRef.current.top;
|
|
6354
|
+
const { value, dist: d } = findBestSnap(box.top, horizontalTargets);
|
|
6355
|
+
if (d <= threshold) {
|
|
6356
|
+
if (!(activeSnapRef == null ? void 0 : activeSnapRef.current)) activeSnapRef.current = {};
|
|
6357
|
+
activeSnapRef.current.top = value;
|
|
6358
|
+
top = value;
|
|
6359
|
+
height = bottom - top;
|
|
6360
|
+
snappedTop = true;
|
|
6361
|
+
} else {
|
|
6362
|
+
top = box.top;
|
|
6363
|
+
height = bottom - top;
|
|
6364
|
+
}
|
|
6365
|
+
} else {
|
|
6366
|
+
top = box.top;
|
|
6367
|
+
height = bottom - top;
|
|
6368
|
+
}
|
|
6369
|
+
} else {
|
|
6370
|
+
const { value, dist } = findBestSnap(box.top, horizontalTargets);
|
|
6371
|
+
if (dist <= threshold) {
|
|
6372
|
+
if (activeSnapRef) {
|
|
6373
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6374
|
+
activeSnapRef.current.top = value;
|
|
6375
|
+
}
|
|
6376
|
+
top = value;
|
|
6377
|
+
height = bottom - top;
|
|
6378
|
+
snappedTop = true;
|
|
6379
|
+
} else {
|
|
6380
|
+
top = box.top;
|
|
6381
|
+
height = bottom - top;
|
|
6382
|
+
}
|
|
6383
|
+
}
|
|
6384
|
+
}
|
|
6385
|
+
if (resizingBottom) {
|
|
6386
|
+
const stick = (_f = activeSnapRef == null ? void 0 : activeSnapRef.current) == null ? void 0 : _f.bottom;
|
|
6387
|
+
if (stick !== void 0) {
|
|
6388
|
+
const dist = Math.abs(bottom - stick);
|
|
6389
|
+
if (dist <= releaseDist) {
|
|
6390
|
+
height = stick - top;
|
|
6391
|
+
snappedBottom = true;
|
|
6392
|
+
} else if (dist > releaseDist) {
|
|
6393
|
+
if (activeSnapRef == null ? void 0 : activeSnapRef.current) delete activeSnapRef.current.bottom;
|
|
6394
|
+
const { value, dist: d } = findBestSnap(bottom, horizontalTargets);
|
|
6395
|
+
if (d <= threshold) {
|
|
6396
|
+
if (!(activeSnapRef == null ? void 0 : activeSnapRef.current)) activeSnapRef.current = {};
|
|
6397
|
+
activeSnapRef.current.bottom = value;
|
|
6398
|
+
height = value - top;
|
|
6399
|
+
snappedBottom = true;
|
|
6400
|
+
} else {
|
|
6401
|
+
height = box.height;
|
|
6402
|
+
}
|
|
6403
|
+
} else {
|
|
6404
|
+
height = box.height;
|
|
6405
|
+
}
|
|
6406
|
+
} else {
|
|
6407
|
+
const { value, dist } = findBestSnap(bottom, horizontalTargets);
|
|
6408
|
+
if (dist <= threshold) {
|
|
6409
|
+
if (activeSnapRef) {
|
|
6410
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6411
|
+
activeSnapRef.current.bottom = value;
|
|
6412
|
+
}
|
|
6413
|
+
height = value - top;
|
|
6414
|
+
snappedBottom = true;
|
|
6415
|
+
} else {
|
|
6416
|
+
height = box.height;
|
|
6417
|
+
}
|
|
6418
|
+
}
|
|
6419
|
+
}
|
|
6420
|
+
if (matchDimensions && resizingLeft !== resizingRight && !snappedLeft && !snappedRight && widthTargets.length > 0) {
|
|
6421
|
+
const stick = (_g = activeSnapRef == null ? void 0 : activeSnapRef.current) == null ? void 0 : _g.width;
|
|
6422
|
+
const applyWidth = (targetWidth) => {
|
|
6423
|
+
width = Math.max(MIN_SNAP_BOX, targetWidth);
|
|
6424
|
+
if (resizingLeft) {
|
|
6425
|
+
left = right - width;
|
|
6426
|
+
snappedLeft = true;
|
|
6427
|
+
} else {
|
|
6428
|
+
snappedRight = true;
|
|
6429
|
+
}
|
|
6430
|
+
};
|
|
6431
|
+
if (stick !== void 0) {
|
|
6432
|
+
const dist = Math.abs(box.width - stick);
|
|
6433
|
+
if (dist <= releaseDist) {
|
|
6434
|
+
applyWidth(stick);
|
|
6435
|
+
} else if (dist > releaseDist) {
|
|
6436
|
+
if (activeSnapRef == null ? void 0 : activeSnapRef.current) delete activeSnapRef.current.width;
|
|
6437
|
+
const { value, dist: d } = findBestDimensionSnap(box.width, widthTargets);
|
|
6438
|
+
if (d <= threshold) {
|
|
6439
|
+
if (activeSnapRef) {
|
|
6440
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6441
|
+
activeSnapRef.current.width = value;
|
|
6442
|
+
}
|
|
6443
|
+
applyWidth(value);
|
|
6444
|
+
}
|
|
6445
|
+
}
|
|
6446
|
+
} else {
|
|
6447
|
+
const { value, dist } = findBestDimensionSnap(box.width, widthTargets);
|
|
6448
|
+
if (dist <= threshold) {
|
|
6449
|
+
if (activeSnapRef) {
|
|
6450
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6451
|
+
activeSnapRef.current.width = value;
|
|
6452
|
+
}
|
|
6453
|
+
applyWidth(value);
|
|
6454
|
+
}
|
|
6455
|
+
}
|
|
6456
|
+
}
|
|
6457
|
+
if (matchDimensions && resizingTop !== resizingBottom && !snappedTop && !snappedBottom && heightTargets.length > 0) {
|
|
6458
|
+
const stick = (_h = activeSnapRef == null ? void 0 : activeSnapRef.current) == null ? void 0 : _h.height;
|
|
6459
|
+
const applyHeight = (targetHeight) => {
|
|
6460
|
+
height = Math.max(MIN_SNAP_BOX, targetHeight);
|
|
6461
|
+
if (resizingTop) {
|
|
6462
|
+
top = bottom - height;
|
|
6463
|
+
snappedTop = true;
|
|
6464
|
+
} else {
|
|
6465
|
+
snappedBottom = true;
|
|
6466
|
+
}
|
|
6467
|
+
};
|
|
6468
|
+
if (stick !== void 0) {
|
|
6469
|
+
const dist = Math.abs(box.height - stick);
|
|
6470
|
+
if (dist <= releaseDist) {
|
|
6471
|
+
applyHeight(stick);
|
|
6472
|
+
} else if (dist > releaseDist) {
|
|
6473
|
+
if (activeSnapRef == null ? void 0 : activeSnapRef.current) delete activeSnapRef.current.height;
|
|
6474
|
+
const { value, dist: d } = findBestDimensionSnap(box.height, heightTargets);
|
|
6475
|
+
if (d <= threshold) {
|
|
6476
|
+
if (activeSnapRef) {
|
|
6477
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6478
|
+
activeSnapRef.current.height = value;
|
|
6479
|
+
}
|
|
6480
|
+
applyHeight(value);
|
|
6481
|
+
}
|
|
6482
|
+
}
|
|
6483
|
+
} else {
|
|
6484
|
+
const { value, dist } = findBestDimensionSnap(box.height, heightTargets);
|
|
6485
|
+
if (dist <= threshold) {
|
|
6486
|
+
if (activeSnapRef) {
|
|
6487
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6488
|
+
activeSnapRef.current.height = value;
|
|
6489
|
+
}
|
|
6490
|
+
applyHeight(value);
|
|
6491
|
+
}
|
|
6492
|
+
}
|
|
6493
|
+
}
|
|
6494
|
+
width = Math.max(MIN_SNAP_BOX, width);
|
|
6495
|
+
height = Math.max(MIN_SNAP_BOX, height);
|
|
6496
|
+
if (resizingLeft && !resizingRight) left = right - width;
|
|
6497
|
+
if (resizingTop && !resizingBottom) top = bottom - height;
|
|
6498
|
+
if (roundSnappedOnly) {
|
|
6499
|
+
return {
|
|
6500
|
+
left: snappedLeft ? Math.round(left) : left,
|
|
6501
|
+
top: snappedTop ? Math.round(top) : top,
|
|
6502
|
+
width: snappedLeft || snappedRight ? Math.round(width) : width,
|
|
6503
|
+
height: snappedTop || snappedBottom ? Math.round(height) : height
|
|
6504
|
+
};
|
|
6505
|
+
}
|
|
6506
|
+
return {
|
|
6507
|
+
left: Math.round(left),
|
|
6508
|
+
top: Math.round(top),
|
|
6509
|
+
width: Math.round(width),
|
|
6510
|
+
height: Math.round(height)
|
|
6511
|
+
};
|
|
6512
|
+
}
|
|
5970
6513
|
const clamp01$1 = (v) => Math.max(0, Math.min(1, Number.isFinite(v) ? v : 0));
|
|
5971
6514
|
function arcPath(w, sag, up) {
|
|
5972
6515
|
if (sag <= 0.5) return `M 0 0 L ${w} 0`;
|
|
@@ -6137,12 +6680,87 @@ if (Array.isArray(stateProps)) {
|
|
|
6137
6680
|
if (!stateProps.includes("minBoxHeight")) stateProps.push("minBoxHeight");
|
|
6138
6681
|
if (!stateProps.includes("verticalAlign")) stateProps.push("verticalAlign");
|
|
6139
6682
|
if (!stateProps.includes("textPath")) stateProps.push("textPath");
|
|
6683
|
+
if (!stateProps.includes("smartWrap")) stateProps.push("smartWrap");
|
|
6140
6684
|
}
|
|
6141
6685
|
const cacheProps = fabric__namespace.Textbox.prototype.cacheProperties;
|
|
6142
6686
|
if (Array.isArray(cacheProps)) {
|
|
6143
6687
|
if (!cacheProps.includes("minBoxHeight")) cacheProps.push("minBoxHeight");
|
|
6144
6688
|
if (!cacheProps.includes("verticalAlign")) cacheProps.push("verticalAlign");
|
|
6145
6689
|
if (!cacheProps.includes("textPath")) cacheProps.push("textPath");
|
|
6690
|
+
if (!cacheProps.includes("smartWrap")) cacheProps.push("smartWrap");
|
|
6691
|
+
}
|
|
6692
|
+
fabric__namespace.Textbox.prototype.smartWrap = true;
|
|
6693
|
+
if (TextboxProto._wrapLine && !TextboxProto.__pixldocsOrigWrapLine) {
|
|
6694
|
+
TextboxProto.__pixldocsOrigWrapLine = TextboxProto._wrapLine;
|
|
6695
|
+
TextboxProto._wrapLine = function(lineIndex, desiredWidth, ref, reservedSpace = 0) {
|
|
6696
|
+
var _a2;
|
|
6697
|
+
const orig = TextboxProto.__pixldocsOrigWrapLine;
|
|
6698
|
+
if (!this.smartWrap || this.splitByGrapheme) {
|
|
6699
|
+
return orig.call(this, lineIndex, desiredWidth, ref, reservedSpace);
|
|
6700
|
+
}
|
|
6701
|
+
try {
|
|
6702
|
+
const additionalSpace = TextboxProto._getWidthOfCharSpacing.call(this);
|
|
6703
|
+
const data = ((_a2 = ref == null ? void 0 : ref.wordsData) == null ? void 0 : _a2[lineIndex]) ?? [];
|
|
6704
|
+
const effective = Math.max(1, desiredWidth - reservedSpace);
|
|
6705
|
+
const infix = " ";
|
|
6706
|
+
const measureWord = TextboxProto._measureWord;
|
|
6707
|
+
const infixWidth = measureWord.call(this, [infix], lineIndex, 0);
|
|
6708
|
+
const graphemeLines = [];
|
|
6709
|
+
let line = [];
|
|
6710
|
+
let lineWidth = 0;
|
|
6711
|
+
let lineJustStarted = true;
|
|
6712
|
+
let largestWordWidth = 0;
|
|
6713
|
+
let offset = 0;
|
|
6714
|
+
const pushLine = () => {
|
|
6715
|
+
graphemeLines.push(line);
|
|
6716
|
+
line = [];
|
|
6717
|
+
lineWidth = 0;
|
|
6718
|
+
lineJustStarted = true;
|
|
6719
|
+
};
|
|
6720
|
+
for (let i = 0; i < data.length; i++) {
|
|
6721
|
+
const { word, width: wordWidth } = data[i];
|
|
6722
|
+
if (wordWidth <= effective) {
|
|
6723
|
+
if (wordWidth > largestWordWidth) largestWordWidth = wordWidth;
|
|
6724
|
+
const projected = lineJustStarted ? wordWidth : lineWidth + infixWidth + wordWidth - additionalSpace;
|
|
6725
|
+
if (!lineJustStarted && projected > effective) {
|
|
6726
|
+
pushLine();
|
|
6727
|
+
}
|
|
6728
|
+
if (!lineJustStarted) {
|
|
6729
|
+
line.push(infix);
|
|
6730
|
+
lineWidth += infixWidth;
|
|
6731
|
+
}
|
|
6732
|
+
line = line.concat(word);
|
|
6733
|
+
lineWidth += wordWidth;
|
|
6734
|
+
lineJustStarted = false;
|
|
6735
|
+
} else {
|
|
6736
|
+
if (!lineJustStarted) pushLine();
|
|
6737
|
+
for (const g of word) {
|
|
6738
|
+
const gw = measureWord.call(this, [g], lineIndex, offset);
|
|
6739
|
+
if (gw > largestWordWidth) largestWordWidth = gw;
|
|
6740
|
+
const projected = lineJustStarted ? gw : lineWidth + gw - additionalSpace;
|
|
6741
|
+
if (!lineJustStarted && projected > effective) {
|
|
6742
|
+
pushLine();
|
|
6743
|
+
}
|
|
6744
|
+
line.push(g);
|
|
6745
|
+
lineWidth += gw;
|
|
6746
|
+
lineJustStarted = false;
|
|
6747
|
+
offset++;
|
|
6748
|
+
}
|
|
6749
|
+
offset -= word.length;
|
|
6750
|
+
}
|
|
6751
|
+
offset += word.length + 1;
|
|
6752
|
+
}
|
|
6753
|
+
if (line.length) graphemeLines.push(line);
|
|
6754
|
+
const minNeeded = Math.max(0, Math.min(largestWordWidth, effective) - additionalSpace + reservedSpace);
|
|
6755
|
+
if (minNeeded > this.dynamicMinWidth) {
|
|
6756
|
+
this.dynamicMinWidth = minNeeded;
|
|
6757
|
+
}
|
|
6758
|
+
return graphemeLines;
|
|
6759
|
+
} catch (e) {
|
|
6760
|
+
console.warn("[smartWrap] fell back to default wrap:", e);
|
|
6761
|
+
return orig.call(this, lineIndex, desiredWidth, ref, reservedSpace);
|
|
6762
|
+
}
|
|
6763
|
+
};
|
|
6146
6764
|
}
|
|
6147
6765
|
const hasActiveTextPath = (obj) => {
|
|
6148
6766
|
const tp = obj.textPath;
|
|
@@ -6299,14 +6917,14 @@ function scaleLocalToScreen(target, p) {
|
|
|
6299
6917
|
return new fabric__namespace.Point(p.x * sx * zx, p.y * sy * zy);
|
|
6300
6918
|
}
|
|
6301
6919
|
function applyTextPathControls(textbox) {
|
|
6302
|
-
var _a2,
|
|
6920
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
6303
6921
|
const obj = textbox;
|
|
6304
6922
|
if (!hasActiveTextPath(obj)) {
|
|
6305
6923
|
obj.__pdTextPathHovered = false;
|
|
6306
6924
|
if (obj.__pdTextPathControls) {
|
|
6307
6925
|
try {
|
|
6308
6926
|
const cu2 = fabric__namespace.controlsUtils;
|
|
6309
|
-
const defaults = ((_a2 = cu2 == null ? void 0 : cu2.createTextboxDefaultControls) == null ? void 0 : _a2.call(cu2)) ?? ((
|
|
6927
|
+
const defaults = ((_a2 = cu2 == null ? void 0 : cu2.createTextboxDefaultControls) == null ? void 0 : _a2.call(cu2)) ?? ((_b2 = cu2 == null ? void 0 : cu2.createObjectDefaultControls) == null ? void 0 : _b2.call(cu2));
|
|
6310
6928
|
if (defaults) obj.controls = defaults;
|
|
6311
6929
|
} catch {
|
|
6312
6930
|
}
|
|
@@ -6570,7 +7188,7 @@ function applyTextPathControls(textbox) {
|
|
|
6570
7188
|
actionName: "tpPivot",
|
|
6571
7189
|
positionHandler: (_d2, finalMatrix, fabricObject) => scaleLocalToScreen(fabricObject, getPivotLocalCentered(fabricObject)).transform(finalMatrix),
|
|
6572
7190
|
actionHandler: (_e2, transform, x, y) => {
|
|
6573
|
-
var _a3,
|
|
7191
|
+
var _a3, _b3;
|
|
6574
7192
|
const target = transform.target;
|
|
6575
7193
|
const state = transform.__pdCirclePivotDrag || (transform.__pdCirclePivotDrag = {
|
|
6576
7194
|
startMatrix: target.calcTransformMatrix(),
|
|
@@ -6587,7 +7205,7 @@ function applyTextPathControls(textbox) {
|
|
|
6587
7205
|
y: (state.startOffset.y || 0) + dy
|
|
6588
7206
|
};
|
|
6589
7207
|
target.setCoords();
|
|
6590
|
-
(
|
|
7208
|
+
(_b3 = target.canvas) == null ? void 0 : _b3.requestRenderAll();
|
|
6591
7209
|
return true;
|
|
6592
7210
|
},
|
|
6593
7211
|
render: renderPivot
|
|
@@ -6638,13 +7256,13 @@ function applyTextPathControls(textbox) {
|
|
|
6638
7256
|
}
|
|
6639
7257
|
if (!obj.__pdCirclePivotDblWired) {
|
|
6640
7258
|
obj.on("mousedblclick", () => {
|
|
6641
|
-
var _a3,
|
|
7259
|
+
var _a3, _b3;
|
|
6642
7260
|
if (((_a3 = obj.textPath) == null ? void 0 : _a3.preset) !== "circle") return;
|
|
6643
7261
|
if (obj.__corner !== "tpPivot") return;
|
|
6644
7262
|
if (!obj.textPath.pivot) return;
|
|
6645
7263
|
obj.textPath.pivot = { x: 0, y: 0 };
|
|
6646
7264
|
obj.setCoords();
|
|
6647
|
-
(
|
|
7265
|
+
(_b3 = obj.canvas) == null ? void 0 : _b3.requestRenderAll();
|
|
6648
7266
|
});
|
|
6649
7267
|
obj.__pdCirclePivotDblWired = true;
|
|
6650
7268
|
}
|
|
@@ -7012,10 +7630,10 @@ function textPathBoundsContainScenePoint(obj, point) {
|
|
|
7012
7630
|
}
|
|
7013
7631
|
}
|
|
7014
7632
|
function drawTextPathBounds(ctx, obj, bounds, hostCanvas) {
|
|
7015
|
-
var _a2,
|
|
7633
|
+
var _a2, _b2, _c;
|
|
7016
7634
|
const host = hostCanvas || obj.canvas || ((_a2 = obj.group) == null ? void 0 : _a2.canvas);
|
|
7017
7635
|
if (!host) return;
|
|
7018
|
-
const retina = ((
|
|
7636
|
+
const retina = ((_b2 = host.getRetinaScaling) == null ? void 0 : _b2.call(host)) || ((_c = obj.getCanvasRetinaScaling) == null ? void 0 : _c.call(obj)) || 1;
|
|
7019
7637
|
const matrix = fabric__namespace.util.multiplyTransformMatrices(host.viewportTransform || [1, 0, 0, 1, 0, 0], obj.calcTransformMatrix());
|
|
7020
7638
|
const corners = [
|
|
7021
7639
|
new fabric__namespace.Point(bounds.minX, bounds.minY),
|
|
@@ -7037,8 +7655,8 @@ function drawTextPathBounds(ctx, obj, bounds, hostCanvas) {
|
|
|
7037
7655
|
}
|
|
7038
7656
|
if (typeof TextboxProto._renderControls === "function" && !TextboxProto.__pixldocsOrigRenderControls) {
|
|
7039
7657
|
let drawWarpGuides = function(ctx) {
|
|
7040
|
-
var _a2,
|
|
7041
|
-
const hostCanvas = this.canvas || ((_a2 = this.group) == null ? void 0 : _a2.canvas) || ((_c = (
|
|
7658
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
7659
|
+
const hostCanvas = this.canvas || ((_a2 = this.group) == null ? void 0 : _a2.canvas) || ((_c = (_b2 = this.group) == null ? void 0 : _b2.group) == null ? void 0 : _c.canvas);
|
|
7042
7660
|
if (!hostCanvas) return;
|
|
7043
7661
|
const hoverBounds = getTextPathHitBounds(this);
|
|
7044
7662
|
const active = (_d = hostCanvas.getActiveObject) == null ? void 0 : _d.call(hostCanvas);
|
|
@@ -7461,12 +8079,12 @@ function buildRoundedRectPath2D(ctx, x, y, w, h, rTL, rTR, rBR, rBL) {
|
|
|
7461
8079
|
ctx.closePath();
|
|
7462
8080
|
}
|
|
7463
8081
|
function measureLineGlyphWidth(obj, lineIndex) {
|
|
7464
|
-
var _a2,
|
|
8082
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
7465
8083
|
try {
|
|
7466
8084
|
const rawLine = (_a2 = obj == null ? void 0 : obj._textLines) == null ? void 0 : _a2[lineIndex];
|
|
7467
8085
|
const lineText = Array.isArray(rawLine) ? rawLine.join("") : String(rawLine ?? "");
|
|
7468
8086
|
if (!lineText) return 0;
|
|
7469
|
-
const fontSize = Number(((
|
|
8087
|
+
const fontSize = Number(((_b2 = obj.getValueOfPropertyAt) == null ? void 0 : _b2.call(obj, lineIndex, 0, "fontSize")) ?? obj.fontSize ?? 0);
|
|
7470
8088
|
if (!fontSize) return 0;
|
|
7471
8089
|
const fontStyle = String(((_c = obj.getValueOfPropertyAt) == null ? void 0 : _c.call(obj, lineIndex, 0, "fontStyle")) ?? obj.fontStyle ?? "normal");
|
|
7472
8090
|
const fontWeight = String(((_d = obj.getValueOfPropertyAt) == null ? void 0 : _d.call(obj, lineIndex, 0, "fontWeight")) ?? obj.fontWeight ?? "400");
|
|
@@ -7735,7 +8353,7 @@ function applyTextBackground(obj, cfg) {
|
|
|
7735
8353
|
const originalToSVG = (_a2 = obj.toSVG) == null ? void 0 : _a2.bind(obj);
|
|
7736
8354
|
if (typeof originalToSVG === "function") {
|
|
7737
8355
|
obj.toSVG = function(reviver) {
|
|
7738
|
-
var _a3,
|
|
8356
|
+
var _a3, _b2;
|
|
7739
8357
|
let svg = originalToSVG(reviver);
|
|
7740
8358
|
const bg = this[PD_BG_KEY];
|
|
7741
8359
|
const shadow = this.shadow;
|
|
@@ -7784,7 +8402,7 @@ function applyTextBackground(obj, cfg) {
|
|
|
7784
8402
|
const bgOpacityAttr = bgOpacity < 1 ? ` fill-opacity="${bgOpacity}"` : "";
|
|
7785
8403
|
let bgGradDefs = "";
|
|
7786
8404
|
let bgFillAttr = escapeXmlAttr(bgFill);
|
|
7787
|
-
if (hasBg && (bg == null ? void 0 : bg.gradient) && ((
|
|
8405
|
+
if (hasBg && (bg == null ? void 0 : bg.gradient) && ((_b2 = bg.gradient.stops) == null ? void 0 : _b2.length) >= 2) {
|
|
7788
8406
|
const bounds = ribbonD ? computeRibbonBoundsFor(this, pT, pR, pB, pL) : unionBounds(rects);
|
|
7789
8407
|
const gid = `__pdBgGrad_${Math.random().toString(36).slice(2, 9)}`;
|
|
7790
8408
|
const def = buildSvgGradientDef(bg.gradient, gid, bounds.x, bounds.y, bounds.w, bounds.h);
|
|
@@ -8813,9 +9431,9 @@ function createShape(element) {
|
|
|
8813
9431
|
});
|
|
8814
9432
|
}
|
|
8815
9433
|
case "circle": {
|
|
8816
|
-
|
|
8817
|
-
|
|
8818
|
-
|
|
9434
|
+
return new fabric__namespace.Ellipse({
|
|
9435
|
+
rx: w / 2,
|
|
9436
|
+
ry: h / 2,
|
|
8819
9437
|
fill,
|
|
8820
9438
|
stroke,
|
|
8821
9439
|
strokeWidth,
|
|
@@ -8824,8 +9442,7 @@ function createShape(element) {
|
|
|
8824
9442
|
objectCaching: true,
|
|
8825
9443
|
strokeUniform: true,
|
|
8826
9444
|
strokeLineJoin: "round",
|
|
8827
|
-
strokeLineCap: "round"
|
|
8828
|
-
lockUniScaling: true
|
|
9445
|
+
strokeLineCap: "round"
|
|
8829
9446
|
});
|
|
8830
9447
|
}
|
|
8831
9448
|
case "triangle": {
|
|
@@ -8860,7 +9477,7 @@ function createShape(element) {
|
|
|
8860
9477
|
}
|
|
8861
9478
|
}
|
|
8862
9479
|
function createText(element) {
|
|
8863
|
-
var _a2,
|
|
9480
|
+
var _a2, _b2, _c, _d, _e;
|
|
8864
9481
|
const overflowPolicy = element.overflowPolicy || "grow-and-push";
|
|
8865
9482
|
let text = element.text || "Text";
|
|
8866
9483
|
let fontSize = element.fontSize || 16;
|
|
@@ -9061,7 +9678,7 @@ function createText(element) {
|
|
|
9061
9678
|
textbox.setCoords();
|
|
9062
9679
|
const widthAfterSet = textbox.width ?? 0;
|
|
9063
9680
|
try {
|
|
9064
|
-
(
|
|
9681
|
+
(_b2 = textbox.setControlsVisibility) == null ? void 0 : _b2.call(textbox, {
|
|
9065
9682
|
tl: true,
|
|
9066
9683
|
tr: true,
|
|
9067
9684
|
bl: true,
|
|
@@ -9860,34 +10477,595 @@ function bakeEdgeFade(source, fade) {
|
|
|
9860
10477
|
return canvas;
|
|
9861
10478
|
}
|
|
9862
10479
|
const SELECTION_PRIMARY = "hsl(217, 91%, 60%)";
|
|
10480
|
+
const SELECTION_BORDER_SCALE = 2;
|
|
10481
|
+
let ensureCanvaControlRenders = () => {
|
|
10482
|
+
};
|
|
9863
10483
|
try {
|
|
9864
10484
|
const InteractiveBase = fabric__namespace.InteractiveFabricObject ?? fabric__namespace.Object;
|
|
10485
|
+
if ((InteractiveBase == null ? void 0 : InteractiveBase.prototype) && !InteractiveBase.prototype.__pixldocsCenteredSelectionBorder) {
|
|
10486
|
+
InteractiveBase.prototype.__pixldocsCenteredSelectionBorder = true;
|
|
10487
|
+
InteractiveBase.prototype.strokeBorders = function(ctx, size) {
|
|
10488
|
+
const border = Number(this.borderScaleFactor ?? SELECTION_BORDER_SCALE) || SELECTION_BORDER_SCALE;
|
|
10489
|
+
const width = Math.max(0, ((size == null ? void 0 : size.x) ?? 0) - border);
|
|
10490
|
+
const height = Math.max(0, ((size == null ? void 0 : size.y) ?? 0) - border);
|
|
10491
|
+
ctx.strokeRect(-width / 2, -height / 2, width, height);
|
|
10492
|
+
};
|
|
10493
|
+
}
|
|
9865
10494
|
if (InteractiveBase == null ? void 0 : InteractiveBase.ownDefaults) {
|
|
9866
10495
|
Object.assign(InteractiveBase.ownDefaults, {
|
|
9867
10496
|
borderColor: SELECTION_PRIMARY,
|
|
9868
|
-
borderScaleFactor:
|
|
10497
|
+
borderScaleFactor: SELECTION_BORDER_SCALE,
|
|
9869
10498
|
cornerColor: SELECTION_PRIMARY,
|
|
9870
10499
|
cornerStrokeColor: "#ffffff",
|
|
9871
|
-
cornerStyle: "
|
|
10500
|
+
cornerStyle: "circle",
|
|
9872
10501
|
transparentCorners: false,
|
|
9873
|
-
cornerSize:
|
|
10502
|
+
cornerSize: 10,
|
|
9874
10503
|
borderOpacityWhenMoving: 0.9
|
|
9875
10504
|
});
|
|
9876
10505
|
} else if (InteractiveBase == null ? void 0 : InteractiveBase.prototype) {
|
|
9877
10506
|
Object.assign(InteractiveBase.prototype, {
|
|
9878
10507
|
borderColor: SELECTION_PRIMARY,
|
|
9879
|
-
borderScaleFactor:
|
|
10508
|
+
borderScaleFactor: SELECTION_BORDER_SCALE,
|
|
9880
10509
|
cornerColor: SELECTION_PRIMARY,
|
|
9881
10510
|
cornerStrokeColor: "#ffffff",
|
|
9882
|
-
cornerStyle: "
|
|
10511
|
+
cornerStyle: "circle",
|
|
9883
10512
|
transparentCorners: false,
|
|
9884
|
-
cornerSize:
|
|
10513
|
+
cornerSize: 10,
|
|
9885
10514
|
borderOpacityWhenMoving: 0.9
|
|
9886
10515
|
});
|
|
9887
10516
|
}
|
|
9888
10517
|
} catch (e) {
|
|
9889
10518
|
console.warn("[PageCanvas] Failed to apply global selection defaults:", e);
|
|
9890
10519
|
}
|
|
10520
|
+
try {
|
|
10521
|
+
const cu = fabric__namespace.controlsUtils;
|
|
10522
|
+
if (cu && typeof cu.createObjectDefaultControls === "function") {
|
|
10523
|
+
const PILL_LEN = 20;
|
|
10524
|
+
const PILL_THICK = 6;
|
|
10525
|
+
const PILL_RADIUS = 3;
|
|
10526
|
+
const CORNER_RADIUS = 6;
|
|
10527
|
+
const EDGE_HIT_PERP = 22;
|
|
10528
|
+
const EDGE_HIT_ALONG = 44;
|
|
10529
|
+
const HOVER_FILL = SELECTION_PRIMARY;
|
|
10530
|
+
const HOVER_STROKE = "#ffffff";
|
|
10531
|
+
const IDLE_FILL = "#ffffff";
|
|
10532
|
+
const IDLE_STROKE = "rgba(15, 23, 42, 0.18)";
|
|
10533
|
+
const isHovered = (fabricObject, controlKey) => fabricObject && fabricObject.__corner === controlKey;
|
|
10534
|
+
const getHoverProgress = (fabricObject, controlKey) => {
|
|
10535
|
+
const map = fabricObject == null ? void 0 : fabricObject.__handleHoverProgress;
|
|
10536
|
+
const p = map ? map[controlKey] : void 0;
|
|
10537
|
+
if (typeof p === "number") return Math.max(0, Math.min(1, p));
|
|
10538
|
+
return isHovered(fabricObject, controlKey) ? 1 : 0;
|
|
10539
|
+
};
|
|
10540
|
+
const HOVER_RGB = [59, 130, 246];
|
|
10541
|
+
const IDLE_RGB = [255, 255, 255];
|
|
10542
|
+
const lerpFill = (p) => {
|
|
10543
|
+
const r = Math.round(IDLE_RGB[0] + (HOVER_RGB[0] - IDLE_RGB[0]) * p);
|
|
10544
|
+
const g = Math.round(IDLE_RGB[1] + (HOVER_RGB[1] - IDLE_RGB[1]) * p);
|
|
10545
|
+
const b = Math.round(IDLE_RGB[2] + (HOVER_RGB[2] - IDLE_RGB[2]) * p);
|
|
10546
|
+
return `rgb(${r}, ${g}, ${b})`;
|
|
10547
|
+
};
|
|
10548
|
+
const getVisualScale = (_fabricObject) => {
|
|
10549
|
+
return 1;
|
|
10550
|
+
};
|
|
10551
|
+
const COLLAPSE_THRESHOLD_PX = 32;
|
|
10552
|
+
const shouldCollapseHandles = (fabricObject) => {
|
|
10553
|
+
var _a2, _b2, _c;
|
|
10554
|
+
try {
|
|
10555
|
+
const canvas = fabricObject == null ? void 0 : fabricObject.canvas;
|
|
10556
|
+
if (!canvas) return false;
|
|
10557
|
+
const zoom = ((_a2 = canvas.getZoom) == null ? void 0 : _a2.call(canvas)) ?? 1;
|
|
10558
|
+
const w = (((_b2 = fabricObject.getScaledWidth) == null ? void 0 : _b2.call(fabricObject)) ?? fabricObject.width ?? 0) * zoom;
|
|
10559
|
+
const h = (((_c = fabricObject.getScaledHeight) == null ? void 0 : _c.call(fabricObject)) ?? fabricObject.height ?? 0) * zoom;
|
|
10560
|
+
return Math.min(w, h) < COLLAPSE_THRESHOLD_PX;
|
|
10561
|
+
} catch {
|
|
10562
|
+
return false;
|
|
10563
|
+
}
|
|
10564
|
+
};
|
|
10565
|
+
const isVisibleControlWhenCollapsed = (controlKey) => controlKey === "tl" || controlKey === "mr" || controlKey === "mtr" || controlKey === "mvh";
|
|
10566
|
+
const wrapCollapseVisibility = (control, controlKey) => {
|
|
10567
|
+
if (!control || control.__pixldocsCollapseVisibilityWrapped) return;
|
|
10568
|
+
const originalGetVisibility = typeof control.getVisibility === "function" ? control.getVisibility.bind(control) : null;
|
|
10569
|
+
control.getVisibility = (fabricObject, key) => {
|
|
10570
|
+
const baseVisible = originalGetVisibility ? originalGetVisibility(fabricObject, key) : control.visible !== false;
|
|
10571
|
+
if (!baseVisible) return false;
|
|
10572
|
+
return !shouldCollapseHandles(fabricObject) || isVisibleControlWhenCollapsed(controlKey);
|
|
10573
|
+
};
|
|
10574
|
+
control.__pixldocsCollapseVisibilityWrapped = true;
|
|
10575
|
+
};
|
|
10576
|
+
const renderPill = (ctx, left, top, _styleOverride, fabricObject, orientation, controlKey) => {
|
|
10577
|
+
var _a2, _b2, _c;
|
|
10578
|
+
const action = (_b2 = (_a2 = fabricObject.canvas) == null ? void 0 : _a2._currentTransform) == null ? void 0 : _b2.action;
|
|
10579
|
+
if (action === "drag" && fabricObject.__pixldocsDragMoved) return;
|
|
10580
|
+
if (shouldCollapseHandles(fabricObject) && !isVisibleControlWhenCollapsed(controlKey)) return;
|
|
10581
|
+
const angle = ((_c = fabricObject.getTotalAngle) == null ? void 0 : _c.call(fabricObject)) ?? (fabricObject.angle ?? 0);
|
|
10582
|
+
const p = getHoverProgress(fabricObject, controlKey);
|
|
10583
|
+
const scale = getVisualScale(fabricObject);
|
|
10584
|
+
const pillLen = PILL_LEN * scale;
|
|
10585
|
+
const pillThick = PILL_THICK * scale;
|
|
10586
|
+
const w = orientation === "horizontal" ? pillLen : pillThick;
|
|
10587
|
+
const h = orientation === "horizontal" ? pillThick : pillLen;
|
|
10588
|
+
ctx.save();
|
|
10589
|
+
ctx.translate(left, top);
|
|
10590
|
+
ctx.rotate(angle * Math.PI / 180);
|
|
10591
|
+
ctx.beginPath();
|
|
10592
|
+
const x = -w / 2;
|
|
10593
|
+
const y = -h / 2;
|
|
10594
|
+
const r = Math.min(PILL_RADIUS * scale, Math.min(w, h) / 2);
|
|
10595
|
+
ctx.moveTo(x + r, y);
|
|
10596
|
+
ctx.lineTo(x + w - r, y);
|
|
10597
|
+
ctx.quadraticCurveTo(x + w, y, x + w, y + r);
|
|
10598
|
+
ctx.lineTo(x + w, y + h - r);
|
|
10599
|
+
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
|
|
10600
|
+
ctx.lineTo(x + r, y + h);
|
|
10601
|
+
ctx.quadraticCurveTo(x, y + h, x, y + h - r);
|
|
10602
|
+
ctx.lineTo(x, y + r);
|
|
10603
|
+
ctx.quadraticCurveTo(x, y, x + r, y);
|
|
10604
|
+
ctx.closePath();
|
|
10605
|
+
ctx.fillStyle = lerpFill(p);
|
|
10606
|
+
ctx.strokeStyle = `rgba(15, 23, 42, ${0.18 * (1 - p)})`;
|
|
10607
|
+
ctx.lineWidth = 0.75 * (1 - p);
|
|
10608
|
+
ctx.shadowColor = "rgba(15, 23, 42, 0.38)";
|
|
10609
|
+
ctx.shadowBlur = 8;
|
|
10610
|
+
ctx.shadowOffsetY = 2;
|
|
10611
|
+
ctx.fill();
|
|
10612
|
+
if (p < 1) ctx.stroke();
|
|
10613
|
+
ctx.restore();
|
|
10614
|
+
};
|
|
10615
|
+
const renderCornerDot = (ctx, left, top, _styleOverride, fabricObject, controlKey) => {
|
|
10616
|
+
var _a2, _b2;
|
|
10617
|
+
const action = (_b2 = (_a2 = fabricObject.canvas) == null ? void 0 : _a2._currentTransform) == null ? void 0 : _b2.action;
|
|
10618
|
+
if (action === "drag" && fabricObject.__pixldocsDragMoved) return;
|
|
10619
|
+
if (shouldCollapseHandles(fabricObject) && !isVisibleControlWhenCollapsed(controlKey)) return;
|
|
10620
|
+
const p = getHoverProgress(fabricObject, controlKey);
|
|
10621
|
+
const scale = getVisualScale(fabricObject);
|
|
10622
|
+
const r = CORNER_RADIUS * scale;
|
|
10623
|
+
ctx.save();
|
|
10624
|
+
ctx.beginPath();
|
|
10625
|
+
ctx.arc(left, top, r, 0, Math.PI * 2);
|
|
10626
|
+
ctx.closePath();
|
|
10627
|
+
ctx.fillStyle = lerpFill(p);
|
|
10628
|
+
ctx.strokeStyle = `rgba(15, 23, 42, ${0.18 * (1 - p)})`;
|
|
10629
|
+
ctx.lineWidth = 0.75 * (1 - p);
|
|
10630
|
+
ctx.shadowColor = "rgba(15, 23, 42, 0.38)";
|
|
10631
|
+
ctx.shadowBlur = 8;
|
|
10632
|
+
ctx.shadowOffsetY = 2;
|
|
10633
|
+
ctx.fill();
|
|
10634
|
+
if (p < 1) ctx.stroke();
|
|
10635
|
+
ctx.restore();
|
|
10636
|
+
};
|
|
10637
|
+
const installPillRenders = (controls) => {
|
|
10638
|
+
var _a2;
|
|
10639
|
+
const CUR_SIZE = 22;
|
|
10640
|
+
const HOT = Math.round(CUR_SIZE / 2);
|
|
10641
|
+
const makeCursor = (angleDeg) => {
|
|
10642
|
+
const svg = `<?xml version="1.0" encoding="UTF-8"?>
|
|
10643
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${CUR_SIZE}" height="${CUR_SIZE}" viewBox="0 0 22 22">
|
|
10644
|
+
<g transform="rotate(${angleDeg} 11 11)" fill="none" stroke="#000" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
|
|
10645
|
+
<path d="M2.5 11 L19.5 11" stroke="#fff" stroke-width="3.2"/>
|
|
10646
|
+
<path d="M5 8.5 L2.5 11 L5 13.5" stroke="#fff" stroke-width="3.2"/>
|
|
10647
|
+
<path d="M17 8.5 L19.5 11 L17 13.5" stroke="#fff" stroke-width="3.2"/>
|
|
10648
|
+
<path d="M2.5 11 L19.5 11"/>
|
|
10649
|
+
<path d="M5 8.5 L2.5 11 L5 13.5"/>
|
|
10650
|
+
<path d="M17 8.5 L19.5 11 L17 13.5"/>
|
|
10651
|
+
</g>
|
|
10652
|
+
</svg>`;
|
|
10653
|
+
const encoded = encodeURIComponent(svg).replace(/'/g, "%27").replace(/"/g, "%22");
|
|
10654
|
+
const fallback = angleDeg % 180 === 0 ? "ew-resize" : angleDeg % 180 === 90 ? "ns-resize" : angleDeg === 45 || angleDeg === 225 ? "nwse-resize" : "nesw-resize";
|
|
10655
|
+
return `url("data:image/svg+xml;utf8,${encoded}") ${HOT} ${HOT}, ${fallback}`;
|
|
10656
|
+
};
|
|
10657
|
+
const cursorFor = {
|
|
10658
|
+
ml: makeCursor(0),
|
|
10659
|
+
mr: makeCursor(0),
|
|
10660
|
+
mt: makeCursor(90),
|
|
10661
|
+
mb: makeCursor(90),
|
|
10662
|
+
tl: makeCursor(45),
|
|
10663
|
+
br: makeCursor(45),
|
|
10664
|
+
tr: makeCursor(135),
|
|
10665
|
+
bl: makeCursor(135)
|
|
10666
|
+
};
|
|
10667
|
+
const ROTATE_ICON_PATH = "M505.4 122.5l-92.2-62.7c-6.7-4.5-15.6-3.1-20.7 3.1l-69.2 87.4c-5.2 6.6-4.1 16.1 2.5 21.3s16.1 4.1 21.3-2.5l50.4-63.8c2.9 14.6 4.3 29.4 4.3 44.3 0 125.2-101.9 227-227 227-45.8 0-90.5-13.8-128.2-39.6l79-27.8c8-2.5 12.4-11 9.9-18.9s-11-12.4-18.9-9.9c-.3.1-.7.2-1 .4l-105.2 37c-2 .7-3.9 1.8-5.4 3.3-4.2 3.8-6 9.7-4.5 15.2l29.3 107.5c1.8 6.6 7.8 11.1 14.6 11.1 1.4 0 2.7-.2 4-.5 8.1-2.2 12.8-10.5 10.6-18.6l-18-66.4c40.3 24.6 86.6 37.5 133.8 37.5 68.3.2 133.8-27 181.9-75.4 48.4-48.1 75.5-113.7 75.4-181.9 0-14.3-1.2-28.6-3.5-42.8l59.8 40.7c7.1 4.4 16.4 2.2 20.8-4.9 4.1-6.6 2.5-15.4-3.8-20.1z";
|
|
10668
|
+
const CUR_R_SIZE = 18;
|
|
10669
|
+
const HOT_R = Math.round(CUR_R_SIZE / 2);
|
|
10670
|
+
const makeRotateCursor = (angleDeg) => {
|
|
10671
|
+
const a = ((angleDeg + 215) % 360 + 360) % 360;
|
|
10672
|
+
const halo = `<path d="${ROTATE_ICON_PATH}" fill="#fff" stroke="#fff" stroke-width="40" stroke-linejoin="round"/>`;
|
|
10673
|
+
const fg = `<path d="${ROTATE_ICON_PATH}" fill="#0f172a" stroke="#0f172a" stroke-width="6" stroke-linejoin="round"/>`;
|
|
10674
|
+
const svg = `<?xml version="1.0" encoding="UTF-8"?>
|
|
10675
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${CUR_R_SIZE}" height="${CUR_R_SIZE}" viewBox="0 0 512 512">
|
|
10676
|
+
<g transform="rotate(${a} 256 256)">${halo}${fg}</g>
|
|
10677
|
+
</svg>`;
|
|
10678
|
+
const encoded = encodeURIComponent(svg).replace(/'/g, "%27").replace(/"/g, "%22");
|
|
10679
|
+
return `url("data:image/svg+xml;utf8,${encoded}") ${HOT_R} ${HOT_R}, crosshair`;
|
|
10680
|
+
};
|
|
10681
|
+
const rotateCursorCache = {};
|
|
10682
|
+
const getRotateCursor = (fabricObject) => {
|
|
10683
|
+
let objAngle = 0;
|
|
10684
|
+
try {
|
|
10685
|
+
objAngle = typeof (fabricObject == null ? void 0 : fabricObject.getTotalAngle) === "function" ? fabricObject.getTotalAngle() : (fabricObject == null ? void 0 : fabricObject.angle) ?? 0;
|
|
10686
|
+
} catch {
|
|
10687
|
+
objAngle = 0;
|
|
10688
|
+
}
|
|
10689
|
+
let a = (objAngle % 360 + 360) % 360;
|
|
10690
|
+
a = Math.round(a / 15) * 15;
|
|
10691
|
+
if (a === 360) a = 0;
|
|
10692
|
+
if (!rotateCursorCache[a]) rotateCursorCache[a] = makeRotateCursor(a);
|
|
10693
|
+
return rotateCursorCache[a];
|
|
10694
|
+
};
|
|
10695
|
+
const MOVE_PATHS_2D = [
|
|
10696
|
+
new Path2D("M12 3L12.3648 2.65803L12 2.26894L11.6352 2.65803L12 3ZM11.5 9C11.5 9.27614 11.7239 9.5 12 9.5C12.2761 9.5 12.5 9.27614 12.5 9H11.5ZM15.3648 5.85803L12.3648 2.65803L11.6352 3.34197L14.6352 6.54197L15.3648 5.85803ZM11.6352 2.65803L8.63523 5.85803L9.36477 6.54197L12.3648 3.34197L11.6352 2.65803ZM11.5 3V9H12.5V3H11.5Z"),
|
|
10697
|
+
new Path2D("M21 12L21.342 12.3648L21.7311 12L21.342 11.6352L21 12ZM15 11.5C14.7239 11.5 14.5 11.7239 14.5 12C14.5 12.2761 14.7239 12.5 15 12.5L15 11.5ZM18.142 15.3648L21.342 12.3648L20.658 11.6352L17.458 14.6352L18.142 15.3648ZM21.342 11.6352L18.142 8.63523L17.458 9.36477L20.658 12.3648L21.342 11.6352ZM21 11.5L15 11.5L15 12.5L21 12.5L21 11.5Z"),
|
|
10698
|
+
new Path2D("M12 21L12.3648 21.342L12 21.7311L11.6352 21.342L12 21ZM11.5 15C11.5 14.7239 11.7239 14.5 12 14.5C12.2761 14.5 12.5 14.7239 12.5 15H11.5ZM15.3648 18.142L12.3648 21.342L11.6352 20.658L14.6352 17.458L15.3648 18.142ZM11.6352 21.342L8.63523 18.142L9.36477 17.458L12.3648 20.658L11.6352 21.342ZM11.5 21V15H12.5V21H11.5Z"),
|
|
10699
|
+
new Path2D("M3 12L2.65803 12.3648L2.26894 12L2.65803 11.6352L3 12ZM9 11.5C9.27614 11.5 9.5 11.7239 9.5 12C9.5 12.2761 9.27614 12.5 9 12.5L9 11.5ZM5.85803 15.3648L2.65803 12.3648L3.34197 11.6352L6.54197 14.6352L5.85803 15.3648ZM2.65803 11.6352L5.85803 8.63523L6.54197 9.36477L3.34197 12.3648L2.65803 11.6352ZM3 11.5L9 11.5L9 12.5L3 12.5L3 11.5Z")
|
|
10700
|
+
];
|
|
10701
|
+
const ROTATE_PATHS_2D = [
|
|
10702
|
+
new Path2D("M22 12l-3 3-3-3"),
|
|
10703
|
+
new Path2D("M2 12l3-3 3 3"),
|
|
10704
|
+
new Path2D("M19.016 14v-1.95A7.05 7.05 0 0 0 8 6.22"),
|
|
10705
|
+
new Path2D("M16.016 17.845A7.05 7.05 0 0 1 5 12.015V10"),
|
|
10706
|
+
new Path2D("M5 10V9"),
|
|
10707
|
+
new Path2D("M19 15v-1")
|
|
10708
|
+
];
|
|
10709
|
+
const baseAngleFor = {
|
|
10710
|
+
ml: 0,
|
|
10711
|
+
mr: 0,
|
|
10712
|
+
mt: 90,
|
|
10713
|
+
mb: 90,
|
|
10714
|
+
tl: 45,
|
|
10715
|
+
br: 45,
|
|
10716
|
+
tr: 135,
|
|
10717
|
+
bl: 135
|
|
10718
|
+
};
|
|
10719
|
+
const cursorCache = {};
|
|
10720
|
+
const getRotatedCursor = (key, fabricObject) => {
|
|
10721
|
+
const base = baseAngleFor[key];
|
|
10722
|
+
if (base === void 0) return cursorFor[key];
|
|
10723
|
+
let objAngle = 0;
|
|
10724
|
+
try {
|
|
10725
|
+
objAngle = typeof (fabricObject == null ? void 0 : fabricObject.getTotalAngle) === "function" ? fabricObject.getTotalAngle() : (fabricObject == null ? void 0 : fabricObject.angle) ?? 0;
|
|
10726
|
+
} catch {
|
|
10727
|
+
objAngle = 0;
|
|
10728
|
+
}
|
|
10729
|
+
let a = ((base + objAngle) % 180 + 180) % 180;
|
|
10730
|
+
a = Math.round(a / 15) * 15;
|
|
10731
|
+
if (a === 180) a = 0;
|
|
10732
|
+
if (!cursorCache[a]) cursorCache[a] = makeCursor(a);
|
|
10733
|
+
return cursorCache[a];
|
|
10734
|
+
};
|
|
10735
|
+
const sides = [
|
|
10736
|
+
["ml", "vertical"],
|
|
10737
|
+
["mr", "vertical"],
|
|
10738
|
+
["mt", "horizontal"],
|
|
10739
|
+
["mb", "horizontal"]
|
|
10740
|
+
];
|
|
10741
|
+
for (const [key, orient] of sides) {
|
|
10742
|
+
const c = controls[key];
|
|
10743
|
+
if (!c) continue;
|
|
10744
|
+
c.sizeX = orient === "horizontal" ? EDGE_HIT_ALONG : EDGE_HIT_PERP;
|
|
10745
|
+
c.sizeY = orient === "horizontal" ? EDGE_HIT_PERP : EDGE_HIT_ALONG;
|
|
10746
|
+
c.touchSizeX = c.sizeX;
|
|
10747
|
+
c.touchSizeY = c.sizeY;
|
|
10748
|
+
wrapCollapseVisibility(c, key);
|
|
10749
|
+
c.cursorStyle = cursorFor[key];
|
|
10750
|
+
c.cursorStyleHandler = (_eventData, _control, fabricObject) => getRotatedCursor(key, fabricObject);
|
|
10751
|
+
c.render = (ctx, left, top, styleOverride, fabricObject) => renderPill(ctx, left, top, styleOverride, fabricObject, orient, key);
|
|
10752
|
+
}
|
|
10753
|
+
const corners = ["tl", "tr", "bl", "br"];
|
|
10754
|
+
for (const key of corners) {
|
|
10755
|
+
const c = controls[key];
|
|
10756
|
+
if (!c) continue;
|
|
10757
|
+
c.sizeX = 16;
|
|
10758
|
+
c.sizeY = 16;
|
|
10759
|
+
c.touchSizeX = 24;
|
|
10760
|
+
c.touchSizeY = 24;
|
|
10761
|
+
wrapCollapseVisibility(c, key);
|
|
10762
|
+
c.cursorStyle = cursorFor[key];
|
|
10763
|
+
c.cursorStyleHandler = (_eventData, _control, fabricObject) => getRotatedCursor(key, fabricObject);
|
|
10764
|
+
c.render = (ctx, left, top, styleOverride, fabricObject) => renderCornerDot(ctx, left, top, styleOverride, fabricObject, key);
|
|
10765
|
+
}
|
|
10766
|
+
const mtr = controls.mtr;
|
|
10767
|
+
if (mtr) {
|
|
10768
|
+
mtr.sizeX = 22;
|
|
10769
|
+
mtr.sizeY = 22;
|
|
10770
|
+
mtr.touchSizeX = 32;
|
|
10771
|
+
mtr.touchSizeY = 32;
|
|
10772
|
+
wrapCollapseVisibility(mtr, "mtr");
|
|
10773
|
+
mtr.offsetY = -28;
|
|
10774
|
+
mtr.withConnection = false;
|
|
10775
|
+
mtr.x = 0;
|
|
10776
|
+
mtr.y = -0.5;
|
|
10777
|
+
mtr.cursorStyle = getRotateCursor(null);
|
|
10778
|
+
mtr.cursorStyleHandler = (_e, _c, fabricObject) => {
|
|
10779
|
+
const cursor = getRotateCursor(fabricObject);
|
|
10780
|
+
try {
|
|
10781
|
+
const canvas = fabricObject == null ? void 0 : fabricObject.canvas;
|
|
10782
|
+
if (canvas) canvas.__pixldocsGetRotateCursor = getRotateCursor;
|
|
10783
|
+
const upper = canvas == null ? void 0 : canvas.upperCanvasEl;
|
|
10784
|
+
if (upper) upper.style.cursor = cursor;
|
|
10785
|
+
} catch {
|
|
10786
|
+
}
|
|
10787
|
+
return cursor;
|
|
10788
|
+
};
|
|
10789
|
+
mtr.render = (ctx, left, top, _styleOverride, fabricObject) => {
|
|
10790
|
+
var _a3, _b2;
|
|
10791
|
+
const action = (_b2 = (_a3 = fabricObject.canvas) == null ? void 0 : _a3._currentTransform) == null ? void 0 : _b2.action;
|
|
10792
|
+
if (action === "drag" && fabricObject.__pixldocsDragMoved) return;
|
|
10793
|
+
const scale = getVisualScale(fabricObject);
|
|
10794
|
+
const p = getHoverProgress(fabricObject, "mtr");
|
|
10795
|
+
const r = 11 * scale;
|
|
10796
|
+
ctx.save();
|
|
10797
|
+
ctx.beginPath();
|
|
10798
|
+
ctx.arc(left, top, r, 0, Math.PI * 2);
|
|
10799
|
+
ctx.closePath();
|
|
10800
|
+
ctx.fillStyle = lerpFill(p);
|
|
10801
|
+
ctx.strokeStyle = `rgba(15, 23, 42, ${0.18 * (1 - p)})`;
|
|
10802
|
+
ctx.lineWidth = 0.75 * (1 - p);
|
|
10803
|
+
ctx.shadowColor = "rgba(15, 23, 42, 0.4)";
|
|
10804
|
+
ctx.shadowBlur = 10;
|
|
10805
|
+
ctx.shadowOffsetY = 2;
|
|
10806
|
+
ctx.fill();
|
|
10807
|
+
if (p < 1) ctx.stroke();
|
|
10808
|
+
ctx.shadowColor = "transparent";
|
|
10809
|
+
ctx.shadowBlur = 0;
|
|
10810
|
+
ctx.shadowOffsetY = 0;
|
|
10811
|
+
const iconColor = p > 0.5 ? "#ffffff" : "rgba(15, 23, 42, 0.85)";
|
|
10812
|
+
ctx.strokeStyle = iconColor;
|
|
10813
|
+
ctx.fillStyle = iconColor;
|
|
10814
|
+
ctx.lineJoin = "miter";
|
|
10815
|
+
ctx.miterLimit = 4;
|
|
10816
|
+
{
|
|
10817
|
+
const target = r * 1.55;
|
|
10818
|
+
const s = target / 24;
|
|
10819
|
+
ctx.translate(left, top);
|
|
10820
|
+
ctx.scale(s, s);
|
|
10821
|
+
ctx.translate(-12, -12);
|
|
10822
|
+
ctx.strokeStyle = iconColor;
|
|
10823
|
+
ctx.lineWidth = 1 / s;
|
|
10824
|
+
ROTATE_PATHS_2D.forEach((p2d, index) => {
|
|
10825
|
+
ctx.lineCap = index >= 4 ? "round" : "square";
|
|
10826
|
+
ctx.stroke(p2d);
|
|
10827
|
+
});
|
|
10828
|
+
}
|
|
10829
|
+
ctx.restore();
|
|
10830
|
+
};
|
|
10831
|
+
}
|
|
10832
|
+
const moveActionHandler = (eventData, transform, x, y) => {
|
|
10833
|
+
const target = transform.target;
|
|
10834
|
+
if (!target) return false;
|
|
10835
|
+
if (!transform.__pixldocsMoveStart) {
|
|
10836
|
+
transform.__pixldocsMoveStart = {
|
|
10837
|
+
x,
|
|
10838
|
+
y,
|
|
10839
|
+
left: target.left ?? 0,
|
|
10840
|
+
top: target.top ?? 0
|
|
10841
|
+
};
|
|
10842
|
+
}
|
|
10843
|
+
const s = transform.__pixldocsMoveStart;
|
|
10844
|
+
target.set({ left: s.left + (x - s.x), top: s.top + (y - s.y) });
|
|
10845
|
+
target.setCoords();
|
|
10846
|
+
try {
|
|
10847
|
+
const canvas = target.canvas;
|
|
10848
|
+
if (canvas) {
|
|
10849
|
+
canvas.fire("object:moving", { target, e: eventData == null ? void 0 : eventData.e, transform, pointer: { x, y } });
|
|
10850
|
+
target.fire("moving", { e: eventData == null ? void 0 : eventData.e, transform, pointer: { x, y } });
|
|
10851
|
+
}
|
|
10852
|
+
} catch {
|
|
10853
|
+
}
|
|
10854
|
+
return true;
|
|
10855
|
+
};
|
|
10856
|
+
const renderMoveHandle = (ctx, left, top, _styleOverride, fabricObject) => {
|
|
10857
|
+
var _a3, _b2;
|
|
10858
|
+
if (!shouldCollapseHandles(fabricObject)) return;
|
|
10859
|
+
const action = (_b2 = (_a3 = fabricObject.canvas) == null ? void 0 : _a3._currentTransform) == null ? void 0 : _b2.action;
|
|
10860
|
+
if (action === "drag" && fabricObject.__pixldocsDragMoved) return;
|
|
10861
|
+
const scale = getVisualScale(fabricObject);
|
|
10862
|
+
const p = getHoverProgress(fabricObject, "mvh");
|
|
10863
|
+
const r = 11 * scale;
|
|
10864
|
+
ctx.save();
|
|
10865
|
+
ctx.beginPath();
|
|
10866
|
+
ctx.arc(left, top, r, 0, Math.PI * 2);
|
|
10867
|
+
ctx.closePath();
|
|
10868
|
+
ctx.fillStyle = lerpFill(p);
|
|
10869
|
+
ctx.strokeStyle = `rgba(15, 23, 42, ${0.18 * (1 - p)})`;
|
|
10870
|
+
ctx.lineWidth = 0.75 * (1 - p);
|
|
10871
|
+
ctx.shadowColor = "rgba(15, 23, 42, 0.4)";
|
|
10872
|
+
ctx.shadowBlur = 10;
|
|
10873
|
+
ctx.shadowOffsetY = 2;
|
|
10874
|
+
ctx.fill();
|
|
10875
|
+
if (p < 1) ctx.stroke();
|
|
10876
|
+
ctx.shadowColor = "transparent";
|
|
10877
|
+
ctx.shadowBlur = 0;
|
|
10878
|
+
ctx.shadowOffsetY = 0;
|
|
10879
|
+
const iconColor = p > 0.5 ? "#ffffff" : "rgba(15, 23, 42, 0.85)";
|
|
10880
|
+
ctx.fillStyle = iconColor;
|
|
10881
|
+
const target = r * 1.5;
|
|
10882
|
+
const s = target / 24;
|
|
10883
|
+
ctx.translate(left, top);
|
|
10884
|
+
ctx.scale(s, s);
|
|
10885
|
+
ctx.translate(-12, -12);
|
|
10886
|
+
for (const p2d of MOVE_PATHS_2D) ctx.fill(p2d);
|
|
10887
|
+
ctx.restore();
|
|
10888
|
+
};
|
|
10889
|
+
if (!controls.mvh) {
|
|
10890
|
+
const mvh = new fabric__namespace.Control({
|
|
10891
|
+
x: 0,
|
|
10892
|
+
y: 0.5,
|
|
10893
|
+
offsetY: 28,
|
|
10894
|
+
sizeX: 22,
|
|
10895
|
+
sizeY: 22,
|
|
10896
|
+
touchSizeX: 32,
|
|
10897
|
+
touchSizeY: 32,
|
|
10898
|
+
cursorStyle: "move",
|
|
10899
|
+
actionName: "drag",
|
|
10900
|
+
actionHandler: moveActionHandler,
|
|
10901
|
+
render: renderMoveHandle
|
|
10902
|
+
});
|
|
10903
|
+
mvh.withConnection = false;
|
|
10904
|
+
controls.mvh = mvh;
|
|
10905
|
+
} else {
|
|
10906
|
+
controls.mvh.render = renderMoveHandle;
|
|
10907
|
+
controls.mvh.actionHandler = moveActionHandler;
|
|
10908
|
+
controls.mvh.cursorStyle = "move";
|
|
10909
|
+
}
|
|
10910
|
+
wrapCollapseVisibility(controls.mvh, "mvh");
|
|
10911
|
+
const baseGetVisibility = (_a2 = controls.mvh.getVisibility) == null ? void 0 : _a2.bind(controls.mvh);
|
|
10912
|
+
if (baseGetVisibility && !controls.mvh.__pixldocsMvhVisibilityWrapped) {
|
|
10913
|
+
controls.mvh.getVisibility = (fabricObject, key) => {
|
|
10914
|
+
if (!shouldCollapseHandles(fabricObject)) return false;
|
|
10915
|
+
return baseGetVisibility(fabricObject, key);
|
|
10916
|
+
};
|
|
10917
|
+
controls.mvh.__pixldocsMvhVisibilityWrapped = true;
|
|
10918
|
+
}
|
|
10919
|
+
return controls;
|
|
10920
|
+
};
|
|
10921
|
+
ensureCanvaControlRenders = (obj) => {
|
|
10922
|
+
try {
|
|
10923
|
+
if (obj && obj.controls) installPillRenders(obj.controls);
|
|
10924
|
+
if (obj && Array.isArray(obj._objects)) {
|
|
10925
|
+
for (const child of obj._objects) {
|
|
10926
|
+
if (child && child.controls) installPillRenders(child.controls);
|
|
10927
|
+
}
|
|
10928
|
+
}
|
|
10929
|
+
} catch (e) {
|
|
10930
|
+
}
|
|
10931
|
+
};
|
|
10932
|
+
const origObj = cu.createObjectDefaultControls.bind(cu);
|
|
10933
|
+
cu.createObjectDefaultControls = () => installPillRenders(origObj());
|
|
10934
|
+
if (typeof cu.createTextboxDefaultControls === "function") {
|
|
10935
|
+
const origTb = cu.createTextboxDefaultControls.bind(cu);
|
|
10936
|
+
cu.createTextboxDefaultControls = () => installPillRenders(origTb());
|
|
10937
|
+
}
|
|
10938
|
+
const wrapClassCreateControls = (Klass) => {
|
|
10939
|
+
if (!Klass || typeof Klass.createControls !== "function") return;
|
|
10940
|
+
const orig = Klass.createControls.bind(Klass);
|
|
10941
|
+
Klass.createControls = () => {
|
|
10942
|
+
const res = orig();
|
|
10943
|
+
if (res && res.controls) installPillRenders(res.controls);
|
|
10944
|
+
return res;
|
|
10945
|
+
};
|
|
10946
|
+
};
|
|
10947
|
+
wrapClassCreateControls(fabric__namespace.InteractiveFabricObject);
|
|
10948
|
+
wrapClassCreateControls(fabric__namespace.FabricObject);
|
|
10949
|
+
wrapClassCreateControls(fabric__namespace.Textbox);
|
|
10950
|
+
wrapClassCreateControls(fabric__namespace.IText);
|
|
10951
|
+
const CanvasProto = (_b = fabric__namespace.Canvas) == null ? void 0 : _b.prototype;
|
|
10952
|
+
if (CanvasProto && typeof CanvasProto._setCursorFromEvent === "function") {
|
|
10953
|
+
const origSet = CanvasProto._setCursorFromEvent;
|
|
10954
|
+
CanvasProto._setCursorFromEvent = function(e, target) {
|
|
10955
|
+
const prev = target && target.__corner;
|
|
10956
|
+
const res = origSet.call(this, e, target);
|
|
10957
|
+
const next = target && target.__corner;
|
|
10958
|
+
if (prev !== next) {
|
|
10959
|
+
try {
|
|
10960
|
+
this.requestRenderAll();
|
|
10961
|
+
} catch {
|
|
10962
|
+
}
|
|
10963
|
+
}
|
|
10964
|
+
return res;
|
|
10965
|
+
};
|
|
10966
|
+
}
|
|
10967
|
+
}
|
|
10968
|
+
} catch (e) {
|
|
10969
|
+
console.warn("[PageCanvas] Failed to install Canva-style control handles:", e);
|
|
10970
|
+
}
|
|
10971
|
+
const scaleTextPathConfig = (textPath, sx, sy, uniform) => {
|
|
10972
|
+
if (!textPath || typeof textPath !== "object") return textPath;
|
|
10973
|
+
const next = JSON.parse(JSON.stringify(textPath));
|
|
10974
|
+
if (typeof next.radius === "number") next.radius *= uniform;
|
|
10975
|
+
if (next.bbox) {
|
|
10976
|
+
if (typeof next.bbox.width === "number") next.bbox.width *= sx;
|
|
10977
|
+
if (typeof next.bbox.height === "number") next.bbox.height *= sy;
|
|
10978
|
+
}
|
|
10979
|
+
if (next.endpoints) {
|
|
10980
|
+
if (typeof next.endpoints.leftY === "number") next.endpoints.leftY *= sy;
|
|
10981
|
+
if (typeof next.endpoints.rightY === "number") next.endpoints.rightY *= sy;
|
|
10982
|
+
if (typeof next.endpoints.centerY === "number") next.endpoints.centerY *= sy;
|
|
10983
|
+
}
|
|
10984
|
+
if (next.pivot) {
|
|
10985
|
+
if (typeof next.pivot.x === "number") next.pivot.x *= sx;
|
|
10986
|
+
if (typeof next.pivot.y === "number") next.pivot.y *= sy;
|
|
10987
|
+
}
|
|
10988
|
+
if (next.bezier) {
|
|
10989
|
+
["p0", "c0", "c1", "p1"].forEach((key) => {
|
|
10990
|
+
if (Array.isArray(next.bezier[key])) {
|
|
10991
|
+
next.bezier[key][0] *= sx;
|
|
10992
|
+
next.bezier[key][1] *= sy;
|
|
10993
|
+
}
|
|
10994
|
+
});
|
|
10995
|
+
}
|
|
10996
|
+
return next;
|
|
10997
|
+
};
|
|
10998
|
+
const scaleUpdateNumber = (updates, source, key, factor) => {
|
|
10999
|
+
const value = Number(source == null ? void 0 : source[key]);
|
|
11000
|
+
if (Number.isFinite(value)) updates[key] = value * factor;
|
|
11001
|
+
};
|
|
11002
|
+
const bakeTextboxScaleIntoTypography = (obj, sourceElement) => {
|
|
11003
|
+
const sx = Math.abs(obj.scaleX ?? 1) || 1;
|
|
11004
|
+
const sy = Math.abs(obj.scaleY ?? 1) || 1;
|
|
11005
|
+
if (Math.abs(sx - 1) < 1e-3 && Math.abs(sy - 1) < 1e-3) return null;
|
|
11006
|
+
const isUniform = Math.abs(sx - sy) < 0.01;
|
|
11007
|
+
const fontScale = isUniform ? (sx + sy) / 2 : Math.abs(sy - 1) > 1e-3 ? sy : 1;
|
|
11008
|
+
const effectScale = isUniform ? fontScale : Math.max(1e-3, Math.sqrt(sx * sy));
|
|
11009
|
+
const updates = {
|
|
11010
|
+
width: Math.max(20, (obj.width ?? (sourceElement == null ? void 0 : sourceElement.width) ?? 20) * sx),
|
|
11011
|
+
scaleX: 1,
|
|
11012
|
+
scaleY: 1
|
|
11013
|
+
};
|
|
11014
|
+
if (fontScale !== 1) {
|
|
11015
|
+
updates.fontSize = Math.max(1, Number(obj.fontSize || (sourceElement == null ? void 0 : sourceElement.fontSize) || 16) * fontScale);
|
|
11016
|
+
const minBoxHeight = Number(obj.minBoxHeight ?? (sourceElement == null ? void 0 : sourceElement.minBoxHeight));
|
|
11017
|
+
if (Number.isFinite(minBoxHeight) && minBoxHeight > 0) updates.minBoxHeight = minBoxHeight * sy;
|
|
11018
|
+
}
|
|
11019
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "strokeWidth", effectScale);
|
|
11020
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textShadowBlur", effectScale);
|
|
11021
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textShadowDistance", effectScale);
|
|
11022
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textShadowOffsetX", sx);
|
|
11023
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textShadowOffsetY", sy);
|
|
11024
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgPaddingTop", sy);
|
|
11025
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgPaddingBottom", sy);
|
|
11026
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgPaddingLeft", sx);
|
|
11027
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgPaddingRight", sx);
|
|
11028
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgPadding", effectScale);
|
|
11029
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgRxTL", effectScale);
|
|
11030
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgRxTR", effectScale);
|
|
11031
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgRxBR", effectScale);
|
|
11032
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgRxBL", effectScale);
|
|
11033
|
+
const textPath = obj.textPath ?? (sourceElement == null ? void 0 : sourceElement.textPath);
|
|
11034
|
+
if (textPath) updates.textPath = scaleTextPathConfig(textPath, sx, sy, effectScale);
|
|
11035
|
+
const center = obj.getCenterPoint();
|
|
11036
|
+
obj.set({
|
|
11037
|
+
width: updates.width,
|
|
11038
|
+
scaleX: 1,
|
|
11039
|
+
scaleY: 1,
|
|
11040
|
+
...updates.fontSize ? { fontSize: updates.fontSize } : {},
|
|
11041
|
+
...updates.strokeWidth !== void 0 ? { strokeWidth: updates.strokeWidth } : {}
|
|
11042
|
+
});
|
|
11043
|
+
if (updates.minBoxHeight !== void 0) obj.minBoxHeight = updates.minBoxHeight;
|
|
11044
|
+
if (updates.textPath) obj.textPath = updates.textPath;
|
|
11045
|
+
const shadow = obj.shadow;
|
|
11046
|
+
if (shadow) {
|
|
11047
|
+
shadow.blur = updates.textShadowBlur ?? shadow.blur;
|
|
11048
|
+
shadow.offsetX = updates.textShadowOffsetX ?? shadow.offsetX;
|
|
11049
|
+
shadow.offsetY = updates.textShadowOffsetY ?? shadow.offsetY;
|
|
11050
|
+
}
|
|
11051
|
+
if ((sourceElement == null ? void 0 : sourceElement.type) === "text") {
|
|
11052
|
+
const bakedElement = { ...sourceElement, ...updates };
|
|
11053
|
+
applyTextBackground(obj, extractTextBgConfig(bakedElement));
|
|
11054
|
+
applyTextShadow(obj, bakedElement);
|
|
11055
|
+
}
|
|
11056
|
+
try {
|
|
11057
|
+
obj.initDimensions();
|
|
11058
|
+
} catch {
|
|
11059
|
+
}
|
|
11060
|
+
obj.setPositionByOrigin(center, "center", "center");
|
|
11061
|
+
obj.setCoords();
|
|
11062
|
+
obj.dirty = true;
|
|
11063
|
+
obj.__pixldocsBakedTextScaleUpdates = {
|
|
11064
|
+
...obj.__pixldocsBakedTextScaleUpdates || {},
|
|
11065
|
+
...updates
|
|
11066
|
+
};
|
|
11067
|
+
return updates;
|
|
11068
|
+
};
|
|
9891
11069
|
function applyWarpAwareSelectionBorders(selection) {
|
|
9892
11070
|
if (selection.__pixldocsOrigASHasBorders !== void 0) {
|
|
9893
11071
|
selection.hasBorders = selection.__pixldocsOrigASHasBorders;
|
|
@@ -9955,8 +11133,11 @@ const PageCanvas = react.forwardRef(
|
|
|
9955
11133
|
const hasRunPostReadyReflowForPageRef = react.useRef(null);
|
|
9956
11134
|
const hasNotifiedReadyForPageRef = react.useRef(null);
|
|
9957
11135
|
const hasClearedCachesBeforeFirstSyncRef = react.useRef(false);
|
|
11136
|
+
const projectSettingsRef = react.useRef(projectSettings);
|
|
11137
|
+
projectSettingsRef.current = projectSettings;
|
|
9958
11138
|
const [guides, setGuides] = react.useState([]);
|
|
9959
11139
|
const [gridResizeLabel, setGridResizeLabel] = react.useState(null);
|
|
11140
|
+
const [hoverBounds, setHoverBounds] = react.useState(null);
|
|
9960
11141
|
const [rotationLabel, setRotationLabel] = react.useState(null);
|
|
9961
11142
|
const [sizeLabel, setSizeLabel] = react.useState(null);
|
|
9962
11143
|
const [ready, setReady] = react.useState(false);
|
|
@@ -10023,7 +11204,8 @@ const PageCanvas = react.forwardRef(
|
|
|
10023
11204
|
react.useRef(null);
|
|
10024
11205
|
react.useRef(null);
|
|
10025
11206
|
react.useRef(/* @__PURE__ */ new Map());
|
|
10026
|
-
react.useRef(null);
|
|
11207
|
+
const groupResizeActiveSnapRef = react.useRef(null);
|
|
11208
|
+
const objectResizeActiveSnapRef = react.useRef(null);
|
|
10027
11209
|
react.useRef(null);
|
|
10028
11210
|
react.useRef(null);
|
|
10029
11211
|
react.useRef(null);
|
|
@@ -10165,33 +11347,358 @@ const PageCanvas = react.forwardRef(
|
|
|
10165
11347
|
(movingObj) => {
|
|
10166
11348
|
const fabricCanvas = fabricRef.current;
|
|
10167
11349
|
if (!fabricCanvas) return { guides: [], snapDx: 0, snapDy: 0 };
|
|
11350
|
+
const ps = projectSettingsRef.current;
|
|
10168
11351
|
return calculateSnapGuides(
|
|
10169
11352
|
movingObj,
|
|
10170
11353
|
fabricCanvas,
|
|
10171
11354
|
canvasWidth,
|
|
10172
11355
|
canvasHeight,
|
|
10173
|
-
|
|
10174
|
-
|
|
11356
|
+
ps.snapToGuides,
|
|
11357
|
+
ps.snapThreshold
|
|
10175
11358
|
);
|
|
10176
11359
|
},
|
|
10177
|
-
[canvasWidth, canvasHeight
|
|
11360
|
+
[canvasWidth, canvasHeight]
|
|
10178
11361
|
);
|
|
11362
|
+
const getResizeExcludeIdsCallback = react.useCallback((obj) => {
|
|
11363
|
+
const ids = /* @__PURE__ */ new Set();
|
|
11364
|
+
const ownId = getObjectId(obj);
|
|
11365
|
+
if (ownId) ids.add(ownId);
|
|
11366
|
+
if (obj instanceof fabric__namespace.ActiveSelection) {
|
|
11367
|
+
obj.getObjects().forEach((member) => {
|
|
11368
|
+
const id = getObjectId(member);
|
|
11369
|
+
if (id) ids.add(id);
|
|
11370
|
+
});
|
|
11371
|
+
} else if (obj instanceof fabric__namespace.Group && typeof obj.getObjects === "function") {
|
|
11372
|
+
obj.getObjects().forEach((member) => {
|
|
11373
|
+
const id = getObjectId(member);
|
|
11374
|
+
if (id) ids.add(id);
|
|
11375
|
+
});
|
|
11376
|
+
}
|
|
11377
|
+
return ids;
|
|
11378
|
+
}, []);
|
|
11379
|
+
const getLogicalGroupSnapBoundsCallback = react.useCallback((excludeIds = []) => {
|
|
11380
|
+
const fabricCanvas = fabricRef.current;
|
|
11381
|
+
if (!fabricCanvas) return [];
|
|
11382
|
+
const excluded = new Set(excludeIds);
|
|
11383
|
+
const page = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
11384
|
+
const children = (page == null ? void 0 : page.children) ?? pageChildren ?? [];
|
|
11385
|
+
const objectBounds = /* @__PURE__ */ new Map();
|
|
11386
|
+
for (const object of fabricCanvas.getObjects()) {
|
|
11387
|
+
const id = getObjectId(object);
|
|
11388
|
+
if (!id || id === "__background__") continue;
|
|
11389
|
+
try {
|
|
11390
|
+
object.setCoords();
|
|
11391
|
+
} catch {
|
|
11392
|
+
}
|
|
11393
|
+
const bounds2 = object.getBoundingRect();
|
|
11394
|
+
objectBounds.set(id, { left: bounds2.left, top: bounds2.top, width: bounds2.width, height: bounds2.height });
|
|
11395
|
+
}
|
|
11396
|
+
const bounds = [];
|
|
11397
|
+
const visit = (nodes) => {
|
|
11398
|
+
for (const node of nodes) {
|
|
11399
|
+
if (!isGroup(node)) continue;
|
|
11400
|
+
const memberIds = getAllElementIds(node.children ?? []);
|
|
11401
|
+
if (memberIds.length === 0) continue;
|
|
11402
|
+
if (memberIds.some((id) => excluded.has(id)) || excluded.has(node.id)) {
|
|
11403
|
+
visit(node.children ?? []);
|
|
11404
|
+
continue;
|
|
11405
|
+
}
|
|
11406
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
11407
|
+
for (const memberId of memberIds) {
|
|
11408
|
+
const b = objectBounds.get(memberId);
|
|
11409
|
+
if (!b) continue;
|
|
11410
|
+
minX = Math.min(minX, b.left);
|
|
11411
|
+
minY = Math.min(minY, b.top);
|
|
11412
|
+
maxX = Math.max(maxX, b.left + b.width);
|
|
11413
|
+
maxY = Math.max(maxY, b.top + b.height);
|
|
11414
|
+
}
|
|
11415
|
+
if (Number.isFinite(minX) && Number.isFinite(minY) && maxX > minX && maxY > minY) {
|
|
11416
|
+
bounds.push({ left: minX, top: minY, width: maxX - minX, height: maxY - minY });
|
|
11417
|
+
}
|
|
11418
|
+
visit(node.children ?? []);
|
|
11419
|
+
}
|
|
11420
|
+
};
|
|
11421
|
+
visit(children);
|
|
11422
|
+
const seen = /* @__PURE__ */ new Set();
|
|
11423
|
+
return bounds.filter((b) => {
|
|
11424
|
+
const key = `${Math.round(b.left)}:${Math.round(b.top)}:${Math.round(b.width)}:${Math.round(b.height)}`;
|
|
11425
|
+
if (seen.has(key)) return false;
|
|
11426
|
+
seen.add(key);
|
|
11427
|
+
return true;
|
|
11428
|
+
});
|
|
11429
|
+
}, [pageId, pageChildren]);
|
|
10179
11430
|
const calculateScaleSnapGuidesCallback = react.useCallback(
|
|
10180
11431
|
(scalingObj, corner) => {
|
|
10181
11432
|
const fabricCanvas = fabricRef.current;
|
|
10182
11433
|
if (!fabricCanvas) return [];
|
|
11434
|
+
const ps = projectSettingsRef.current;
|
|
11435
|
+
const excludeIds = getResizeExcludeIdsCallback(scalingObj);
|
|
10183
11436
|
return calculateScaleSnapGuides(
|
|
10184
11437
|
scalingObj,
|
|
10185
11438
|
corner,
|
|
10186
|
-
fabricCanvas,
|
|
11439
|
+
fabricCanvas,
|
|
11440
|
+
canvasWidth,
|
|
11441
|
+
canvasHeight,
|
|
11442
|
+
ps.snapToGuides,
|
|
11443
|
+
ps.snapThreshold || 4,
|
|
11444
|
+
getLogicalGroupSnapBoundsCallback(excludeIds)
|
|
11445
|
+
);
|
|
11446
|
+
},
|
|
11447
|
+
[canvasWidth, canvasHeight, getLogicalGroupSnapBoundsCallback, getResizeExcludeIdsCallback]
|
|
11448
|
+
);
|
|
11449
|
+
const snapDuringScaleCallback = react.useCallback(
|
|
11450
|
+
(obj, corner) => {
|
|
11451
|
+
const fc = fabricRef.current;
|
|
11452
|
+
if (!fc || !obj || !corner) return;
|
|
11453
|
+
const ps = projectSettingsRef.current;
|
|
11454
|
+
if (!ps.snapToGuides) return;
|
|
11455
|
+
if (obj instanceof fabric__namespace.Textbox && (corner === "ml" || corner === "mr")) {
|
|
11456
|
+
const sourceEl = getObjectId(obj) ? elementsRef.current.find((el) => el.id === getObjectId(obj)) : void 0;
|
|
11457
|
+
bakeTextboxScaleIntoTypography(obj, sourceEl);
|
|
11458
|
+
}
|
|
11459
|
+
try {
|
|
11460
|
+
obj.setCoords();
|
|
11461
|
+
} catch {
|
|
11462
|
+
}
|
|
11463
|
+
const br = obj.getBoundingRect();
|
|
11464
|
+
const excludeIds = getResizeExcludeIdsCallback(obj);
|
|
11465
|
+
const snapThreshold = ps.snapThreshold || 4;
|
|
11466
|
+
const snapped = applyScaleSnapToBox(
|
|
11467
|
+
{ left: br.left, top: br.top, width: br.width, height: br.height },
|
|
11468
|
+
corner,
|
|
11469
|
+
fc,
|
|
10187
11470
|
canvasWidth,
|
|
10188
11471
|
canvasHeight,
|
|
10189
|
-
|
|
10190
|
-
|
|
11472
|
+
true,
|
|
11473
|
+
snapThreshold,
|
|
11474
|
+
getObjectId(obj),
|
|
11475
|
+
{
|
|
11476
|
+
hysteresis: 3,
|
|
11477
|
+
activeSnapRef: objectResizeActiveSnapRef,
|
|
11478
|
+
roundSnappedOnly: true,
|
|
11479
|
+
additionalBounds: getLogicalGroupSnapBoundsCallback(excludeIds),
|
|
11480
|
+
excludeObjectIds: excludeIds,
|
|
11481
|
+
matchDimensions: true
|
|
11482
|
+
}
|
|
10191
11483
|
);
|
|
11484
|
+
const maxSnapShift = Math.max(snapThreshold + 3, 10);
|
|
11485
|
+
const brRight = br.left + br.width;
|
|
11486
|
+
const brBottom = br.top + br.height;
|
|
11487
|
+
const snappedRight = snapped.left + snapped.width;
|
|
11488
|
+
const snappedBottom = snapped.top + snapped.height;
|
|
11489
|
+
const xJump = Math.max(Math.abs(snapped.left - br.left), Math.abs(snappedRight - brRight));
|
|
11490
|
+
const yJump = Math.max(Math.abs(snapped.top - br.top), Math.abs(snappedBottom - brBottom));
|
|
11491
|
+
if (xJump > maxSnapShift) {
|
|
11492
|
+
snapped.left = br.left;
|
|
11493
|
+
snapped.width = br.width;
|
|
11494
|
+
if (objectResizeActiveSnapRef.current) {
|
|
11495
|
+
delete objectResizeActiveSnapRef.current.left;
|
|
11496
|
+
delete objectResizeActiveSnapRef.current.right;
|
|
11497
|
+
delete objectResizeActiveSnapRef.current.width;
|
|
11498
|
+
}
|
|
11499
|
+
}
|
|
11500
|
+
if (yJump > maxSnapShift) {
|
|
11501
|
+
snapped.top = br.top;
|
|
11502
|
+
snapped.height = br.height;
|
|
11503
|
+
if (objectResizeActiveSnapRef.current) {
|
|
11504
|
+
delete objectResizeActiveSnapRef.current.top;
|
|
11505
|
+
delete objectResizeActiveSnapRef.current.bottom;
|
|
11506
|
+
delete objectResizeActiveSnapRef.current.height;
|
|
11507
|
+
}
|
|
11508
|
+
}
|
|
11509
|
+
if (Math.abs(snapped.left - br.left) < 0.01 && Math.abs(snapped.top - br.top) < 0.01 && Math.abs(snapped.width - br.width) < 0.01 && Math.abs(snapped.height - br.height) < 0.01) return;
|
|
11510
|
+
if (obj instanceof fabric__namespace.Textbox && (corner === "ml" || corner === "mr")) {
|
|
11511
|
+
if (corner.includes("l") !== corner.includes("r")) {
|
|
11512
|
+
obj.set({ width: Math.max(20, snapped.width) });
|
|
11513
|
+
obj.initDimensions();
|
|
11514
|
+
obj.setCoords();
|
|
11515
|
+
const after2 = obj.getBoundingRect();
|
|
11516
|
+
obj.set({ left: (obj.left ?? 0) + (snapped.left - after2.left), top: (obj.top ?? 0) + (snapped.top - after2.top) });
|
|
11517
|
+
obj.setCoords();
|
|
11518
|
+
}
|
|
11519
|
+
return;
|
|
11520
|
+
}
|
|
11521
|
+
const baseW = obj.width ?? 1;
|
|
11522
|
+
const baseH = obj.height ?? 1;
|
|
11523
|
+
const signX = (obj.scaleX ?? 1) < 0 ? -1 : 1;
|
|
11524
|
+
const signY = (obj.scaleY ?? 1) < 0 ? -1 : 1;
|
|
11525
|
+
const newScaleX = snapped.width / Math.max(1, baseW) * signX;
|
|
11526
|
+
const newScaleY = snapped.height / Math.max(1, baseH) * signY;
|
|
11527
|
+
obj.set({ scaleX: newScaleX, scaleY: newScaleY });
|
|
11528
|
+
obj.setCoords();
|
|
11529
|
+
const after = obj.getBoundingRect();
|
|
11530
|
+
obj.set({ left: (obj.left ?? 0) + (snapped.left - after.left), top: (obj.top ?? 0) + (snapped.top - after.top) });
|
|
11531
|
+
obj.setCoords();
|
|
10192
11532
|
},
|
|
10193
|
-
[canvasWidth, canvasHeight,
|
|
11533
|
+
[canvasWidth, canvasHeight, getLogicalGroupSnapBoundsCallback, getResizeExcludeIdsCallback]
|
|
10194
11534
|
);
|
|
11535
|
+
const installImageResizeControlsWithSnap = react.useCallback((group) => {
|
|
11536
|
+
group.__resizeSnapHandler = (target, corner) => {
|
|
11537
|
+
const fc = fabricRef.current ?? target.canvas;
|
|
11538
|
+
if (!fc || !isActiveRef.current || !corner) return;
|
|
11539
|
+
fc.__isUserTransforming = true;
|
|
11540
|
+
didTransformRef.current = true;
|
|
11541
|
+
lastResizeScaleTargetRef.current = target;
|
|
11542
|
+
const targetId = getObjectId(target);
|
|
11543
|
+
if (targetId && targetId !== "__background__") {
|
|
11544
|
+
preserveSelectionAfterTransformIdRef.current = targetId;
|
|
11545
|
+
transformingIdsRef.current.add(targetId);
|
|
11546
|
+
}
|
|
11547
|
+
target.getObjects().forEach((member) => {
|
|
11548
|
+
const memberId = getObjectId(member);
|
|
11549
|
+
if (memberId) transformingIdsRef.current.add(memberId);
|
|
11550
|
+
});
|
|
11551
|
+
const gridGuidesForResize = [];
|
|
11552
|
+
try {
|
|
11553
|
+
target.setCoords();
|
|
11554
|
+
const br = target.getBoundingRect();
|
|
11555
|
+
const excludeIds = getResizeExcludeIdsCallback(target);
|
|
11556
|
+
const ps = projectSettingsRef.current;
|
|
11557
|
+
const snapThreshold = ps.snapThreshold || 4;
|
|
11558
|
+
const snapped = applyScaleSnapToBox(
|
|
11559
|
+
{ left: br.left, top: br.top, width: br.width, height: br.height },
|
|
11560
|
+
corner,
|
|
11561
|
+
fc,
|
|
11562
|
+
canvasWidth,
|
|
11563
|
+
canvasHeight,
|
|
11564
|
+
ps.snapToGuides,
|
|
11565
|
+
snapThreshold,
|
|
11566
|
+
targetId ?? void 0,
|
|
11567
|
+
{
|
|
11568
|
+
hysteresis: 3,
|
|
11569
|
+
activeSnapRef: objectResizeActiveSnapRef,
|
|
11570
|
+
roundSnappedOnly: true,
|
|
11571
|
+
additionalBounds: getLogicalGroupSnapBoundsCallback(excludeIds),
|
|
11572
|
+
excludeObjectIds: excludeIds,
|
|
11573
|
+
matchDimensions: true
|
|
11574
|
+
}
|
|
11575
|
+
);
|
|
11576
|
+
const maxSnapShift = Math.max(snapThreshold + 3, 10);
|
|
11577
|
+
const brRight = br.left + br.width;
|
|
11578
|
+
const brBottom = br.top + br.height;
|
|
11579
|
+
const snappedRight = snapped.left + snapped.width;
|
|
11580
|
+
const snappedBottom = snapped.top + snapped.height;
|
|
11581
|
+
const xJump = Math.max(Math.abs(snapped.left - br.left), Math.abs(snappedRight - brRight));
|
|
11582
|
+
const yJump = Math.max(Math.abs(snapped.top - br.top), Math.abs(snappedBottom - brBottom));
|
|
11583
|
+
if (xJump > maxSnapShift) {
|
|
11584
|
+
snapped.left = br.left;
|
|
11585
|
+
snapped.width = br.width;
|
|
11586
|
+
if (objectResizeActiveSnapRef.current) {
|
|
11587
|
+
delete objectResizeActiveSnapRef.current.left;
|
|
11588
|
+
delete objectResizeActiveSnapRef.current.right;
|
|
11589
|
+
delete objectResizeActiveSnapRef.current.width;
|
|
11590
|
+
}
|
|
11591
|
+
}
|
|
11592
|
+
if (yJump > maxSnapShift) {
|
|
11593
|
+
snapped.top = br.top;
|
|
11594
|
+
snapped.height = br.height;
|
|
11595
|
+
if (objectResizeActiveSnapRef.current) {
|
|
11596
|
+
delete objectResizeActiveSnapRef.current.top;
|
|
11597
|
+
delete objectResizeActiveSnapRef.current.bottom;
|
|
11598
|
+
delete objectResizeActiveSnapRef.current.height;
|
|
11599
|
+
}
|
|
11600
|
+
}
|
|
11601
|
+
const gridX = ps.gridSizeX ?? ps.gridSize ?? 0;
|
|
11602
|
+
const gridY = ps.gridSizeY ?? ps.gridSize ?? 0;
|
|
11603
|
+
if (ps.snapToGrid && gridX > 0 && gridY > 0) {
|
|
11604
|
+
const hasL = corner.includes("l");
|
|
11605
|
+
const hasR = corner.includes("r");
|
|
11606
|
+
const hasT = corner.includes("t");
|
|
11607
|
+
const hasB = corner.includes("b");
|
|
11608
|
+
const anchorRight = snapped.left + snapped.width;
|
|
11609
|
+
const anchorBottom = snapped.top + snapped.height;
|
|
11610
|
+
if (hasL) {
|
|
11611
|
+
const newLeft = Math.round(snapped.left / gridX) * gridX;
|
|
11612
|
+
const newWidth = Math.max(20, anchorRight - newLeft);
|
|
11613
|
+
snapped.left = anchorRight - newWidth;
|
|
11614
|
+
snapped.width = newWidth;
|
|
11615
|
+
gridGuidesForResize.push({ type: "vertical", position: snapped.left, kind: "grid" });
|
|
11616
|
+
} else if (hasR) {
|
|
11617
|
+
const newRight = Math.round(anchorRight / gridX) * gridX;
|
|
11618
|
+
snapped.width = Math.max(20, newRight - snapped.left);
|
|
11619
|
+
gridGuidesForResize.push({ type: "vertical", position: snapped.left + snapped.width, kind: "grid" });
|
|
11620
|
+
}
|
|
11621
|
+
if (hasT) {
|
|
11622
|
+
const newTop = Math.round(snapped.top / gridY) * gridY;
|
|
11623
|
+
const newHeight = Math.max(20, anchorBottom - newTop);
|
|
11624
|
+
snapped.top = anchorBottom - newHeight;
|
|
11625
|
+
snapped.height = newHeight;
|
|
11626
|
+
gridGuidesForResize.push({ type: "horizontal", position: snapped.top, kind: "grid" });
|
|
11627
|
+
} else if (hasB) {
|
|
11628
|
+
const newBottom = Math.round(anchorBottom / gridY) * gridY;
|
|
11629
|
+
snapped.height = Math.max(20, newBottom - snapped.top);
|
|
11630
|
+
gridGuidesForResize.push({ type: "horizontal", position: snapped.top + snapped.height, kind: "grid" });
|
|
11631
|
+
}
|
|
11632
|
+
}
|
|
11633
|
+
const changed = Math.abs(snapped.left - br.left) > 0.01 || Math.abs(snapped.top - br.top) > 0.01 || Math.abs(snapped.width - br.width) > 0.01 || Math.abs(snapped.height - br.height) > 0.01;
|
|
11634
|
+
if (changed) {
|
|
11635
|
+
const ct = target.__cropData;
|
|
11636
|
+
if (ct) {
|
|
11637
|
+
const next = { ...snapped };
|
|
11638
|
+
const isCornerHandle = corner.includes("l") !== corner.includes("r") && corner.includes("t") !== corner.includes("b");
|
|
11639
|
+
const widthChanged = Math.abs(snapped.width - br.width) > 0.01;
|
|
11640
|
+
const heightChanged = Math.abs(snapped.height - br.height) > 0.01;
|
|
11641
|
+
if (isCornerHandle && br.width > 0 && br.height > 0 && widthChanged !== heightChanged) {
|
|
11642
|
+
const aspect = br.width / br.height;
|
|
11643
|
+
if (widthChanged) {
|
|
11644
|
+
next.height = Math.max(20, next.width / aspect);
|
|
11645
|
+
if (corner.includes("t")) next.top = br.top + br.height - next.height;
|
|
11646
|
+
} else {
|
|
11647
|
+
next.width = Math.max(20, next.height * aspect);
|
|
11648
|
+
if (corner.includes("l")) next.left = br.left + br.width - next.width;
|
|
11649
|
+
}
|
|
11650
|
+
} else if (isCornerHandle && br.width > 0 && br.height > 0) {
|
|
11651
|
+
const aspect = br.width / br.height;
|
|
11652
|
+
const nextAspect = next.width / Math.max(1, next.height);
|
|
11653
|
+
if (Math.abs(nextAspect - aspect) > 0.01) {
|
|
11654
|
+
const widthDelta = Math.abs(next.width - br.width);
|
|
11655
|
+
const heightDelta = Math.abs(next.height - br.height);
|
|
11656
|
+
if (widthDelta <= heightDelta) {
|
|
11657
|
+
next.height = Math.max(20, next.width / aspect);
|
|
11658
|
+
if (corner.includes("t")) next.top = br.top + br.height - next.height;
|
|
11659
|
+
} else {
|
|
11660
|
+
next.width = Math.max(20, next.height * aspect);
|
|
11661
|
+
if (corner.includes("l")) next.left = br.left + br.width - next.width;
|
|
11662
|
+
}
|
|
11663
|
+
}
|
|
11664
|
+
}
|
|
11665
|
+
ct.frameW = Math.max(20, next.width);
|
|
11666
|
+
ct.frameH = Math.max(20, next.height);
|
|
11667
|
+
target.set({
|
|
11668
|
+
left: next.left + ct.frameW / 2,
|
|
11669
|
+
top: next.top + ct.frameH / 2,
|
|
11670
|
+
width: ct.frameW,
|
|
11671
|
+
height: ct.frameH,
|
|
11672
|
+
scaleX: 1,
|
|
11673
|
+
scaleY: 1,
|
|
11674
|
+
originX: "center",
|
|
11675
|
+
originY: "center"
|
|
11676
|
+
});
|
|
11677
|
+
updateCoverLayout(target);
|
|
11678
|
+
}
|
|
11679
|
+
}
|
|
11680
|
+
} catch {
|
|
11681
|
+
snapDuringScaleCallback(target, corner);
|
|
11682
|
+
}
|
|
11683
|
+
try {
|
|
11684
|
+
target.setCoords();
|
|
11685
|
+
const br = target.getBoundingRect();
|
|
11686
|
+
setSizeLabel({
|
|
11687
|
+
width: Math.round(br.width),
|
|
11688
|
+
height: Math.round(br.height),
|
|
11689
|
+
x: br.left + br.width / 2,
|
|
11690
|
+
y: br.top + br.height + 18
|
|
11691
|
+
});
|
|
11692
|
+
} catch {
|
|
11693
|
+
}
|
|
11694
|
+
const smartGuides = calculateScaleSnapGuidesCallback(target, corner);
|
|
11695
|
+
setGuides(gridGuidesForResize.length ? [...smartGuides, ...gridGuidesForResize] : smartGuides);
|
|
11696
|
+
setHoverBounds(null);
|
|
11697
|
+
};
|
|
11698
|
+
installCanvaMaskControls(group);
|
|
11699
|
+
applyControlSizeForZoom(group.canvas ?? fabricRef.current, group);
|
|
11700
|
+
ensureCanvaControlRenders(group);
|
|
11701
|
+
}, [calculateScaleSnapGuidesCallback, canvasHeight, canvasWidth, getLogicalGroupSnapBoundsCallback, getResizeExcludeIdsCallback, snapDuringScaleCallback]);
|
|
10195
11702
|
const isTransforming = react.useCallback((canvas2) => {
|
|
10196
11703
|
if (!canvas2) return false;
|
|
10197
11704
|
return !!canvas2._currentTransform || !!canvas2.__isUserTransforming;
|
|
@@ -10317,6 +11824,8 @@ const PageCanvas = react.forwardRef(
|
|
|
10317
11824
|
// Transparent so underlay (page bg + group bgs) shows through
|
|
10318
11825
|
backgroundColor: "transparent"
|
|
10319
11826
|
});
|
|
11827
|
+
fabricCanvas.hoverCursor = "default";
|
|
11828
|
+
fabricCanvas.moveCursor = "move";
|
|
10320
11829
|
if (!allowSelection) {
|
|
10321
11830
|
fabricCanvas.selection = false;
|
|
10322
11831
|
fabricCanvas.on("selection:created", () => {
|
|
@@ -10338,6 +11847,61 @@ const PageCanvas = react.forwardRef(
|
|
|
10338
11847
|
fabricRef.current = fabricCanvas;
|
|
10339
11848
|
const storeRegistryKey = registerFabricCanvas(pageId, fabricCanvas);
|
|
10340
11849
|
fabricCanvas.__storeRegistryKey = storeRegistryKey;
|
|
11850
|
+
{
|
|
11851
|
+
const TWEEN_MS = 130;
|
|
11852
|
+
const active = /* @__PURE__ */ new Map();
|
|
11853
|
+
const ensureMap = (obj) => {
|
|
11854
|
+
if (!obj.__handleHoverProgress) obj.__handleHoverProgress = {};
|
|
11855
|
+
return obj.__handleHoverProgress;
|
|
11856
|
+
};
|
|
11857
|
+
const stateKey = (obj, key) => `${obj.__docuforgeId || ""}:${key}`;
|
|
11858
|
+
const step = (sk) => {
|
|
11859
|
+
const s = active.get(sk);
|
|
11860
|
+
if (!s) return;
|
|
11861
|
+
const t = Math.min(1, (performance.now() - s.start) / TWEEN_MS);
|
|
11862
|
+
const eased = 1 - Math.pow(1 - t, 3);
|
|
11863
|
+
const value = s.from + (s.to - s.from) * eased;
|
|
11864
|
+
const map = ensureMap(s.obj);
|
|
11865
|
+
map[s.key] = value;
|
|
11866
|
+
try {
|
|
11867
|
+
fabricCanvas.requestRenderAll();
|
|
11868
|
+
} catch {
|
|
11869
|
+
}
|
|
11870
|
+
if (t < 1) {
|
|
11871
|
+
s.raf = requestAnimationFrame(() => step(sk));
|
|
11872
|
+
} else {
|
|
11873
|
+
map[s.key] = s.to;
|
|
11874
|
+
active.delete(sk);
|
|
11875
|
+
}
|
|
11876
|
+
};
|
|
11877
|
+
const startTween = (obj, key, to) => {
|
|
11878
|
+
const sk = stateKey(obj, key);
|
|
11879
|
+
const map = ensureMap(obj);
|
|
11880
|
+
const from = map[key] ?? (to === 1 ? 0 : 1);
|
|
11881
|
+
if (from === to) return;
|
|
11882
|
+
const existing = active.get(sk);
|
|
11883
|
+
if (existing && existing.raf != null) cancelAnimationFrame(existing.raf);
|
|
11884
|
+
const s = { obj, key, start: performance.now(), from, to, raf: null };
|
|
11885
|
+
active.set(sk, s);
|
|
11886
|
+
s.raf = requestAnimationFrame(() => step(sk));
|
|
11887
|
+
};
|
|
11888
|
+
let prevTarget = null;
|
|
11889
|
+
let prevKey = null;
|
|
11890
|
+
fabricCanvas.on("mouse:move", (opt) => {
|
|
11891
|
+
const t = opt == null ? void 0 : opt.target;
|
|
11892
|
+
const key = t && t.__corner ? String(t.__corner) : null;
|
|
11893
|
+
if (t === prevTarget && key === prevKey) return;
|
|
11894
|
+
if (prevTarget && prevKey) startTween(prevTarget, prevKey, 0);
|
|
11895
|
+
if (t && key) startTween(t, key, 1);
|
|
11896
|
+
prevTarget = t;
|
|
11897
|
+
prevKey = key;
|
|
11898
|
+
});
|
|
11899
|
+
fabricCanvas.on("mouse:out", () => {
|
|
11900
|
+
if (prevTarget && prevKey) startTween(prevTarget, prevKey, 0);
|
|
11901
|
+
prevTarget = null;
|
|
11902
|
+
prevKey = null;
|
|
11903
|
+
});
|
|
11904
|
+
}
|
|
10341
11905
|
const initFonts = async () => {
|
|
10342
11906
|
try {
|
|
10343
11907
|
await preloadAllFonts();
|
|
@@ -10427,6 +11991,17 @@ const PageCanvas = react.forwardRef(
|
|
|
10427
11991
|
});
|
|
10428
11992
|
fabricCanvas.on("mouse:up", () => {
|
|
10429
11993
|
fabricCanvas.__isUserTransforming = false;
|
|
11994
|
+
objectResizeActiveSnapRef.current = null;
|
|
11995
|
+
groupResizeActiveSnapRef.current = null;
|
|
11996
|
+
try {
|
|
11997
|
+
for (const o of fabricCanvas.getObjects()) {
|
|
11998
|
+
if (o.__pixldocsDragMoved) o.__pixldocsDragMoved = false;
|
|
11999
|
+
}
|
|
12000
|
+
const active = fabricCanvas.getActiveObject();
|
|
12001
|
+
if (active == null ? void 0 : active.__pixldocsDragMoved) active.__pixldocsDragMoved = false;
|
|
12002
|
+
fabricCanvas.requestRenderAll();
|
|
12003
|
+
} catch {
|
|
12004
|
+
}
|
|
10430
12005
|
});
|
|
10431
12006
|
fabricCanvas.on("object:scaling", () => {
|
|
10432
12007
|
fabricCanvas.__isUserTransforming = true;
|
|
@@ -10473,7 +12048,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10473
12048
|
didTransformRef.current = true;
|
|
10474
12049
|
});
|
|
10475
12050
|
const syncSelectionToStore = () => {
|
|
10476
|
-
var _a2,
|
|
12051
|
+
var _a2, _b2, _c, _d;
|
|
10477
12052
|
if (!isActiveRef.current || isRebuildingRef.current || isSyncingSelectionToFabricRef.current || !allowSelection) return;
|
|
10478
12053
|
const walkToTopmostGroup = (childId, children, activeEditingGroupId) => {
|
|
10479
12054
|
let topmost = null;
|
|
@@ -10512,7 +12087,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10512
12087
|
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
10513
12088
|
const clickedId = ids[0];
|
|
10514
12089
|
const state = useEditorStore.getState();
|
|
10515
|
-
const currentPage2 = (
|
|
12090
|
+
const currentPage2 = (_b2 = state.canvas.pages) == null ? void 0 : _b2.find((p) => p.id === pageId);
|
|
10516
12091
|
const children = (currentPage2 == null ? void 0 : currentPage2.children) ?? [];
|
|
10517
12092
|
const parent = walkToTopmostGroup(clickedId, children, activeEditingGroupId);
|
|
10518
12093
|
const targetIsInCrop = !!(active instanceof fabric__namespace.Group && isCropGroupInCropMode(active) || (active == null ? void 0 : active.group) instanceof fabric__namespace.Group && isCropGroupInCropMode(active.group));
|
|
@@ -10659,8 +12234,10 @@ const PageCanvas = react.forwardRef(
|
|
|
10659
12234
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10660
12235
|
if (activeObj instanceof fabric__namespace.ActiveSelection) applyWarpAwareSelectionBorders(activeObj);
|
|
10661
12236
|
if (activeObj) applyControlSizeForZoom(fabricCanvas, activeObj);
|
|
12237
|
+
if (activeObj) ensureCanvaControlRenders(activeObj);
|
|
10662
12238
|
if (activeObj && !(activeObj instanceof fabric__namespace.ActiveSelection) && (((_a2 = activeObj._ct) == null ? void 0 : _a2.isCropGroup) || activeObj.__cropGroup)) {
|
|
10663
|
-
|
|
12239
|
+
installImageResizeControlsWithSnap(activeObj);
|
|
12240
|
+
ensureCanvaControlRenders(activeObj);
|
|
10664
12241
|
}
|
|
10665
12242
|
});
|
|
10666
12243
|
fabricCanvas.on("selection:updated", () => {
|
|
@@ -10672,12 +12249,14 @@ const PageCanvas = react.forwardRef(
|
|
|
10672
12249
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10673
12250
|
if (activeObj instanceof fabric__namespace.ActiveSelection) applyWarpAwareSelectionBorders(activeObj);
|
|
10674
12251
|
if (activeObj) applyControlSizeForZoom(fabricCanvas, activeObj);
|
|
12252
|
+
if (activeObj) ensureCanvaControlRenders(activeObj);
|
|
10675
12253
|
if (activeObj && !(activeObj instanceof fabric__namespace.ActiveSelection) && (((_a2 = activeObj._ct) == null ? void 0 : _a2.isCropGroup) || activeObj.__cropGroup)) {
|
|
10676
|
-
|
|
12254
|
+
installImageResizeControlsWithSnap(activeObj);
|
|
12255
|
+
ensureCanvaControlRenders(activeObj);
|
|
10677
12256
|
}
|
|
10678
12257
|
});
|
|
10679
12258
|
fabricCanvas.on("mouse:dblclick", (opt) => {
|
|
10680
|
-
var _a2,
|
|
12259
|
+
var _a2, _b2;
|
|
10681
12260
|
const target = opt == null ? void 0 : opt.target;
|
|
10682
12261
|
if (!target) return;
|
|
10683
12262
|
if (target.isEditing) return;
|
|
@@ -10701,7 +12280,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10701
12280
|
const childId = getObjectId(hitChild);
|
|
10702
12281
|
if (!childId) return;
|
|
10703
12282
|
const stateNow = useEditorStore.getState();
|
|
10704
|
-
const pageNow = (
|
|
12283
|
+
const pageNow = (_b2 = stateNow.canvas.pages) == null ? void 0 : _b2.find((p) => p.id === pageId);
|
|
10705
12284
|
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
10706
12285
|
const chain = [];
|
|
10707
12286
|
{
|
|
@@ -10828,7 +12407,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10828
12407
|
transformingIdsRef.current.clear();
|
|
10829
12408
|
};
|
|
10830
12409
|
const prepareGroupSelectionTransformStart = (target) => {
|
|
10831
|
-
var _a2,
|
|
12410
|
+
var _a2, _b2;
|
|
10832
12411
|
const active = target instanceof fabric__namespace.ActiveSelection ? target : fabricCanvas.getActiveObject();
|
|
10833
12412
|
if (!(active instanceof fabric__namespace.ActiveSelection)) return;
|
|
10834
12413
|
if (!activeSelectionMoveStartRef.current || activeSelectionMoveStartRef.current.selection !== active) {
|
|
@@ -10842,7 +12421,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10842
12421
|
const groupId = active.__pixldocsGroupSelection;
|
|
10843
12422
|
if (!groupId) return;
|
|
10844
12423
|
if (((_a2 = groupSelectionTransformStartRef.current) == null ? void 0 : _a2.groupId) === groupId && groupSelectionTransformStartRef.current.selection === active) return;
|
|
10845
|
-
const pageChildren2 = ((
|
|
12424
|
+
const pageChildren2 = ((_b2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
|
|
10846
12425
|
const groupNode = findNodeById(pageChildren2, groupId);
|
|
10847
12426
|
if (!groupNode) return;
|
|
10848
12427
|
const groupAbs = getAbsoluteBounds(groupNode, pageChildren2);
|
|
@@ -10926,7 +12505,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10926
12505
|
};
|
|
10927
12506
|
let pendingShiftMultiSelect = null;
|
|
10928
12507
|
const applyShiftMultiSelect = (target, event, baselineActive = fabricCanvas.getActiveObject(), baselineObjects = fabricCanvas.getActiveObjects()) => {
|
|
10929
|
-
var _a2,
|
|
12508
|
+
var _a2, _b2, _c;
|
|
10930
12509
|
if (!target || !target.selectable) return false;
|
|
10931
12510
|
const active = baselineActive;
|
|
10932
12511
|
if (!active || ((_a2 = active.getActiveControl) == null ? void 0 : _a2.call(active))) return false;
|
|
@@ -10960,7 +12539,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10960
12539
|
isSyncingSelectionToFabricRef.current = false;
|
|
10961
12540
|
});
|
|
10962
12541
|
}
|
|
10963
|
-
(
|
|
12542
|
+
(_b2 = event == null ? void 0 : event.preventDefault) == null ? void 0 : _b2.call(event);
|
|
10964
12543
|
(_c = event == null ? void 0 : event.stopPropagation) == null ? void 0 : _c.call(event);
|
|
10965
12544
|
return true;
|
|
10966
12545
|
};
|
|
@@ -11011,9 +12590,9 @@ const PageCanvas = react.forwardRef(
|
|
|
11011
12590
|
return !!(((_a2 = o == null ? void 0 : o._ct) == null ? void 0 : _a2.isCropGroup) || (o == null ? void 0 : o.__cropGroup));
|
|
11012
12591
|
};
|
|
11013
12592
|
const promoteToCropGroup = (opt) => {
|
|
11014
|
-
var _a2,
|
|
12593
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
11015
12594
|
const t = opt.target;
|
|
11016
|
-
if (((_a2 = opt.e) == null ? void 0 : _a2.type) !== "mousedown" && ((
|
|
12595
|
+
if (((_a2 = opt.e) == null ? void 0 : _a2.type) !== "mousedown" && ((_b2 = opt.e) == null ? void 0 : _b2.type) !== "pointerdown" && ((_c = opt.e) == null ? void 0 : _c.type) !== "touchstart") {
|
|
11017
12596
|
if (t && isCropGroup2(t)) {
|
|
11018
12597
|
fabricCanvas._hoveredTarget = t;
|
|
11019
12598
|
} else if ((t == null ? void 0 : t.group) && isCropGroup2(t.group)) {
|
|
@@ -11029,6 +12608,8 @@ const PageCanvas = react.forwardRef(
|
|
|
11029
12608
|
const objects = fabricCanvas.getObjects();
|
|
11030
12609
|
for (const obj of objects) {
|
|
11031
12610
|
if (isCropGroup2(obj) && obj.containsPoint(pointer)) {
|
|
12611
|
+
installImageResizeControlsWithSnap(obj);
|
|
12612
|
+
ensureCanvaControlRenders(obj);
|
|
11032
12613
|
fabricCanvas.setActiveObject(obj);
|
|
11033
12614
|
opt.target = obj;
|
|
11034
12615
|
fabricCanvas._hoveredTarget = obj;
|
|
@@ -11039,12 +12620,16 @@ const PageCanvas = react.forwardRef(
|
|
|
11039
12620
|
}
|
|
11040
12621
|
const g = t.group;
|
|
11041
12622
|
if (g && isCropGroup2(g)) {
|
|
12623
|
+
installImageResizeControlsWithSnap(g);
|
|
12624
|
+
ensureCanvaControlRenders(g);
|
|
11042
12625
|
fabricCanvas.setActiveObject(g);
|
|
11043
12626
|
opt.target = g;
|
|
11044
12627
|
fabricCanvas._hoveredTarget = g;
|
|
11045
12628
|
return;
|
|
11046
12629
|
}
|
|
11047
12630
|
if (isCropGroup2(t)) {
|
|
12631
|
+
installImageResizeControlsWithSnap(t);
|
|
12632
|
+
ensureCanvaControlRenders(t);
|
|
11048
12633
|
fabricCanvas.setActiveObject(t);
|
|
11049
12634
|
t.set({
|
|
11050
12635
|
selectable: true,
|
|
@@ -11097,7 +12682,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11097
12682
|
});
|
|
11098
12683
|
}
|
|
11099
12684
|
fabricCanvas.on("mouse:down", (opt) => {
|
|
11100
|
-
var _a2,
|
|
12685
|
+
var _a2, _b2;
|
|
11101
12686
|
if (pendingShiftMultiSelect) {
|
|
11102
12687
|
const pending = pendingShiftMultiSelect;
|
|
11103
12688
|
pendingShiftMultiSelect = null;
|
|
@@ -11105,17 +12690,19 @@ const PageCanvas = react.forwardRef(
|
|
|
11105
12690
|
return;
|
|
11106
12691
|
}
|
|
11107
12692
|
const target = opt.target;
|
|
11108
|
-
const cropGroup = ((_a2 = target == null ? void 0 : target._ct) == null ? void 0 : _a2.isCropGroup) || (target == null ? void 0 : target.__cropGroup) ? target : (target == null ? void 0 : target.group) && (((
|
|
12693
|
+
const cropGroup = ((_a2 = target == null ? void 0 : target._ct) == null ? void 0 : _a2.isCropGroup) || (target == null ? void 0 : target.__cropGroup) ? target : (target == null ? void 0 : target.group) && (((_b2 = target.group._ct) == null ? void 0 : _b2.isCropGroup) || target.group.__cropGroup) ? target.group : null;
|
|
11109
12694
|
if (cropGroup) {
|
|
11110
12695
|
lockEdits();
|
|
11111
12696
|
didTransformRef.current = false;
|
|
12697
|
+
installImageResizeControlsWithSnap(cropGroup);
|
|
12698
|
+
ensureCanvaControlRenders(cropGroup);
|
|
11112
12699
|
fabricCanvas.setActiveObject(cropGroup);
|
|
11113
12700
|
cropGroup.setCoords();
|
|
11114
12701
|
fabricCanvas.requestRenderAll();
|
|
11115
12702
|
}
|
|
11116
12703
|
});
|
|
11117
12704
|
const groupFabricUnionBBox = (g) => {
|
|
11118
|
-
var _a2,
|
|
12705
|
+
var _a2, _b2;
|
|
11119
12706
|
const memberIds = new Set(getAllElementIds(g.children ?? []));
|
|
11120
12707
|
if (memberIds.size === 0) return null;
|
|
11121
12708
|
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
@@ -11123,7 +12710,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11123
12710
|
for (const o of fabricCanvas.getObjects()) {
|
|
11124
12711
|
const oid = getObjectId(o);
|
|
11125
12712
|
if (!oid || !memberIds.has(oid)) continue;
|
|
11126
|
-
const br = ((_a2 = o.getBoundingRect) == null ? void 0 : _a2.call(o, true, true)) ?? ((
|
|
12713
|
+
const br = ((_a2 = o.getBoundingRect) == null ? void 0 : _a2.call(o, true, true)) ?? ((_b2 = o.getBoundingRect) == null ? void 0 : _b2.call(o));
|
|
11127
12714
|
if (!br) continue;
|
|
11128
12715
|
minX = Math.min(minX, br.left);
|
|
11129
12716
|
minY = Math.min(minY, br.top);
|
|
@@ -11149,13 +12736,13 @@ const PageCanvas = react.forwardRef(
|
|
|
11149
12736
|
return pick;
|
|
11150
12737
|
};
|
|
11151
12738
|
fabricCanvas.on("mouse:down:before", (opt) => {
|
|
11152
|
-
var _a2,
|
|
12739
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
|
|
11153
12740
|
if (editLockRef.current) {
|
|
11154
12741
|
const active = fabricCanvas.getActiveObject();
|
|
11155
12742
|
if (active && (((_a2 = active._ct) == null ? void 0 : _a2.isCropGroup) || active.__cropGroup)) {
|
|
11156
12743
|
opt.target = active;
|
|
11157
12744
|
if (opt.e) {
|
|
11158
|
-
(_c = (
|
|
12745
|
+
(_c = (_b2 = opt.e).preventDefault) == null ? void 0 : _c.call(_b2);
|
|
11159
12746
|
(_e = (_d = opt.e).stopPropagation) == null ? void 0 : _e.call(_d);
|
|
11160
12747
|
}
|
|
11161
12748
|
}
|
|
@@ -11170,6 +12757,10 @@ const PageCanvas = react.forwardRef(
|
|
|
11170
12757
|
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
11171
12758
|
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
11172
12759
|
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
12760
|
+
if (target instanceof fabric__namespace.Textbox && target.__corner && (target.__corner === "ml" || target.__corner === "mr")) {
|
|
12761
|
+
const sourceEl = targetId ? elementsRef.current.find((el) => el.id === targetId) : void 0;
|
|
12762
|
+
bakeTextboxScaleIntoTypography(target, sourceEl);
|
|
12763
|
+
}
|
|
11173
12764
|
if (isMultiSelectModifier(opt.e)) {
|
|
11174
12765
|
const manualTarget = target && !(target instanceof fabric__namespace.ActiveSelection) && targetId && targetId !== "__background__" ? target : pickSelectableObjectAtPointer(opt.e);
|
|
11175
12766
|
if (manualTarget) {
|
|
@@ -11196,11 +12787,39 @@ const PageCanvas = react.forwardRef(
|
|
|
11196
12787
|
return topmost;
|
|
11197
12788
|
};
|
|
11198
12789
|
if (target && targetId && targetId !== "__background__") {
|
|
11199
|
-
|
|
11200
|
-
|
|
12790
|
+
let effectiveTarget = target;
|
|
12791
|
+
let effectiveTargetId = targetId;
|
|
12792
|
+
const activeNowEarly = fabricCanvas.getActiveObject();
|
|
12793
|
+
const asGroupId = target instanceof fabric__namespace.ActiveSelection ? target.__pixldocsGroupSelection : void 0;
|
|
12794
|
+
if (target instanceof fabric__namespace.ActiveSelection && asGroupId && target === activeNowEarly) {
|
|
12795
|
+
try {
|
|
12796
|
+
const pointer = fabricCanvas.getViewportPoint(opt.e);
|
|
12797
|
+
const members = target.getObjects();
|
|
12798
|
+
for (let i = members.length - 1; i >= 0; i--) {
|
|
12799
|
+
const m = members[i];
|
|
12800
|
+
if (m.visible === false) continue;
|
|
12801
|
+
if (typeof m.containsPoint === "function" && m.containsPoint(pointer)) {
|
|
12802
|
+
const mid = getObjectId(m);
|
|
12803
|
+
if (mid) {
|
|
12804
|
+
effectiveTarget = m;
|
|
12805
|
+
effectiveTargetId = mid;
|
|
12806
|
+
}
|
|
12807
|
+
break;
|
|
12808
|
+
}
|
|
12809
|
+
}
|
|
12810
|
+
} catch {
|
|
12811
|
+
}
|
|
12812
|
+
}
|
|
12813
|
+
const parent = findTopmostPromotableGroup(effectiveTargetId);
|
|
12814
|
+
const targetIsInCrop = !!(effectiveTarget instanceof fabric__namespace.Group && isCropGroupInCropMode(effectiveTarget) || (effectiveTarget == null ? void 0 : effectiveTarget.group) instanceof fabric__namespace.Group && isCropGroupInCropMode(effectiveTarget.group));
|
|
11201
12815
|
const activeNow = fabricCanvas.getActiveObject();
|
|
11202
12816
|
const alreadyThisGroup = activeNow instanceof fabric__namespace.ActiveSelection && activeNow.__pixldocsGroupSelection === (parent == null ? void 0 : parent.id);
|
|
11203
12817
|
const isMultiSelectKey = !!(((_f = opt.e) == null ? void 0 : _f.shiftKey) || ((_g = opt.e) == null ? void 0 : _g.metaKey) || ((_h = opt.e) == null ? void 0 : _h.ctrlKey));
|
|
12818
|
+
const isDeepSelectKey = !!((_i = opt.e) == null ? void 0 : _i.altKey);
|
|
12819
|
+
if (isDeepSelectKey) {
|
|
12820
|
+
pendingGroupPromotionRef.current = null;
|
|
12821
|
+
return;
|
|
12822
|
+
}
|
|
11204
12823
|
if (parent && !parent.backgroundColor && !targetIsInCrop && activeEditingGroupId !== parent.id && !alreadyThisGroup && !isMultiSelectKey) {
|
|
11205
12824
|
const memberIds = new Set(getAllElementIds(parent.children ?? []));
|
|
11206
12825
|
const memberObjs = fabricCanvas.getObjects().filter((o) => {
|
|
@@ -11224,10 +12843,33 @@ const PageCanvas = react.forwardRef(
|
|
|
11224
12843
|
opt.target = only;
|
|
11225
12844
|
pendingGroupPromotionRef.current = { groupId: parent.id, selection: only };
|
|
11226
12845
|
}
|
|
12846
|
+
} else if (parent && !parent.backgroundColor && !targetIsInCrop && alreadyThisGroup && !isMultiSelectKey && effectiveTarget !== activeNow) {
|
|
12847
|
+
try {
|
|
12848
|
+
skipSelectionClearOnDiscardRef.current = true;
|
|
12849
|
+
preserveEditingScopeOnSelectionClearRef.current = true;
|
|
12850
|
+
restoreSuppressedGroupBorders();
|
|
12851
|
+
fabricCanvas.discardActiveObject();
|
|
12852
|
+
} finally {
|
|
12853
|
+
skipSelectionClearOnDiscardRef.current = false;
|
|
12854
|
+
preserveEditingScopeOnSelectionClearRef.current = false;
|
|
12855
|
+
}
|
|
12856
|
+
fabricCanvas.__activeEditingGroupId = parent.id;
|
|
12857
|
+
delete effectiveTarget.__pixldocsGroupSelection;
|
|
12858
|
+
delete effectiveTarget.__pixldocsLogicalGroupIds;
|
|
12859
|
+
try {
|
|
12860
|
+
(_j = effectiveTarget.set) == null ? void 0 : _j.call(effectiveTarget, { selectable: true, evented: true, hasBorders: true, hasControls: true });
|
|
12861
|
+
} catch {
|
|
12862
|
+
}
|
|
12863
|
+
fabricCanvas.setActiveObject(effectiveTarget);
|
|
12864
|
+
effectiveTarget.setCoords();
|
|
12865
|
+
fabricCanvas._target = effectiveTarget;
|
|
12866
|
+
opt.target = effectiveTarget;
|
|
12867
|
+
pendingGroupPromotionRef.current = null;
|
|
11227
12868
|
}
|
|
11228
12869
|
} else if (!target || targetId === "__background__") {
|
|
11229
|
-
const isMultiSelectKey = !!(((
|
|
12870
|
+
const isMultiSelectKey = !!(((_k = opt.e) == null ? void 0 : _k.shiftKey) || ((_l = opt.e) == null ? void 0 : _l.metaKey) || ((_m = opt.e) == null ? void 0 : _m.ctrlKey));
|
|
11230
12871
|
if (isMultiSelectKey) return;
|
|
12872
|
+
if ((_n = opt.e) == null ? void 0 : _n.altKey) return;
|
|
11231
12873
|
try {
|
|
11232
12874
|
const pointer = fabricCanvas.getPointer(opt.e);
|
|
11233
12875
|
const px = pointer.x;
|
|
@@ -11298,6 +12940,43 @@ const PageCanvas = react.forwardRef(
|
|
|
11298
12940
|
if (editLockRef.current) return;
|
|
11299
12941
|
const t = opt.target;
|
|
11300
12942
|
const tid = t ? getObjectId(t) : null;
|
|
12943
|
+
try {
|
|
12944
|
+
const activeIds = new Set(selectedIdsRef.current);
|
|
12945
|
+
const pointer = fabricCanvas.getPointer(opt.e);
|
|
12946
|
+
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
12947
|
+
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
12948
|
+
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
12949
|
+
const groupPick = pickGroupAtPointer(pointer.x, pointer.y, childrenNow, activeEditingGroupId);
|
|
12950
|
+
if (groupPick && !activeIds.has(groupPick.group.id)) {
|
|
12951
|
+
const b = groupFabricUnionBBox(groupPick.group);
|
|
12952
|
+
if (b) {
|
|
12953
|
+
setHoverBounds({
|
|
12954
|
+
left: b.left,
|
|
12955
|
+
top: b.top,
|
|
12956
|
+
width: b.right - b.left,
|
|
12957
|
+
height: b.bottom - b.top,
|
|
12958
|
+
angle: 0
|
|
12959
|
+
});
|
|
12960
|
+
return;
|
|
12961
|
+
}
|
|
12962
|
+
}
|
|
12963
|
+
const isHoveringSelected = !!(tid && activeIds.has(tid));
|
|
12964
|
+
if (t && tid && tid !== "__background__" && !isHoveringSelected) {
|
|
12965
|
+
t.setCoords();
|
|
12966
|
+
const br = t.getBoundingRect();
|
|
12967
|
+
setHoverBounds({
|
|
12968
|
+
left: br.left,
|
|
12969
|
+
top: br.top,
|
|
12970
|
+
width: br.width,
|
|
12971
|
+
height: br.height,
|
|
12972
|
+
angle: 0
|
|
12973
|
+
});
|
|
12974
|
+
} else {
|
|
12975
|
+
setHoverBounds(null);
|
|
12976
|
+
}
|
|
12977
|
+
} catch {
|
|
12978
|
+
setHoverBounds(null);
|
|
12979
|
+
}
|
|
11301
12980
|
if (t && tid && tid !== "__background__") return;
|
|
11302
12981
|
try {
|
|
11303
12982
|
const pointer = fabricCanvas.getPointer(opt.e);
|
|
@@ -11305,11 +12984,19 @@ const PageCanvas = react.forwardRef(
|
|
|
11305
12984
|
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
11306
12985
|
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
11307
12986
|
const pick = pickGroupAtPointer(pointer.x, pointer.y, childrenNow, activeEditingGroupId);
|
|
11308
|
-
fabricCanvas.defaultCursor =
|
|
12987
|
+
fabricCanvas.defaultCursor = "default";
|
|
11309
12988
|
} catch {
|
|
11310
12989
|
fabricCanvas.defaultCursor = "default";
|
|
11311
12990
|
}
|
|
11312
12991
|
});
|
|
12992
|
+
fabricCanvas.on("mouse:out", () => {
|
|
12993
|
+
setHoverBounds(null);
|
|
12994
|
+
});
|
|
12995
|
+
fabricCanvas.on("mouse:down", () => {
|
|
12996
|
+
setHoverBounds(null);
|
|
12997
|
+
});
|
|
12998
|
+
fabricCanvas.on("selection:created", () => setHoverBounds(null));
|
|
12999
|
+
fabricCanvas.on("selection:updated", () => setHoverBounds(null));
|
|
11313
13000
|
fabricCanvas.on("mouse:down", (ev) => {
|
|
11314
13001
|
if (fabricCanvas._currentTransform) {
|
|
11315
13002
|
lockEdits();
|
|
@@ -11325,6 +13012,8 @@ const PageCanvas = react.forwardRef(
|
|
|
11325
13012
|
setGuides([]);
|
|
11326
13013
|
setRotationLabel(null);
|
|
11327
13014
|
setSizeLabel(null);
|
|
13015
|
+
objectResizeActiveSnapRef.current = null;
|
|
13016
|
+
groupResizeActiveSnapRef.current = null;
|
|
11328
13017
|
dragStarted = false;
|
|
11329
13018
|
const pendingPromotion = pendingGroupPromotionRef.current;
|
|
11330
13019
|
pendingGroupPromotionRef.current = null;
|
|
@@ -11479,7 +13168,9 @@ const PageCanvas = react.forwardRef(
|
|
|
11479
13168
|
const intrH = obj.height ?? 1;
|
|
11480
13169
|
let newW = Math.max(1, intrW * Math.abs(sx));
|
|
11481
13170
|
let newH = Math.max(1, intrH * Math.abs(sy));
|
|
11482
|
-
if (obj instanceof fabric__namespace.
|
|
13171
|
+
if (obj instanceof fabric__namespace.Ellipse) {
|
|
13172
|
+
obj.set({ rx: newW / 2, ry: newH / 2 });
|
|
13173
|
+
} else if (obj instanceof fabric__namespace.Circle) {
|
|
11483
13174
|
const diameter = Math.max(1, Math.min(newW, newH));
|
|
11484
13175
|
newW = diameter;
|
|
11485
13176
|
newH = diameter;
|
|
@@ -11596,8 +13287,128 @@ const PageCanvas = react.forwardRef(
|
|
|
11596
13287
|
}
|
|
11597
13288
|
const transform = e.transform;
|
|
11598
13289
|
const corner = (transform == null ? void 0 : transform.corner) || "";
|
|
13290
|
+
if (obj instanceof fabric__namespace.ActiveSelection && (corner === "ml" || corner === "mr" || corner === "mt" || corner === "mb")) {
|
|
13291
|
+
const isXSide = corner === "ml" || corner === "mr";
|
|
13292
|
+
const sAxis = isXSide ? Math.abs(obj.scaleX ?? 1) : Math.abs(obj.scaleY ?? 1);
|
|
13293
|
+
if (sAxis > 1e-3) {
|
|
13294
|
+
for (const child of obj.getObjects()) {
|
|
13295
|
+
if (!(child instanceof fabric__namespace.Textbox)) continue;
|
|
13296
|
+
if (isXSide) {
|
|
13297
|
+
if (child.__asLiveOrigW == null) {
|
|
13298
|
+
child.__asLiveOrigW = (child.width ?? 0) * (child.scaleX ?? 1);
|
|
13299
|
+
}
|
|
13300
|
+
const origW = child.__asLiveOrigW;
|
|
13301
|
+
const newW = Math.max(20, origW * sAxis);
|
|
13302
|
+
if (Math.abs((child.width ?? 0) - newW) > 0.5) {
|
|
13303
|
+
child.set({ width: newW, scaleX: 1 / sAxis });
|
|
13304
|
+
try {
|
|
13305
|
+
child.initDimensions();
|
|
13306
|
+
} catch {
|
|
13307
|
+
}
|
|
13308
|
+
child.dirty = true;
|
|
13309
|
+
}
|
|
13310
|
+
} else {
|
|
13311
|
+
if (child.__asLiveOrigH == null) {
|
|
13312
|
+
child.__asLiveOrigH = (child.height ?? 0) * (child.scaleY ?? 1);
|
|
13313
|
+
}
|
|
13314
|
+
const origH = child.__asLiveOrigH;
|
|
13315
|
+
const newH = Math.max(20, origH * sAxis);
|
|
13316
|
+
child.minBoxHeight = newH;
|
|
13317
|
+
child.set({ scaleY: 1 / sAxis });
|
|
13318
|
+
try {
|
|
13319
|
+
child.initDimensions();
|
|
13320
|
+
} catch {
|
|
13321
|
+
}
|
|
13322
|
+
child.dirty = true;
|
|
13323
|
+
}
|
|
13324
|
+
}
|
|
13325
|
+
}
|
|
13326
|
+
}
|
|
13327
|
+
snapDuringScaleCallback(obj, corner);
|
|
11599
13328
|
const scaleGuides = calculateScaleSnapGuidesCallback(obj, corner);
|
|
11600
|
-
|
|
13329
|
+
const gridGuidesForScale = [];
|
|
13330
|
+
try {
|
|
13331
|
+
const psGrid = projectSettingsRef.current;
|
|
13332
|
+
const canApplyGridSnap = psGrid.snapToGrid && corner && !obj.__cropGroup && !obj.__resizeSnapHandler;
|
|
13333
|
+
if (canApplyGridSnap) {
|
|
13334
|
+
const gridX = psGrid.gridSizeX ?? psGrid.gridSize ?? 0;
|
|
13335
|
+
const gridY = psGrid.gridSizeY ?? psGrid.gridSize ?? 0;
|
|
13336
|
+
if (gridX > 0 && gridY > 0) {
|
|
13337
|
+
obj.setCoords();
|
|
13338
|
+
const br = obj.getBoundingRect();
|
|
13339
|
+
if (br.width > 1 && br.height > 1) {
|
|
13340
|
+
const hasL = corner.includes("l");
|
|
13341
|
+
const hasR = corner.includes("r");
|
|
13342
|
+
const hasT = corner.includes("t");
|
|
13343
|
+
const hasB = corner.includes("b");
|
|
13344
|
+
const anchorRight = br.left + br.width;
|
|
13345
|
+
const anchorBottom = br.top + br.height;
|
|
13346
|
+
let newLeft = br.left;
|
|
13347
|
+
let newTop = br.top;
|
|
13348
|
+
let newWidth = br.width;
|
|
13349
|
+
let newHeight = br.height;
|
|
13350
|
+
const xAlreadySnapped = scaleGuides.some((g) => g.type === "vertical");
|
|
13351
|
+
const yAlreadySnapped = scaleGuides.some((g) => g.type === "horizontal");
|
|
13352
|
+
if (!xAlreadySnapped) {
|
|
13353
|
+
if (hasL) {
|
|
13354
|
+
const nL = Math.round(br.left / gridX) * gridX;
|
|
13355
|
+
newWidth = Math.max(20, anchorRight - nL);
|
|
13356
|
+
newLeft = anchorRight - newWidth;
|
|
13357
|
+
} else if (hasR) {
|
|
13358
|
+
const nR = Math.round(anchorRight / gridX) * gridX;
|
|
13359
|
+
newWidth = Math.max(20, nR - br.left);
|
|
13360
|
+
}
|
|
13361
|
+
}
|
|
13362
|
+
if (!yAlreadySnapped) {
|
|
13363
|
+
if (hasT) {
|
|
13364
|
+
const nT = Math.round(br.top / gridY) * gridY;
|
|
13365
|
+
newHeight = Math.max(20, anchorBottom - nT);
|
|
13366
|
+
newTop = anchorBottom - newHeight;
|
|
13367
|
+
} else if (hasB) {
|
|
13368
|
+
const nB = Math.round(anchorBottom / gridY) * gridY;
|
|
13369
|
+
newHeight = Math.max(20, nB - br.top);
|
|
13370
|
+
}
|
|
13371
|
+
}
|
|
13372
|
+
const widthChanged = Math.abs(newWidth - br.width) > 0.5;
|
|
13373
|
+
const heightChanged = Math.abs(newHeight - br.height) > 0.5;
|
|
13374
|
+
if (widthChanged || heightChanged) {
|
|
13375
|
+
const isTextWidth = obj instanceof fabric__namespace.Textbox && widthChanged && !heightChanged;
|
|
13376
|
+
if (isTextWidth) {
|
|
13377
|
+
obj.set({ width: Math.max(20, newWidth) });
|
|
13378
|
+
try {
|
|
13379
|
+
obj.initDimensions();
|
|
13380
|
+
} catch {
|
|
13381
|
+
}
|
|
13382
|
+
} else {
|
|
13383
|
+
const ratioX = widthChanged ? newWidth / br.width : 1;
|
|
13384
|
+
const ratioY = heightChanged ? newHeight / br.height : 1;
|
|
13385
|
+
const curSx = obj.scaleX ?? 1;
|
|
13386
|
+
const curSy = obj.scaleY ?? 1;
|
|
13387
|
+
obj.set({ scaleX: curSx * ratioX, scaleY: curSy * ratioY });
|
|
13388
|
+
}
|
|
13389
|
+
obj.setCoords();
|
|
13390
|
+
const after = obj.getBoundingRect();
|
|
13391
|
+
const dx = newLeft - after.left;
|
|
13392
|
+
const dy = newTop - after.top;
|
|
13393
|
+
if (Math.abs(dx) > 0.01 || Math.abs(dy) > 0.01) {
|
|
13394
|
+
obj.set({ left: (obj.left ?? 0) + dx, top: (obj.top ?? 0) + dy });
|
|
13395
|
+
obj.setCoords();
|
|
13396
|
+
}
|
|
13397
|
+
if (!xAlreadySnapped) {
|
|
13398
|
+
if (hasL) gridGuidesForScale.push({ type: "vertical", position: newLeft, kind: "grid" });
|
|
13399
|
+
else if (hasR) gridGuidesForScale.push({ type: "vertical", position: newLeft + newWidth, kind: "grid" });
|
|
13400
|
+
}
|
|
13401
|
+
if (!yAlreadySnapped) {
|
|
13402
|
+
if (hasT) gridGuidesForScale.push({ type: "horizontal", position: newTop, kind: "grid" });
|
|
13403
|
+
else if (hasB) gridGuidesForScale.push({ type: "horizontal", position: newTop + newHeight, kind: "grid" });
|
|
13404
|
+
}
|
|
13405
|
+
}
|
|
13406
|
+
}
|
|
13407
|
+
}
|
|
13408
|
+
}
|
|
13409
|
+
} catch {
|
|
13410
|
+
}
|
|
13411
|
+
setGuides(gridGuidesForScale.length ? [...scaleGuides, ...gridGuidesForScale] : scaleGuides);
|
|
11601
13412
|
});
|
|
11602
13413
|
fabricCanvas.on("object:resizing", (e) => {
|
|
11603
13414
|
if (!isActiveRef.current) return;
|
|
@@ -11623,13 +13434,70 @@ const PageCanvas = react.forwardRef(
|
|
|
11623
13434
|
}
|
|
11624
13435
|
const transform = e.transform;
|
|
11625
13436
|
const corner = (transform == null ? void 0 : transform.corner) || "";
|
|
13437
|
+
if (obj instanceof fabric__namespace.Textbox && (corner === "ml" || corner === "mr")) {
|
|
13438
|
+
const objId = getObjectId(obj);
|
|
13439
|
+
const sourceEl = objId ? elementsRef.current.find((el) => el.id === objId) : void 0;
|
|
13440
|
+
bakeTextboxScaleIntoTypography(obj, sourceEl);
|
|
13441
|
+
}
|
|
13442
|
+
snapDuringScaleCallback(obj, corner);
|
|
11626
13443
|
const scaleGuides = calculateScaleSnapGuidesCallback(obj, corner);
|
|
11627
|
-
|
|
13444
|
+
const gridGuidesForTextResize = [];
|
|
13445
|
+
try {
|
|
13446
|
+
const psGrid = projectSettingsRef.current;
|
|
13447
|
+
if (psGrid.snapToGrid && corner && obj instanceof fabric__namespace.Textbox && (corner === "ml" || corner === "mr")) {
|
|
13448
|
+
const gridX = psGrid.gridSizeX ?? psGrid.gridSize ?? 0;
|
|
13449
|
+
if (gridX > 0) {
|
|
13450
|
+
obj.setCoords();
|
|
13451
|
+
const br = obj.getBoundingRect();
|
|
13452
|
+
const xAlreadySnapped = scaleGuides.some((g) => g.type === "vertical");
|
|
13453
|
+
if (!xAlreadySnapped && br.width > 1) {
|
|
13454
|
+
const anchorRight = br.left + br.width;
|
|
13455
|
+
let newLeft = br.left;
|
|
13456
|
+
let newWidth = br.width;
|
|
13457
|
+
if (corner === "ml") {
|
|
13458
|
+
const nL = Math.round(br.left / gridX) * gridX;
|
|
13459
|
+
newWidth = Math.max(20, anchorRight - nL);
|
|
13460
|
+
newLeft = anchorRight - newWidth;
|
|
13461
|
+
} else {
|
|
13462
|
+
const nR = Math.round(anchorRight / gridX) * gridX;
|
|
13463
|
+
newWidth = Math.max(20, nR - br.left);
|
|
13464
|
+
}
|
|
13465
|
+
if (Math.abs(newWidth - br.width) > 0.5) {
|
|
13466
|
+
obj.set({ width: Math.max(20, newWidth) });
|
|
13467
|
+
try {
|
|
13468
|
+
obj.initDimensions();
|
|
13469
|
+
} catch {
|
|
13470
|
+
}
|
|
13471
|
+
obj.setCoords();
|
|
13472
|
+
const after = obj.getBoundingRect();
|
|
13473
|
+
const dx = newLeft - after.left;
|
|
13474
|
+
if (Math.abs(dx) > 0.01) {
|
|
13475
|
+
obj.set({ left: (obj.left ?? 0) + dx });
|
|
13476
|
+
obj.setCoords();
|
|
13477
|
+
}
|
|
13478
|
+
gridGuidesForTextResize.push({
|
|
13479
|
+
type: "vertical",
|
|
13480
|
+
position: corner === "ml" ? newLeft : newLeft + newWidth,
|
|
13481
|
+
kind: "grid"
|
|
13482
|
+
});
|
|
13483
|
+
}
|
|
13484
|
+
}
|
|
13485
|
+
}
|
|
13486
|
+
}
|
|
13487
|
+
} catch {
|
|
13488
|
+
}
|
|
13489
|
+
setGuides(gridGuidesForTextResize.length ? [...scaleGuides, ...gridGuidesForTextResize] : scaleGuides);
|
|
11628
13490
|
});
|
|
11629
13491
|
fabricCanvas.on("object:rotating", (e) => {
|
|
11630
13492
|
markSimpleTransform(e);
|
|
11631
13493
|
didTransformRef.current = true;
|
|
11632
13494
|
const tr = e.target;
|
|
13495
|
+
try {
|
|
13496
|
+
const getCursor = fabricCanvas.__pixldocsGetRotateCursor;
|
|
13497
|
+
const upper = fabricCanvas.upperCanvasEl;
|
|
13498
|
+
if (typeof getCursor === "function" && upper && tr) upper.style.cursor = getCursor(tr);
|
|
13499
|
+
} catch {
|
|
13500
|
+
}
|
|
11633
13501
|
const rotateTargetId = tr ? getObjectId(tr) : null;
|
|
11634
13502
|
if (rotateTargetId && rotateTargetId !== "__background__") {
|
|
11635
13503
|
preserveSelectionAfterTransformIdRef.current = rotateTargetId;
|
|
@@ -11656,6 +13524,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11656
13524
|
prepareGroupSelectionTransformStart(e.target);
|
|
11657
13525
|
markTransforming(e.target);
|
|
11658
13526
|
didTransformRef.current = true;
|
|
13527
|
+
if (e.target) e.target.__pixldocsDragMoved = true;
|
|
11659
13528
|
const moveTargetId = e.target ? getObjectId(e.target) : null;
|
|
11660
13529
|
if (moveTargetId && moveTargetId !== "__background__") {
|
|
11661
13530
|
preserveSelectionAfterTransformIdRef.current = moveTargetId;
|
|
@@ -11672,19 +13541,57 @@ const PageCanvas = react.forwardRef(
|
|
|
11672
13541
|
if (!obj) return;
|
|
11673
13542
|
const snapTarget = fabricCanvas.getActiveObject() ?? obj;
|
|
11674
13543
|
const { guides: newGuides, snapDx, snapDy } = calculateSnapGuidesCallback(snapTarget);
|
|
11675
|
-
|
|
11676
|
-
|
|
11677
|
-
|
|
13544
|
+
let finalDx = snapDx;
|
|
13545
|
+
let finalDy = snapDy;
|
|
13546
|
+
let mergedGuides = newGuides;
|
|
13547
|
+
const psLive = projectSettingsRef.current;
|
|
13548
|
+
const gridX = psLive.gridSizeX ?? psLive.gridSize ?? 0;
|
|
13549
|
+
const gridY = psLive.gridSizeY ?? psLive.gridSize ?? 0;
|
|
13550
|
+
if (psLive.snapToGrid && gridX > 0 && gridY > 0) {
|
|
13551
|
+
try {
|
|
13552
|
+
snapTarget.setCoords();
|
|
13553
|
+
} catch {
|
|
13554
|
+
}
|
|
13555
|
+
const br = snapTarget.getBoundingRect();
|
|
13556
|
+
const gridGuides = [];
|
|
13557
|
+
if (finalDx === 0) {
|
|
13558
|
+
const newLeft = Math.round(br.left / gridX) * gridX;
|
|
13559
|
+
finalDx = newLeft - br.left;
|
|
13560
|
+
gridGuides.push({ type: "vertical", position: newLeft, kind: "grid" });
|
|
13561
|
+
}
|
|
13562
|
+
if (finalDy === 0) {
|
|
13563
|
+
const newTop = Math.round(br.top / gridY) * gridY;
|
|
13564
|
+
finalDy = newTop - br.top;
|
|
13565
|
+
gridGuides.push({ type: "horizontal", position: newTop, kind: "grid" });
|
|
13566
|
+
}
|
|
13567
|
+
if (gridGuides.length) mergedGuides = [...newGuides, ...gridGuides];
|
|
13568
|
+
}
|
|
13569
|
+
setGuides(mergedGuides);
|
|
13570
|
+
setHoverBounds(null);
|
|
13571
|
+
if (finalDx !== 0 || finalDy !== 0) {
|
|
13572
|
+
snapTarget.set({ left: (snapTarget.left ?? 0) + finalDx, top: (snapTarget.top ?? 0) + finalDy });
|
|
11678
13573
|
}
|
|
11679
13574
|
});
|
|
11680
13575
|
let cropGroupSaveTimer = null;
|
|
11681
13576
|
fabricCanvas.on("object:modified", (e) => {
|
|
11682
|
-
var _a2,
|
|
13577
|
+
var _a2, _b2, _c, _d, _e, _f, _g;
|
|
11683
13578
|
try {
|
|
11684
13579
|
dragStarted = false;
|
|
11685
13580
|
setGuides([]);
|
|
11686
13581
|
setGroupOverlayLiveBoundsRef.current(null);
|
|
13582
|
+
objectResizeActiveSnapRef.current = null;
|
|
13583
|
+
groupResizeActiveSnapRef.current = null;
|
|
11687
13584
|
onDragEnd == null ? void 0 : onDragEnd();
|
|
13585
|
+
try {
|
|
13586
|
+
const t = e.target;
|
|
13587
|
+
if (t instanceof fabric__namespace.ActiveSelection) {
|
|
13588
|
+
for (const child of t.getObjects()) {
|
|
13589
|
+
delete child.__asLiveOrigW;
|
|
13590
|
+
delete child.__asLiveOrigH;
|
|
13591
|
+
}
|
|
13592
|
+
}
|
|
13593
|
+
} catch {
|
|
13594
|
+
}
|
|
11688
13595
|
lockEdits();
|
|
11689
13596
|
const modifiedTarget = e.target;
|
|
11690
13597
|
const modifiedTargetId = modifiedTarget ? getObjectId(modifiedTarget) : null;
|
|
@@ -11793,7 +13700,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11793
13700
|
useEditorStore.getState().reflowStackGroupInPage(pageId, groupId);
|
|
11794
13701
|
}
|
|
11795
13702
|
const stateAfter = useEditorStore.getState();
|
|
11796
|
-
const pageAfter = ((
|
|
13703
|
+
const pageAfter = ((_b2 = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
|
|
11797
13704
|
const groupNodeAfter = findNodeById(pageAfter, groupId);
|
|
11798
13705
|
if (groupNodeAfter) {
|
|
11799
13706
|
const abs = getAbsoluteBounds(groupNodeAfter, pageAfter);
|
|
@@ -11820,11 +13727,11 @@ const PageCanvas = react.forwardRef(
|
|
|
11820
13727
|
clearTimeout(cropGroupSaveTimer);
|
|
11821
13728
|
}
|
|
11822
13729
|
cropGroupSaveTimer = setTimeout(() => {
|
|
11823
|
-
var _a3,
|
|
13730
|
+
var _a3, _b3, _c2;
|
|
11824
13731
|
const { updateElement: updateElement2 } = useEditorStore.getState();
|
|
11825
13732
|
const img = ct._img;
|
|
11826
13733
|
const zoom3 = ((_a3 = img == null ? void 0 : img._ct) == null ? void 0 : _a3.zoom) ?? 1;
|
|
11827
|
-
const panX = ((
|
|
13734
|
+
const panX = ((_b3 = img == null ? void 0 : img._ct) == null ? void 0 : _b3.panX) ?? 0.5;
|
|
11828
13735
|
const panY = ((_c2 = img == null ? void 0 : img._ct) == null ? void 0 : _c2.panY) ?? 0.5;
|
|
11829
13736
|
const stateCrop = useEditorStore.getState();
|
|
11830
13737
|
const pageCrop = stateCrop.canvas.pages.find((p) => p.id === pageId);
|
|
@@ -11843,6 +13750,8 @@ const PageCanvas = react.forwardRef(
|
|
|
11843
13750
|
cropZoom: zoom3
|
|
11844
13751
|
}, { recordHistory: false });
|
|
11845
13752
|
active.__isInternalCropUpdate = false;
|
|
13753
|
+
installImageResizeControlsWithSnap(active);
|
|
13754
|
+
ensureCanvaControlRenders(active);
|
|
11846
13755
|
fabricCanvas.setActiveObject(active);
|
|
11847
13756
|
setTimeout(() => justModifiedIdsRef.current.delete(objId), 150);
|
|
11848
13757
|
}, 0);
|
|
@@ -12096,6 +14005,10 @@ const PageCanvas = react.forwardRef(
|
|
|
12096
14005
|
for (const obj of activeObjects) {
|
|
12097
14006
|
const objId = getObjectId(obj);
|
|
12098
14007
|
if (!objId || objId === "__background__") continue;
|
|
14008
|
+
const sourceElement = elementsRef.current.find((el) => el.id === objId);
|
|
14009
|
+
if (obj instanceof fabric__namespace.Textbox && !isActiveSelection) {
|
|
14010
|
+
bakeTextboxScaleIntoTypography(obj, sourceElement);
|
|
14011
|
+
}
|
|
12099
14012
|
let intrinsicWidth;
|
|
12100
14013
|
let intrinsicHeight;
|
|
12101
14014
|
if (obj instanceof fabric__namespace.Circle) {
|
|
@@ -12162,7 +14075,6 @@ const PageCanvas = react.forwardRef(
|
|
|
12162
14075
|
absoluteLeft = (absoluteLeft ?? 0) - w / 2;
|
|
12163
14076
|
absoluteTop = (absoluteTop ?? 0) - h / 2;
|
|
12164
14077
|
}
|
|
12165
|
-
const sourceElement = elementsRef.current.find((el) => el.id === objId);
|
|
12166
14078
|
const preserveCornerGeometry = (sourceElement == null ? void 0 : sourceElement.type) === "shape" && (sourceElement.shapeType === "circle" || sourceElement.shapeType === "rounded-rect" || sourceElement.shapeType === "triangle");
|
|
12167
14079
|
let finalWidth = intrinsicWidth;
|
|
12168
14080
|
let finalHeight = intrinsicHeight;
|
|
@@ -12248,17 +14160,35 @@ const PageCanvas = react.forwardRef(
|
|
|
12248
14160
|
finalHeight = 0;
|
|
12249
14161
|
finalScaleX = 1;
|
|
12250
14162
|
finalScaleY = 1;
|
|
14163
|
+
} else if (obj instanceof fabric__namespace.Textbox && isActiveSelection && (Math.abs((decomposed.scaleX ?? 1) - 1) > 1e-3 || Math.abs((decomposed.scaleY ?? 1) - 1) > 1e-3)) {
|
|
14164
|
+
const sx = Math.abs(decomposed.scaleX || 1);
|
|
14165
|
+
const sy = Math.abs(decomposed.scaleY || 1);
|
|
14166
|
+
const bakedWidth = Math.max(20, intrinsicWidth * sx);
|
|
14167
|
+
const bakedHeight = Math.max(1, intrinsicHeight * sy);
|
|
14168
|
+
finalWidth = bakedWidth;
|
|
14169
|
+
finalHeight = bakedHeight;
|
|
14170
|
+
finalScaleX = 1;
|
|
14171
|
+
finalScaleY = 1;
|
|
14172
|
+
try {
|
|
14173
|
+
obj.set({ width: bakedWidth, scaleX: 1, scaleY: 1 });
|
|
14174
|
+
obj.initDimensions();
|
|
14175
|
+
obj.setCoords();
|
|
14176
|
+
} catch {
|
|
14177
|
+
}
|
|
14178
|
+
finalAbsoluteMatrix = fabric__namespace.util.composeMatrix({
|
|
14179
|
+
translateX: decomposed.translateX,
|
|
14180
|
+
translateY: decomposed.translateY,
|
|
14181
|
+
angle: decomposed.angle ?? 0,
|
|
14182
|
+
scaleX: 1,
|
|
14183
|
+
scaleY: 1,
|
|
14184
|
+
skewX: 0,
|
|
14185
|
+
skewY: 0
|
|
14186
|
+
});
|
|
12251
14187
|
} else if (preserveCornerGeometry) {
|
|
12252
14188
|
const scaledW = Math.max(1, intrinsicWidth * Math.abs(decomposed.scaleX || 1));
|
|
12253
14189
|
const scaledH = Math.max(1, intrinsicHeight * Math.abs(decomposed.scaleY || 1));
|
|
12254
|
-
|
|
12255
|
-
|
|
12256
|
-
finalWidth = diameter;
|
|
12257
|
-
finalHeight = diameter;
|
|
12258
|
-
} else {
|
|
12259
|
-
finalWidth = scaledW;
|
|
12260
|
-
finalHeight = scaledH;
|
|
12261
|
-
}
|
|
14190
|
+
finalWidth = scaledW;
|
|
14191
|
+
finalHeight = scaledH;
|
|
12262
14192
|
finalScaleX = 1;
|
|
12263
14193
|
finalScaleY = 1;
|
|
12264
14194
|
obj.set({ scaleX: 1, scaleY: 1 });
|
|
@@ -12297,6 +14227,11 @@ const PageCanvas = react.forwardRef(
|
|
|
12297
14227
|
transformMatrix: finalAbsoluteMatrix
|
|
12298
14228
|
};
|
|
12299
14229
|
if (obj instanceof fabric__namespace.Textbox) {
|
|
14230
|
+
const bakedTextScaleUpdates = obj.__pixldocsBakedTextScaleUpdates;
|
|
14231
|
+
if (bakedTextScaleUpdates && typeof bakedTextScaleUpdates === "object") {
|
|
14232
|
+
Object.assign(elementUpdate, bakedTextScaleUpdates);
|
|
14233
|
+
delete obj.__pixldocsBakedTextScaleUpdates;
|
|
14234
|
+
}
|
|
12300
14235
|
const baked = obj.minBoxHeight;
|
|
12301
14236
|
if (typeof baked === "number" && baked > 0) {
|
|
12302
14237
|
elementUpdate.minBoxHeight = baked;
|
|
@@ -12405,7 +14340,7 @@ const PageCanvas = react.forwardRef(
|
|
|
12405
14340
|
}
|
|
12406
14341
|
});
|
|
12407
14342
|
fabricCanvas.on("mouse:dblclick", (e) => {
|
|
12408
|
-
var _a2,
|
|
14343
|
+
var _a2, _b2;
|
|
12409
14344
|
if (!isActiveRef.current || !allowEditing) return;
|
|
12410
14345
|
let target = e.target;
|
|
12411
14346
|
if (!target) {
|
|
@@ -12415,7 +14350,7 @@ const PageCanvas = react.forwardRef(
|
|
|
12415
14350
|
if (target && target instanceof fabric__namespace.Group && target.__cropGroup) {
|
|
12416
14351
|
const ct = target.__cropData;
|
|
12417
14352
|
const innerImg = ct == null ? void 0 : ct._img;
|
|
12418
|
-
const innerSrc = ((_a2 = innerImg == null ? void 0 : innerImg.getSrc) == null ? void 0 : _a2.call(innerImg)) || ((
|
|
14353
|
+
const innerSrc = ((_a2 = innerImg == null ? void 0 : innerImg.getSrc) == null ? void 0 : _a2.call(innerImg)) || ((_b2 = innerImg == null ? void 0 : innerImg._originalElement) == null ? void 0 : _b2.src) || (innerImg == null ? void 0 : innerImg.src) || "";
|
|
12419
14354
|
const isPlaceholder = !innerSrc || innerSrc === EMPTY_IMAGE_PLACEHOLDER_DATA_URL;
|
|
12420
14355
|
if (innerImg && !isPlaceholder && !isCropGroupInCropMode(target)) {
|
|
12421
14356
|
enterCropMode(target);
|
|
@@ -12594,13 +14529,13 @@ const PageCanvas = react.forwardRef(
|
|
|
12594
14529
|
visibilityUpdateInProgressRef.current = false;
|
|
12595
14530
|
}
|
|
12596
14531
|
doSyncRef.current = () => {
|
|
12597
|
-
var _a2,
|
|
14532
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
12598
14533
|
const shouldSkipUpdates2 = syncLockedRef.current || editLockRef.current;
|
|
12599
14534
|
const state = useEditorStore.getState();
|
|
12600
14535
|
const elementsToSync = elements;
|
|
12601
14536
|
elementsRef.current = elementsToSync;
|
|
12602
14537
|
const pageTree = isPreviewMode && (pageChildren == null ? void 0 : pageChildren.length) ? pageChildren ?? [] : ((_a2 = state.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
|
|
12603
|
-
const selectedIdsFromStore = new Set(((
|
|
14538
|
+
const selectedIdsFromStore = new Set(((_b2 = state.canvas) == null ? void 0 : _b2.selectedIds) ?? []);
|
|
12604
14539
|
isRebuildingRef.current = true;
|
|
12605
14540
|
const allElementIds = new Set(elementsToSync.map((el) => el.id));
|
|
12606
14541
|
const sectionGroups = pageTree.filter(
|
|
@@ -12627,7 +14562,8 @@ const PageCanvas = react.forwardRef(
|
|
|
12627
14562
|
const activeObj = fc.getActiveObject();
|
|
12628
14563
|
const activeObjId = activeObj ? getObjectId(activeObj) : null;
|
|
12629
14564
|
const isTextBeingEdited = activeObjId && editingTextIdRef.current === activeObjId;
|
|
12630
|
-
|
|
14565
|
+
const isMultiSelect = activeObj instanceof fabric__namespace.ActiveSelection;
|
|
14566
|
+
if (activeObj && isMultiSelect && !(((_c = activeObj._ct) == null ? void 0 : _c.isCropGroup) || activeObj.__cropGroup) && !isTextBeingEdited) {
|
|
12631
14567
|
fc.discardActiveObject();
|
|
12632
14568
|
}
|
|
12633
14569
|
}
|
|
@@ -12947,7 +14883,7 @@ const PageCanvas = react.forwardRef(
|
|
|
12947
14883
|
updateCoverLayout(existingObj);
|
|
12948
14884
|
applyEdgeFadeFrameClipPath(existingObj, element, ct.frameW, ct.frameH, ct.shape || "rect", ct.rx || 0);
|
|
12949
14885
|
if (allowEditing) {
|
|
12950
|
-
|
|
14886
|
+
installImageResizeControlsWithSnap(existingObj);
|
|
12951
14887
|
} else {
|
|
12952
14888
|
existingObj.set({
|
|
12953
14889
|
hasControls: false,
|
|
@@ -13029,7 +14965,7 @@ const PageCanvas = react.forwardRef(
|
|
|
13029
14965
|
hoverCursor: isDynamicField && isPreviewMode ? "pointer" : void 0
|
|
13030
14966
|
});
|
|
13031
14967
|
if (allowEditing) {
|
|
13032
|
-
|
|
14968
|
+
installImageResizeControlsWithSnap(existingObj);
|
|
13033
14969
|
}
|
|
13034
14970
|
existingObj.setCoords();
|
|
13035
14971
|
fc.requestRenderAll();
|
|
@@ -13755,7 +15691,7 @@ const PageCanvas = react.forwardRef(
|
|
|
13755
15691
|
return unsub;
|
|
13756
15692
|
}, []);
|
|
13757
15693
|
const updateFabricObject = (obj, element, skipPositionUpdate = false) => {
|
|
13758
|
-
var _a2,
|
|
15694
|
+
var _a2, _b2, _c;
|
|
13759
15695
|
const fc = fabricRef.current;
|
|
13760
15696
|
if (fc && isTransforming(fc)) {
|
|
13761
15697
|
return;
|
|
@@ -13823,11 +15759,12 @@ const PageCanvas = react.forwardRef(
|
|
|
13823
15759
|
// Disable rotation for crop groups (simplifies resize math)
|
|
13824
15760
|
hasRotatingPoint: false,
|
|
13825
15761
|
// Hide rotation handle
|
|
13826
|
-
//
|
|
13827
|
-
|
|
13828
|
-
|
|
15762
|
+
// Handles are drawn in screen-space — keep them constant on-screen.
|
|
15763
|
+
// Match the global Canva-style defaults (circular dots, pill sides).
|
|
15764
|
+
cornerSize: 10,
|
|
15765
|
+
borderScaleFactor: SELECTION_BORDER_SCALE,
|
|
13829
15766
|
transparentCorners: false,
|
|
13830
|
-
cornerStyle: "
|
|
15767
|
+
cornerStyle: "circle",
|
|
13831
15768
|
cornerColor: SELECTION_PRIMARY,
|
|
13832
15769
|
cornerStrokeColor: "#ffffff",
|
|
13833
15770
|
borderColor: SELECTION_PRIMARY,
|
|
@@ -13937,7 +15874,8 @@ const PageCanvas = react.forwardRef(
|
|
|
13937
15874
|
obj.clipPath.dirty = true;
|
|
13938
15875
|
obj.clipPath.setCoords();
|
|
13939
15876
|
}
|
|
13940
|
-
|
|
15877
|
+
installImageResizeControlsWithSnap(obj);
|
|
15878
|
+
ensureCanvaControlRenders(obj);
|
|
13941
15879
|
obj.set({
|
|
13942
15880
|
selectable: true,
|
|
13943
15881
|
evented: true,
|
|
@@ -14032,7 +15970,7 @@ const PageCanvas = react.forwardRef(
|
|
|
14032
15970
|
obj.setCoords();
|
|
14033
15971
|
}
|
|
14034
15972
|
if (!isLine) {
|
|
14035
|
-
const angleTextPathActive = isTextbox && ((
|
|
15973
|
+
const angleTextPathActive = isTextbox && ((_b2 = element.textPath) == null ? void 0 : _b2.preset) === "rise";
|
|
14036
15974
|
const appliedSkewY = angleTextPathActive ? 0 : element.skewY ?? 0;
|
|
14037
15975
|
let posIfNotSkipped = skipPositionUpdate ? {} : { left: fabricPos.left, top: fabricPos.top };
|
|
14038
15976
|
if (!skipPositionUpdate && (obj instanceof fabric__namespace.FabricImage && obj.originX === "center" || obj instanceof fabric__namespace.Group && obj.__cropGroup)) {
|
|
@@ -14109,7 +16047,17 @@ const PageCanvas = react.forwardRef(
|
|
|
14109
16047
|
objectCaching: true
|
|
14110
16048
|
});
|
|
14111
16049
|
} else if (obj instanceof fabric__namespace.Ellipse) {
|
|
14112
|
-
obj.set({
|
|
16050
|
+
obj.set({
|
|
16051
|
+
rx: cornerSafeW / 2,
|
|
16052
|
+
ry: cornerSafeH / 2,
|
|
16053
|
+
fill: element.fill || "transparent",
|
|
16054
|
+
stroke: element.stroke || "transparent",
|
|
16055
|
+
strokeWidth: element.strokeWidth || 0,
|
|
16056
|
+
strokeUniform: true,
|
|
16057
|
+
strokeLineJoin: "round",
|
|
16058
|
+
strokeLineCap: "round",
|
|
16059
|
+
objectCaching: true
|
|
16060
|
+
});
|
|
14113
16061
|
} else if (obj instanceof fabric__namespace.Textbox) {
|
|
14114
16062
|
const overflowPolicy = element.overflowPolicy || "grow-and-push";
|
|
14115
16063
|
let text = element.text || "Text";
|
|
@@ -14303,6 +16251,16 @@ const PageCanvas = react.forwardRef(
|
|
|
14303
16251
|
strokeUniform: true,
|
|
14304
16252
|
objectCaching: true
|
|
14305
16253
|
});
|
|
16254
|
+
} else if (obj instanceof fabric__namespace.Ellipse) {
|
|
16255
|
+
obj.set({
|
|
16256
|
+
rx: cornerSafeW / 2,
|
|
16257
|
+
ry: cornerSafeH / 2,
|
|
16258
|
+
fill: element.fill || "transparent",
|
|
16259
|
+
stroke: element.stroke || "transparent",
|
|
16260
|
+
strokeWidth: element.strokeWidth || 0,
|
|
16261
|
+
strokeUniform: true,
|
|
16262
|
+
objectCaching: true
|
|
16263
|
+
});
|
|
14306
16264
|
} else if (obj instanceof fabric__namespace.Rect && element.shapeType === "rounded-rect") {
|
|
14307
16265
|
const toRadius = (value, fallback) => Number.isFinite(value) ? Math.max(0, Number(value)) : fallback;
|
|
14308
16266
|
const baseRx = Math.max(0, Number(element.rx ?? 0));
|
|
@@ -14562,7 +16520,7 @@ const PageCanvas = react.forwardRef(
|
|
|
14562
16520
|
return Math.max(min, Math.min(max, v));
|
|
14563
16521
|
};
|
|
14564
16522
|
const applyEdgeFadeFrameClipPath = (group, element, frameW, frameH, shape, rxRatio) => {
|
|
14565
|
-
var _a2,
|
|
16523
|
+
var _a2, _b2, _c;
|
|
14566
16524
|
const fadeElement = element;
|
|
14567
16525
|
const fadeGroup = group;
|
|
14568
16526
|
const inputKey = edgeFadeKey(fadeElement);
|
|
@@ -14683,7 +16641,7 @@ const PageCanvas = react.forwardRef(
|
|
|
14683
16641
|
delete fadeGroup.__edgeFadeRenderConfig;
|
|
14684
16642
|
delete fadeGroup.__edgeFadeKey;
|
|
14685
16643
|
delete fadeGroup.__edgeFadeInputKey;
|
|
14686
|
-
if ((
|
|
16644
|
+
if ((_b2 = group.clipPath) == null ? void 0 : _b2.__edgeFadeMask) {
|
|
14687
16645
|
group.clipPath = void 0;
|
|
14688
16646
|
updateCoverLayout(group);
|
|
14689
16647
|
}
|
|
@@ -14700,7 +16658,7 @@ const PageCanvas = react.forwardRef(
|
|
|
14700
16658
|
(_c = group.canvas) == null ? void 0 : _c.requestRenderAll();
|
|
14701
16659
|
};
|
|
14702
16660
|
const loadImageAsync2 = async (element, placeholder, fc) => {
|
|
14703
|
-
var _a2,
|
|
16661
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
14704
16662
|
const imageUrl = element.src || element.imageUrl;
|
|
14705
16663
|
if (!imageUrl) return;
|
|
14706
16664
|
const elementId = element.id;
|
|
@@ -14731,7 +16689,7 @@ const PageCanvas = react.forwardRef(
|
|
|
14731
16689
|
await normalizeSvgImageDimensions(img, imageUrl, element.sourceFormat);
|
|
14732
16690
|
if (!isLatestRequest()) return;
|
|
14733
16691
|
const imageFitForFade = element.imageFit || ((_a2 = element.style) == null ? void 0 : _a2.imageFit) || "cover";
|
|
14734
|
-
const clipShapeForFade = element.clipShape ?? ((
|
|
16692
|
+
const clipShapeForFade = element.clipShape ?? ((_b2 = element.style) == null ? void 0 : _b2.imageFrameShape) ?? (isPreviewMode ? "rectangle" : "none");
|
|
14735
16693
|
const willUseCropGroupForFade = imageFitForFade !== "fill" || clipShapeForFade && clipShapeForFade !== "none";
|
|
14736
16694
|
try {
|
|
14737
16695
|
if (hasEdgeFade(element) && !willUseCropGroupForFade) {
|
|
@@ -14949,7 +16907,7 @@ const PageCanvas = react.forwardRef(
|
|
|
14949
16907
|
evented: canBeEvented && !isHidden
|
|
14950
16908
|
});
|
|
14951
16909
|
} else {
|
|
14952
|
-
|
|
16910
|
+
installImageResizeControlsWithSnap(cropGroup);
|
|
14953
16911
|
}
|
|
14954
16912
|
const cropImg = (_o = cropGroup.__cropData) == null ? void 0 : _o._img;
|
|
14955
16913
|
if (cropImg) {
|
|
@@ -15160,65 +17118,191 @@ const PageCanvas = react.forwardRef(
|
|
|
15160
17118
|
),
|
|
15161
17119
|
sectionsOverlay,
|
|
15162
17120
|
groupBoundsOverlay,
|
|
15163
|
-
guides.length
|
|
17121
|
+
hoverBounds && !guides.length && !(selectedIdsRef.current && selectedIdsRef.current.length) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
15164
17122
|
"svg",
|
|
15165
17123
|
{
|
|
15166
17124
|
className: "absolute inset-0 pointer-events-none",
|
|
15167
17125
|
style: { width: scaledWidth, height: scaledHeight },
|
|
15168
17126
|
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
15169
|
-
children:
|
|
15170
|
-
|
|
15171
|
-
|
|
15172
|
-
|
|
15173
|
-
|
|
15174
|
-
|
|
15175
|
-
|
|
15176
|
-
|
|
15177
|
-
|
|
15178
|
-
|
|
15179
|
-
|
|
15180
|
-
|
|
15181
|
-
|
|
15182
|
-
|
|
15183
|
-
|
|
15184
|
-
|
|
15185
|
-
|
|
15186
|
-
|
|
15187
|
-
|
|
15188
|
-
|
|
15189
|
-
|
|
15190
|
-
|
|
15191
|
-
|
|
15192
|
-
|
|
15193
|
-
|
|
15194
|
-
|
|
15195
|
-
|
|
15196
|
-
|
|
15197
|
-
|
|
15198
|
-
|
|
15199
|
-
|
|
15200
|
-
|
|
15201
|
-
|
|
15202
|
-
|
|
15203
|
-
|
|
15204
|
-
|
|
15205
|
-
|
|
15206
|
-
|
|
15207
|
-
|
|
15208
|
-
|
|
15209
|
-
|
|
15210
|
-
|
|
15211
|
-
|
|
15212
|
-
|
|
15213
|
-
|
|
15214
|
-
|
|
15215
|
-
|
|
15216
|
-
|
|
15217
|
-
|
|
15218
|
-
|
|
17127
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17128
|
+
"rect",
|
|
17129
|
+
{
|
|
17130
|
+
x: hoverBounds.left,
|
|
17131
|
+
y: hoverBounds.top,
|
|
17132
|
+
width: hoverBounds.width,
|
|
17133
|
+
height: hoverBounds.height,
|
|
17134
|
+
fill: "none",
|
|
17135
|
+
stroke: SELECTION_PRIMARY,
|
|
17136
|
+
strokeWidth: 2,
|
|
17137
|
+
vectorEffect: "non-scaling-stroke",
|
|
17138
|
+
strokeDasharray: "0",
|
|
17139
|
+
opacity: 1
|
|
17140
|
+
}
|
|
17141
|
+
)
|
|
17142
|
+
}
|
|
17143
|
+
),
|
|
17144
|
+
canvas.projectSettings.showGrid && (() => {
|
|
17145
|
+
const ps = canvas.projectSettings;
|
|
17146
|
+
const gx = Math.max(1, ps.gridSizeX ?? ps.gridSize ?? 0);
|
|
17147
|
+
const gy = Math.max(1, ps.gridSizeY ?? ps.gridSize ?? 0);
|
|
17148
|
+
if (gx <= 0 || gy <= 0) return null;
|
|
17149
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17150
|
+
"svg",
|
|
17151
|
+
{
|
|
17152
|
+
className: "absolute inset-0 pointer-events-none",
|
|
17153
|
+
style: { width: scaledWidth, height: scaledHeight },
|
|
17154
|
+
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
17155
|
+
children: [
|
|
17156
|
+
/* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17157
|
+
"pattern",
|
|
17158
|
+
{
|
|
17159
|
+
id: `pixldocs-grid-${pageId}`,
|
|
17160
|
+
width: gx,
|
|
17161
|
+
height: gy,
|
|
17162
|
+
patternUnits: "userSpaceOnUse",
|
|
17163
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17164
|
+
"path",
|
|
17165
|
+
{
|
|
17166
|
+
d: `M ${gx} 0 L 0 0 0 ${gy}`,
|
|
17167
|
+
fill: "none",
|
|
17168
|
+
stroke: ps.gridColor || "#0f172a",
|
|
17169
|
+
strokeWidth: 0.5,
|
|
17170
|
+
opacity: 0.22
|
|
17171
|
+
}
|
|
17172
|
+
)
|
|
17173
|
+
}
|
|
17174
|
+
) }),
|
|
17175
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { width: canvasWidth, height: canvasHeight, fill: `url(#pixldocs-grid-${pageId})` })
|
|
17176
|
+
]
|
|
17177
|
+
}
|
|
17178
|
+
);
|
|
17179
|
+
})(),
|
|
17180
|
+
guides.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17181
|
+
"svg",
|
|
17182
|
+
{
|
|
17183
|
+
className: "absolute inset-0 pointer-events-none",
|
|
17184
|
+
style: { width: scaledWidth, height: scaledHeight },
|
|
17185
|
+
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
17186
|
+
children: [
|
|
17187
|
+
(() => {
|
|
17188
|
+
const seenBoxes = /* @__PURE__ */ new Set();
|
|
17189
|
+
const boxes = [];
|
|
17190
|
+
for (const g of guides) {
|
|
17191
|
+
const list = g.targetBoundsList ?? (g.targetBounds ? [g.targetBounds] : []);
|
|
17192
|
+
for (const b of list) {
|
|
17193
|
+
const key = `${b.left.toFixed(1)}-${b.top.toFixed(1)}-${b.width.toFixed(1)}-${b.height.toFixed(1)}`;
|
|
17194
|
+
if (seenBoxes.has(key)) continue;
|
|
17195
|
+
seenBoxes.add(key);
|
|
17196
|
+
boxes.push(b);
|
|
17197
|
+
}
|
|
15219
17198
|
}
|
|
15220
|
-
|
|
15221
|
-
|
|
17199
|
+
return boxes.map((b, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
17200
|
+
"rect",
|
|
17201
|
+
{
|
|
17202
|
+
x: b.left,
|
|
17203
|
+
y: b.top,
|
|
17204
|
+
width: b.width,
|
|
17205
|
+
height: b.height,
|
|
17206
|
+
fill: "none",
|
|
17207
|
+
stroke: "#f43f5e",
|
|
17208
|
+
strokeWidth: 1.5,
|
|
17209
|
+
strokeDasharray: "4,3",
|
|
17210
|
+
opacity: 0.9,
|
|
17211
|
+
vectorEffect: "non-scaling-stroke"
|
|
17212
|
+
},
|
|
17213
|
+
`tb-${i}`
|
|
17214
|
+
));
|
|
17215
|
+
})(),
|
|
17216
|
+
(() => {
|
|
17217
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17218
|
+
return guides.filter((guide) => {
|
|
17219
|
+
if (guide.kind === "gap") return true;
|
|
17220
|
+
const key = `${guide.type}-${guide.position.toFixed(1)}`;
|
|
17221
|
+
if (seen.has(key)) return false;
|
|
17222
|
+
seen.add(key);
|
|
17223
|
+
return true;
|
|
17224
|
+
}).map((guide, i) => {
|
|
17225
|
+
if (guide.kind === "gap" && guide.gap != null && guide.start != null && guide.end != null) {
|
|
17226
|
+
const gapColor = "#ec4899";
|
|
17227
|
+
const label = `${guide.gap}`;
|
|
17228
|
+
const labelW2 = Math.max(22, label.length * 7 + 8);
|
|
17229
|
+
if (guide.type === "horizontal") {
|
|
17230
|
+
const y = guide.bracketAt ?? guide.position;
|
|
17231
|
+
const x1 = guide.start;
|
|
17232
|
+
const x2 = guide.end;
|
|
17233
|
+
const mid = (x1 + x2) / 2;
|
|
17234
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
17235
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1, y1: y, x2, y2: y, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17236
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1, y1: y - 4, x2: x1, y2: y + 4, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17237
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: x2, y1: y - 4, x2, y2: y + 4, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17238
|
+
/* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${mid}, ${y - 12})`, children: [
|
|
17239
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: -labelW2 / 2, y: -9, width: labelW2, height: 16, rx: 4, fill: gapColor }),
|
|
17240
|
+
/* @__PURE__ */ jsxRuntime.jsx("text", { x: 0, y: 3, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 600, children: label })
|
|
17241
|
+
] })
|
|
17242
|
+
] }, i);
|
|
17243
|
+
} else {
|
|
17244
|
+
const x = guide.bracketAt ?? guide.position;
|
|
17245
|
+
const y1 = guide.start;
|
|
17246
|
+
const y2 = guide.end;
|
|
17247
|
+
const mid = (y1 + y2) / 2;
|
|
17248
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
17249
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: x, y1, x2: x, y2, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17250
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: x - 4, y1, x2: x + 4, y2: y1, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17251
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: x - 4, y1: y2, x2: x + 4, y2, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17252
|
+
/* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x + 12}, ${mid})`, children: [
|
|
17253
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: -labelW2 / 2, y: -9, width: labelW2, height: 16, rx: 4, fill: gapColor }),
|
|
17254
|
+
/* @__PURE__ */ jsxRuntime.jsx("text", { x: 0, y: 3, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 600, children: label })
|
|
17255
|
+
] })
|
|
17256
|
+
] }, i);
|
|
17257
|
+
}
|
|
17258
|
+
}
|
|
17259
|
+
const isElementRelative = guide.start !== void 0 && guide.end !== void 0;
|
|
17260
|
+
const isActive2 = guide.active === true;
|
|
17261
|
+
const isGrid = guide.kind === "grid";
|
|
17262
|
+
const strokeColor = isGrid ? "#f59e0b" : isActive2 ? "#22c55e" : isElementRelative ? "#f43f5e" : "#ec4899";
|
|
17263
|
+
const strokeWidth = isGrid ? 1.75 : 1.75;
|
|
17264
|
+
const strokeDasharray = isGrid ? "2,3" : isActive2 ? "none" : isElementRelative ? "3,3" : "4,4";
|
|
17265
|
+
const showDistance = typeof guide.distance === "number";
|
|
17266
|
+
const labelText = showDistance ? String(Math.round(guide.distance)) : "";
|
|
17267
|
+
const labelW = Math.max(24, labelText.length * 7);
|
|
17268
|
+
if (guide.type === "vertical") {
|
|
17269
|
+
const padding = isElementRelative || isActive2 ? 20 : 0;
|
|
17270
|
+
const y1 = guide.start != null && guide.end != null ? Math.max(0, guide.start - padding) : 0;
|
|
17271
|
+
const y2 = guide.start != null && guide.end != null ? Math.min(canvasHeight, guide.end + padding) : canvasHeight;
|
|
17272
|
+
const labelY = guide.start != null && guide.end != null ? (guide.start + guide.end) / 2 : canvasHeight / 2;
|
|
17273
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
17274
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: guide.position, y1, x2: guide.position, y2, stroke: strokeColor, strokeWidth, strokeDasharray, vectorEffect: "non-scaling-stroke" }),
|
|
17275
|
+
isActive2 && /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: guide.position, cy: y2, r: 4, fill: "#22c55e", opacity: 0.9 }),
|
|
17276
|
+
isElementRelative && !isActive2 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
17277
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: guide.position, cy: y1, r: 2, fill: "#f43f5e" }),
|
|
17278
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: guide.position, cy: y2, r: 2, fill: "#f43f5e" })
|
|
17279
|
+
] }),
|
|
17280
|
+
showDistance && /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${guide.position + 6}, ${labelY})`, children: [
|
|
17281
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: -2, y: -9, width: labelW, height: 16, rx: 4, fill: "rgba(0,0,0,0.75)" }),
|
|
17282
|
+
/* @__PURE__ */ jsxRuntime.jsx("text", { x: labelW / 2 - 2, y: 4, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 500, children: labelText })
|
|
17283
|
+
] })
|
|
17284
|
+
] }, i);
|
|
17285
|
+
} else {
|
|
17286
|
+
const padding = isElementRelative || isActive2 ? 20 : 0;
|
|
17287
|
+
const x1 = guide.start != null && guide.end != null ? Math.max(0, guide.start - padding) : 0;
|
|
17288
|
+
const x2 = guide.start != null && guide.end != null ? Math.min(canvasWidth, guide.end + padding) : canvasWidth;
|
|
17289
|
+
const labelX = guide.start != null && guide.end != null ? (guide.start + guide.end) / 2 : canvasWidth / 2;
|
|
17290
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
17291
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1, y1: guide.position, x2, y2: guide.position, stroke: strokeColor, strokeWidth, strokeDasharray, vectorEffect: "non-scaling-stroke" }),
|
|
17292
|
+
isActive2 && /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x2, cy: guide.position, r: 4, fill: "#22c55e", opacity: 0.9 }),
|
|
17293
|
+
isElementRelative && !isActive2 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
17294
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x1, cy: guide.position, r: 2, fill: "#f43f5e" }),
|
|
17295
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x2, cy: guide.position, r: 2, fill: "#f43f5e" })
|
|
17296
|
+
] }),
|
|
17297
|
+
showDistance && /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${labelX}, ${guide.position - 10})`, children: [
|
|
17298
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: -2, y: -9, width: labelW, height: 16, rx: 4, fill: "rgba(0,0,0,0.75)" }),
|
|
17299
|
+
/* @__PURE__ */ jsxRuntime.jsx("text", { x: labelW / 2 - 2, y: 4, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 500, children: labelText })
|
|
17300
|
+
] })
|
|
17301
|
+
] }, i);
|
|
17302
|
+
}
|
|
17303
|
+
});
|
|
17304
|
+
})()
|
|
17305
|
+
]
|
|
15222
17306
|
}
|
|
15223
17307
|
),
|
|
15224
17308
|
gridResizeLabel && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -15354,13 +17438,13 @@ function PreviewCanvas({
|
|
|
15354
17438
|
onDynamicFieldClick,
|
|
15355
17439
|
onReady
|
|
15356
17440
|
}) {
|
|
15357
|
-
var _a2,
|
|
17441
|
+
var _a2, _b2, _c, _d, _e;
|
|
15358
17442
|
const canvasRef = react.useRef(null);
|
|
15359
17443
|
const containerRef = react.useRef(null);
|
|
15360
17444
|
const [containerWidth, setContainerWidth] = react.useState(0);
|
|
15361
17445
|
const [hoveredFieldId, setHoveredFieldId] = react.useState(null);
|
|
15362
17446
|
const page = (_a2 = config == null ? void 0 : config.pages) == null ? void 0 : _a2[pageIndex];
|
|
15363
|
-
const canvasWidth = ((
|
|
17447
|
+
const canvasWidth = ((_b2 = config == null ? void 0 : config.canvas) == null ? void 0 : _b2.width) || 612;
|
|
15364
17448
|
const canvasHeight = ((_c = config == null ? void 0 : config.canvas) == null ? void 0 : _c.height) || 792;
|
|
15365
17449
|
const elementToFieldMap = react.useMemo(
|
|
15366
17450
|
() => buildElementToFieldMap(config == null ? void 0 : config.dynamicFields),
|
|
@@ -15410,14 +17494,14 @@ function PreviewCanvas({
|
|
|
15410
17494
|
}
|
|
15411
17495
|
}, [elements]);
|
|
15412
17496
|
const pageSettings = react.useMemo(() => {
|
|
15413
|
-
var _a3,
|
|
17497
|
+
var _a3, _b3;
|
|
15414
17498
|
return {
|
|
15415
17499
|
backgroundColor: ((_a3 = page == null ? void 0 : page.settings) == null ? void 0 : _a3.backgroundColor) || "#ffffff",
|
|
15416
|
-
backgroundGradient: (
|
|
17500
|
+
backgroundGradient: (_b3 = page == null ? void 0 : page.settings) == null ? void 0 : _b3.backgroundGradient
|
|
15417
17501
|
};
|
|
15418
17502
|
}, [(_d = page == null ? void 0 : page.settings) == null ? void 0 : _d.backgroundColor, (_e = page == null ? void 0 : page.settings) == null ? void 0 : _e.backgroundGradient]);
|
|
15419
17503
|
const projectSettings = react.useMemo(() => {
|
|
15420
|
-
var _a3,
|
|
17504
|
+
var _a3, _b3, _c2;
|
|
15421
17505
|
const vars = ((_a3 = config.themeConfig) == null ? void 0 : _a3.variables) || {};
|
|
15422
17506
|
return {
|
|
15423
17507
|
showGrid: false,
|
|
@@ -15425,7 +17509,7 @@ function PreviewCanvas({
|
|
|
15425
17509
|
gridSize: 10,
|
|
15426
17510
|
snapToGuides: false,
|
|
15427
17511
|
snapThreshold: 5,
|
|
15428
|
-
primaryColor: (
|
|
17512
|
+
primaryColor: (_b3 = vars.primary) == null ? void 0 : _b3.value,
|
|
15429
17513
|
secondaryColor: (_c2 = vars.secondary) == null ? void 0 : _c2.value
|
|
15430
17514
|
};
|
|
15431
17515
|
}, [config.themeConfig]);
|
|
@@ -15577,7 +17661,7 @@ const PreviewCanvas$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
|
|
|
15577
17661
|
PreviewCanvas
|
|
15578
17662
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
15579
17663
|
function applyThemeToConfig(config, themeOverrides) {
|
|
15580
|
-
var _a2,
|
|
17664
|
+
var _a2, _b2, _c;
|
|
15581
17665
|
if (!themeOverrides || Object.keys(themeOverrides).length === 0) return config;
|
|
15582
17666
|
const cloned = JSON.parse(JSON.stringify(config));
|
|
15583
17667
|
if ((_a2 = cloned.themeConfig) == null ? void 0 : _a2.variables) {
|
|
@@ -15588,7 +17672,7 @@ function applyThemeToConfig(config, themeOverrides) {
|
|
|
15588
17672
|
}
|
|
15589
17673
|
}
|
|
15590
17674
|
const varMap = /* @__PURE__ */ new Map();
|
|
15591
|
-
if ((
|
|
17675
|
+
if ((_b2 = cloned.themeConfig) == null ? void 0 : _b2.variables) {
|
|
15592
17676
|
for (const [key, def] of Object.entries(cloned.themeConfig.variables)) {
|
|
15593
17677
|
varMap.set(key, themeOverrides[key] ?? def.value);
|
|
15594
17678
|
}
|
|
@@ -15625,7 +17709,7 @@ function mapFormDefFieldType(t) {
|
|
|
15625
17709
|
function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
15626
17710
|
const sections = [];
|
|
15627
17711
|
function convert(defs, parentId) {
|
|
15628
|
-
var _a2,
|
|
17712
|
+
var _a2, _b2;
|
|
15629
17713
|
for (const def of defs) {
|
|
15630
17714
|
const isRepeatable = def.repeatable === true || def.type === "repeatable";
|
|
15631
17715
|
const defFields = def.fields ?? def.entryFields ?? [];
|
|
@@ -15677,7 +17761,7 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
15677
17761
|
placeholder: f.placeholder
|
|
15678
17762
|
}))
|
|
15679
17763
|
});
|
|
15680
|
-
if ((
|
|
17764
|
+
if ((_b2 = def.children) == null ? void 0 : _b2.length) {
|
|
15681
17765
|
convert(def.children, def.id);
|
|
15682
17766
|
}
|
|
15683
17767
|
}
|
|
@@ -16306,7 +18390,7 @@ function findAllRepeatableElementsBySourceId(pages, baseNodeId, oneBasedIndex, s
|
|
|
16306
18390
|
return out;
|
|
16307
18391
|
}
|
|
16308
18392
|
function findNestedRepeatableElementBySourceId(pages, parentBaseNodeId, parentPi, childBaseNodeId, childCi, sourceElementId) {
|
|
16309
|
-
var _a2,
|
|
18393
|
+
var _a2, _b2;
|
|
16310
18394
|
const parentGroups = collectGroupsByBaseId(pages, parentBaseNodeId);
|
|
16311
18395
|
const parentGroup = parentGroups[parentPi - 1];
|
|
16312
18396
|
if (!parentGroup || !isGroup(parentGroup) || !((_a2 = parentGroup.children) == null ? void 0 : _a2.length)) return void 0;
|
|
@@ -16321,7 +18405,7 @@ function findNestedRepeatableElementBySourceId(pages, parentBaseNodeId, parentPi
|
|
|
16321
18405
|
}
|
|
16322
18406
|
collectChild(parentGroup.children);
|
|
16323
18407
|
const childGroup = childGroups[childCi - 1];
|
|
16324
|
-
if (!childGroup || !isGroup(childGroup) || !((
|
|
18408
|
+
if (!childGroup || !isGroup(childGroup) || !((_b2 = childGroup.children) == null ? void 0 : _b2.length)) return void 0;
|
|
16325
18409
|
return findElementBySourceIdInSubtree(childGroup.children, sourceElementId) ?? (childGroup.__sourceId === sourceElementId ? childGroup.id : void 0);
|
|
16326
18410
|
}
|
|
16327
18411
|
function repeatableLabelKey(label) {
|
|
@@ -16371,7 +18455,7 @@ function getRepeatableFromConfig(pages) {
|
|
|
16371
18455
|
var _a2;
|
|
16372
18456
|
const result = [];
|
|
16373
18457
|
function walk(children) {
|
|
16374
|
-
var _a3,
|
|
18458
|
+
var _a3, _b2;
|
|
16375
18459
|
if (!children) return;
|
|
16376
18460
|
for (const node of children) {
|
|
16377
18461
|
if (isGroup(node) && isVerticalStackLayoutMode(node.layoutMode) && ((_a3 = node.children) == null ? void 0 : _a3.length)) {
|
|
@@ -16380,7 +18464,7 @@ function getRepeatableFromConfig(pages) {
|
|
|
16380
18464
|
if (rep == null ? void 0 : rep.label) result.push({ nodeId: child.id, label: rep.label });
|
|
16381
18465
|
}
|
|
16382
18466
|
}
|
|
16383
|
-
if (isGroup(node) && ((
|
|
18467
|
+
if (isGroup(node) && ((_b2 = node.children) == null ? void 0 : _b2.length)) walk(node.children);
|
|
16384
18468
|
}
|
|
16385
18469
|
}
|
|
16386
18470
|
for (const page of pages) if ((_a2 = page.children) == null ? void 0 : _a2.length) walk(page.children);
|
|
@@ -16396,7 +18480,7 @@ function findRepeatableByNodeIds(pages, nodeIds) {
|
|
|
16396
18480
|
return !!((_a3 = n.repeatableSection) == null ? void 0 : _a3.label);
|
|
16397
18481
|
};
|
|
16398
18482
|
function walk(children, parentRepeatableBaseId, parentInfo, parentRepeatableEntryIndex) {
|
|
16399
|
-
var _a3,
|
|
18483
|
+
var _a3, _b2;
|
|
16400
18484
|
if (!Array.isArray(children)) return;
|
|
16401
18485
|
for (let i = 0; i < children.length; i++) {
|
|
16402
18486
|
const node = children[i];
|
|
@@ -16439,7 +18523,7 @@ function findRepeatableByNodeIds(pages, nodeIds) {
|
|
|
16439
18523
|
if (isGroup(child) && Array.isArray(child.children)) walk(child.children, effectiveChildBase, void 0, childEntryIndex);
|
|
16440
18524
|
j += count;
|
|
16441
18525
|
}
|
|
16442
|
-
} else if (isGroup(node) && ((
|
|
18526
|
+
} else if (isGroup(node) && ((_b2 = node.children) == null ? void 0 : _b2.length)) {
|
|
16443
18527
|
const nodeBase = baseId(node.id);
|
|
16444
18528
|
const selfMatch = schemaBaseIds.has(node.id) || schemaBaseIds.has(nodeBase) || node.__baseNodeId != null && schemaBaseIds.has(node.__baseNodeId);
|
|
16445
18529
|
const isSelfRepeatable = selfMatch && hasRepeatableSection(node);
|
|
@@ -16528,7 +18612,7 @@ function getNestedRepeatableEntryCount(parentId, parentIndex, childId, formValue
|
|
|
16528
18612
|
return Math.max(1, maxIndex);
|
|
16529
18613
|
}
|
|
16530
18614
|
function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsFromSchema, repeatableEntryCounts, repeatableNestedEntryCounts, displayFormatMap, repeatablePagesFromSchema) {
|
|
16531
|
-
var _a2,
|
|
18615
|
+
var _a2, _b2, _c;
|
|
16532
18616
|
const cloned = JSON.parse(JSON.stringify(config));
|
|
16533
18617
|
if (!cloned.pages) return cloned;
|
|
16534
18618
|
const dynamicFields = cloned.dynamicFields;
|
|
@@ -16709,7 +18793,7 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
|
|
|
16709
18793
|
const { node, baseNodeId, startIndex, count } = block;
|
|
16710
18794
|
const occIdx = block.__occurrenceIndex ?? 1;
|
|
16711
18795
|
const N = computeN(baseNodeId, node.id);
|
|
16712
|
-
const entryFilter = ((
|
|
18796
|
+
const entryFilter = ((_b2 = node.repeatableSection) == null ? void 0 : _b2.entryFilter) ?? entryFilterFromList(baseNodeId);
|
|
16713
18797
|
let entryIndices;
|
|
16714
18798
|
if (entryFilter && entryFilter.mode === "range" && entryFilter.range) {
|
|
16715
18799
|
const parsed = parseEntryRange(entryFilter.range, N, entryMetaFromList(baseNodeId));
|
|
@@ -17166,7 +19250,7 @@ function findAllFlowStacks(pageChildren) {
|
|
|
17166
19250
|
return result;
|
|
17167
19251
|
}
|
|
17168
19252
|
function findNestedFlowStack(entry) {
|
|
17169
|
-
var _a2,
|
|
19253
|
+
var _a2, _b2;
|
|
17170
19254
|
const queue = [...entry.children ?? []];
|
|
17171
19255
|
while (queue.length > 0) {
|
|
17172
19256
|
const node = queue.shift();
|
|
@@ -17174,7 +19258,7 @@ function findNestedFlowStack(entry) {
|
|
|
17174
19258
|
const g = node;
|
|
17175
19259
|
const hasRepeatableChildren = ((_a2 = g.children) == null ? void 0 : _a2.length) && (g.children.some(hasBaseNodeId) || g.children.some((c) => isGroup(c)));
|
|
17176
19260
|
if (isVerticalStackLayoutMode(g.layoutMode) && hasRepeatableChildren) return g;
|
|
17177
|
-
if ((
|
|
19261
|
+
if ((_b2 = g.children) == null ? void 0 : _b2.length) queue.push(...g.children);
|
|
17178
19262
|
}
|
|
17179
19263
|
return null;
|
|
17180
19264
|
}
|
|
@@ -17305,9 +19389,9 @@ function splitNestedForOverflow(flowStack, stayChildren, overflowChildren, overf
|
|
|
17305
19389
|
return { stayChildren: newStay, overflowChildren: newOverflow };
|
|
17306
19390
|
}
|
|
17307
19391
|
function paginateSinglePage(sourcePage, pageOffsetIndex) {
|
|
17308
|
-
var _a2,
|
|
19392
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
17309
19393
|
const contentTop = (_a2 = sourcePage.settings) == null ? void 0 : _a2.contentTop;
|
|
17310
|
-
const contentBottom = (
|
|
19394
|
+
const contentBottom = (_b2 = sourcePage.settings) == null ? void 0 : _b2.contentBottom;
|
|
17311
19395
|
if (contentTop == null || contentBottom == null || contentBottom <= contentTop) {
|
|
17312
19396
|
return [sourcePage];
|
|
17313
19397
|
}
|
|
@@ -18497,7 +20581,7 @@ function splitIntoRuns(text, mainSupportsChar) {
|
|
|
18497
20581
|
return runs;
|
|
18498
20582
|
}
|
|
18499
20583
|
function rewriteSvgFontsForJsPDF(svgStr) {
|
|
18500
|
-
var _a2,
|
|
20584
|
+
var _a2, _b2;
|
|
18501
20585
|
const parser = new DOMParser();
|
|
18502
20586
|
const doc = parser.parseFromString(svgStr, "image/svg+xml");
|
|
18503
20587
|
const allTextEls = Array.from(doc.querySelectorAll("text, tspan, textPath"));
|
|
@@ -18602,7 +20686,7 @@ function rewriteSvgFontsForJsPDF(svgStr) {
|
|
|
18602
20686
|
for (const node of childNodes) {
|
|
18603
20687
|
if (node.nodeType !== 3 || !node.textContent) continue;
|
|
18604
20688
|
const runs = splitIntoRuns(node.textContent, mainSupportsChar);
|
|
18605
|
-
if (runs.length <= 1 && ((
|
|
20689
|
+
if (runs.length <= 1 && ((_b2 = runs[0]) == null ? void 0 : _b2.runType) === "main") continue;
|
|
18606
20690
|
const fragment = doc.createDocumentFragment();
|
|
18607
20691
|
for (const run of runs) {
|
|
18608
20692
|
const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan");
|
|
@@ -18912,9 +20996,9 @@ function appendDataUriFontFaceRule(family, weight, style, dataUri) {
|
|
|
18912
20996
|
styleEl.appendChild(document.createTextNode(cssText));
|
|
18913
20997
|
}
|
|
18914
20998
|
function resolveHarnessFontProxyUrl() {
|
|
18915
|
-
var _a2,
|
|
20999
|
+
var _a2, _b2;
|
|
18916
21000
|
try {
|
|
18917
|
-
const runtimeBase = typeof window !== "undefined" && (window.__PIXLDOCS_SUPABASE_URL || ((_a2 = window.__CONFIG__) == null ? void 0 : _a2.supabaseUrl)) || typeof globalThis !== "undefined" && (globalThis.__PIXLDOCS_SUPABASE_URL || ((
|
|
21001
|
+
const runtimeBase = typeof window !== "undefined" && (window.__PIXLDOCS_SUPABASE_URL || ((_a2 = window.__CONFIG__) == null ? void 0 : _a2.supabaseUrl)) || typeof globalThis !== "undefined" && (globalThis.__PIXLDOCS_SUPABASE_URL || ((_b2 = globalThis.__CONFIG__) == null ? void 0 : _b2.supabaseUrl)) || "";
|
|
18918
21002
|
const base = String(runtimeBase || "").replace(/\/$/, "");
|
|
18919
21003
|
return base ? `${base}/functions/v1/font-proxy` : "";
|
|
18920
21004
|
} catch {
|
|
@@ -19576,7 +21660,7 @@ async function resolveTemplateData(options) {
|
|
|
19576
21660
|
};
|
|
19577
21661
|
}
|
|
19578
21662
|
async function resolveFromForm(options) {
|
|
19579
|
-
var _a2,
|
|
21663
|
+
var _a2, _b2, _c;
|
|
19580
21664
|
const { templateId, formSchemaId, sectionState, flatFormData: directFlatFormData, themeId, supabaseUrl, supabaseAnonKey, prefetched } = options;
|
|
19581
21665
|
const hasSectionStateInput = !!sectionState && Object.keys(sectionState).length > 0;
|
|
19582
21666
|
if (!formSchemaId && !hasSectionStateInput) {
|
|
@@ -19626,7 +21710,7 @@ async function resolveFromForm(options) {
|
|
|
19626
21710
|
inferredSections = inferFormSchemaFromTemplate(
|
|
19627
21711
|
templateConfig.dynamicFields,
|
|
19628
21712
|
groups,
|
|
19629
|
-
((
|
|
21713
|
+
((_b2 = templateConfig.pages) == null ? void 0 : _b2.length) ? { pages: templateConfig.pages } : void 0
|
|
19630
21714
|
);
|
|
19631
21715
|
} else {
|
|
19632
21716
|
inferredSections = [];
|
|
@@ -19813,10 +21897,10 @@ function themeBaseId(id) {
|
|
|
19813
21897
|
return out;
|
|
19814
21898
|
}
|
|
19815
21899
|
function applyThemeVariantToConfig(config, themeConfig, themeId) {
|
|
19816
|
-
var _a2,
|
|
21900
|
+
var _a2, _b2, _c, _d;
|
|
19817
21901
|
if (!themeConfig) return config;
|
|
19818
21902
|
const variant = themeId && themeId !== "default" ? (_a2 = themeConfig.variants) == null ? void 0 : _a2.find((v) => v.id === themeId) : null;
|
|
19819
|
-
const shouldApplyDefaults = !variant && ((
|
|
21903
|
+
const shouldApplyDefaults = !variant && ((_b2 = themeConfig.properties) == null ? void 0 : _b2.length);
|
|
19820
21904
|
if (!variant && !shouldApplyDefaults) return config;
|
|
19821
21905
|
if (!((_c = themeConfig.properties) == null ? void 0 : _c.length)) return config;
|
|
19822
21906
|
const result = JSON.parse(JSON.stringify(config));
|
|
@@ -19837,8 +21921,8 @@ function applyThemeVariantToConfig(config, themeConfig, themeId) {
|
|
|
19837
21921
|
if (stopMatch) {
|
|
19838
21922
|
const stopIndex = parseInt(stopMatch[1], 10);
|
|
19839
21923
|
result.pages.forEach((p) => {
|
|
19840
|
-
var _a3,
|
|
19841
|
-
if ((
|
|
21924
|
+
var _a3, _b3;
|
|
21925
|
+
if ((_b3 = (_a3 = p.settings.backgroundGradient) == null ? void 0 : _a3.stops) == null ? void 0 : _b3[stopIndex]) {
|
|
19842
21926
|
p.settings.backgroundGradient = {
|
|
19843
21927
|
...p.settings.backgroundGradient,
|
|
19844
21928
|
stops: p.settings.backgroundGradient.stops.map(
|
|
@@ -19915,7 +21999,7 @@ function normalizeLayoutModes(config) {
|
|
|
19915
21999
|
}
|
|
19916
22000
|
}
|
|
19917
22001
|
function paintRepeatableSections(config, repeatableSections, formSchema) {
|
|
19918
|
-
var _a2,
|
|
22002
|
+
var _a2, _b2;
|
|
19919
22003
|
const pages = config.pages ?? [];
|
|
19920
22004
|
const entryFilters = (formSchema == null ? void 0 : formSchema.entryFilters) ?? [];
|
|
19921
22005
|
const entryFilterBases = new Set(entryFilters.map((f) => baseId(f.nodeId)));
|
|
@@ -19943,7 +22027,7 @@ function paintRepeatableSections(config, repeatableSections, formSchema) {
|
|
|
19943
22027
|
return painted;
|
|
19944
22028
|
}
|
|
19945
22029
|
for (const section of repeatableSections) {
|
|
19946
|
-
const inlineRange = ((_a2 = section.entryFilter) == null ? void 0 : _a2.mode) === "range" ? (
|
|
22030
|
+
const inlineRange = ((_a2 = section.entryFilter) == null ? void 0 : _a2.mode) === "range" ? (_b2 = section.entryFilter.range) == null ? void 0 : _b2.trim() : void 0;
|
|
19947
22031
|
const shouldUseInlineFilter = !!inlineRange && !entryFilterBases.has(baseId(section.nodeId));
|
|
19948
22032
|
const payload = { label: section.label };
|
|
19949
22033
|
if (section.minEntries !== void 0) payload.minEntries = section.minEntries;
|
|
@@ -19979,7 +22063,7 @@ function paintRepeatableSections(config, repeatableSections, formSchema) {
|
|
|
19979
22063
|
}
|
|
19980
22064
|
}
|
|
19981
22065
|
async function getTemplateForm(options) {
|
|
19982
|
-
var _a2,
|
|
22066
|
+
var _a2, _b2;
|
|
19983
22067
|
const { templateId, supabaseUrl, supabaseAnonKey } = options;
|
|
19984
22068
|
if (!supabaseUrl || !supabaseAnonKey) {
|
|
19985
22069
|
throw new Error("[getTemplateForm] supabaseUrl and supabaseAnonKey are required");
|
|
@@ -20023,7 +22107,7 @@ async function getTemplateForm(options) {
|
|
|
20023
22107
|
sections = inferFormSchemaFromTemplate(
|
|
20024
22108
|
templateConfig.dynamicFields,
|
|
20025
22109
|
templateConfig.fieldGroups || [],
|
|
20026
|
-
((
|
|
22110
|
+
((_b2 = templateConfig.pages) == null ? void 0 : _b2.length) ? { pages: templateConfig.pages } : void 0
|
|
20027
22111
|
);
|
|
20028
22112
|
} else {
|
|
20029
22113
|
sections = [];
|
|
@@ -20407,7 +22491,7 @@ function computeFrostedBoundsForPage(config, pageIndex, extraBaseIds, extraExact
|
|
|
20407
22491
|
return out;
|
|
20408
22492
|
}
|
|
20409
22493
|
function PixldocsPreview(props) {
|
|
20410
|
-
var _a2,
|
|
22494
|
+
var _a2, _b2;
|
|
20411
22495
|
const {
|
|
20412
22496
|
pageIndex = 0,
|
|
20413
22497
|
zoom = 1,
|
|
@@ -20475,10 +22559,10 @@ function PixldocsPreview(props) {
|
|
|
20475
22559
|
supabaseUrl: p.supabaseUrl,
|
|
20476
22560
|
supabaseAnonKey: p.supabaseAnonKey
|
|
20477
22561
|
}).then((resolved) => {
|
|
20478
|
-
var _a3,
|
|
22562
|
+
var _a3, _b3;
|
|
20479
22563
|
if (!cancelled) {
|
|
20480
22564
|
console.log(PREVIEW_DEBUG_PREFIX, "resolve-done", {
|
|
20481
|
-
pages: ((
|
|
22565
|
+
pages: ((_b3 = (_a3 = resolved.config) == null ? void 0 : _a3.pages) == null ? void 0 : _b3.length) ?? 0,
|
|
20482
22566
|
underlinedNodes: countUnderlinedNodes(resolved.config)
|
|
20483
22567
|
});
|
|
20484
22568
|
setResolvedConfig(resolved.config);
|
|
@@ -20588,7 +22672,7 @@ function PixldocsPreview(props) {
|
|
|
20588
22672
|
const satPct = (frostedBlurOptions == null ? void 0 : frostedBlurOptions.saturatePct) ?? 130;
|
|
20589
22673
|
const bgTint = (frostedBlurOptions == null ? void 0 : frostedBlurOptions.background) ?? "rgba(255,255,255,0.12)";
|
|
20590
22674
|
const canvasW = getNum((_a2 = config == null ? void 0 : config.canvas) == null ? void 0 : _a2.width, 0);
|
|
20591
|
-
const canvasH = getNum((
|
|
22675
|
+
const canvasH = getNum((_b2 = config == null ? void 0 : config.canvas) == null ? void 0 : _b2.height, 0);
|
|
20592
22676
|
const hasOverlays = frostedBounds.length > 0 && canvasW > 0 && canvasH > 0;
|
|
20593
22677
|
if (isLoading) {
|
|
20594
22678
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...style, position: "relative", minHeight: 200, display: "flex", alignItems: "center", justifyContent: "center" }, children: loadingFallback ?? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) });
|
|
@@ -20729,7 +22813,7 @@ function ensureFabricGradientDef(doc, obj, width, height) {
|
|
|
20729
22813
|
return `url(#${id})`;
|
|
20730
22814
|
}
|
|
20731
22815
|
function warpTextboxSvgAlongPath(svg, obj) {
|
|
20732
|
-
var _a2,
|
|
22816
|
+
var _a2, _b2, _c, _d, _e;
|
|
20733
22817
|
const tp = obj == null ? void 0 : obj.textPath;
|
|
20734
22818
|
if (!tp || !tp.preset || tp.preset === "none") return svg;
|
|
20735
22819
|
if (tp.preset === "rise" || tp.preset === "angle") {
|
|
@@ -20793,7 +22877,7 @@ function warpTextboxSvgAlongPath(svg, obj) {
|
|
|
20793
22877
|
}
|
|
20794
22878
|
for (const clone of Array.from(doc.querySelectorAll("g.__pdTextShadowClone"))) {
|
|
20795
22879
|
try {
|
|
20796
|
-
(
|
|
22880
|
+
(_b2 = clone.parentNode) == null ? void 0 : _b2.removeChild(clone);
|
|
20797
22881
|
} catch {
|
|
20798
22882
|
}
|
|
20799
22883
|
}
|
|
@@ -20813,9 +22897,9 @@ function warpTextboxSvgAlongPath(svg, obj) {
|
|
|
20813
22897
|
const fw = obj.fontWeight ?? 400;
|
|
20814
22898
|
const fst = obj.fontStyle || "normal";
|
|
20815
22899
|
const readFill = (el) => {
|
|
20816
|
-
var _a3,
|
|
22900
|
+
var _a3, _b3;
|
|
20817
22901
|
if (!el) return "";
|
|
20818
|
-
return el.getAttribute("fill") || ((
|
|
22902
|
+
return el.getAttribute("fill") || ((_b3 = (_a3 = (el.getAttribute("style") || "").match(/(?:^|;)\s*fill\s*:\s*([^;]+)/i)) == null ? void 0 : _a3[1]) == null ? void 0 : _b3.trim()) || "";
|
|
20819
22903
|
};
|
|
20820
22904
|
const w = Number(obj.width) || 0;
|
|
20821
22905
|
const h = Number(obj.height) || 0;
|
|
@@ -21168,9 +23252,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
21168
23252
|
}
|
|
21169
23253
|
return svgString;
|
|
21170
23254
|
}
|
|
21171
|
-
const resolvedPackageVersion = "0.5.
|
|
23255
|
+
const resolvedPackageVersion = "0.5.242";
|
|
21172
23256
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
21173
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
23257
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.242";
|
|
21174
23258
|
const roundParityValue = (value) => {
|
|
21175
23259
|
if (typeof value !== "number") return value;
|
|
21176
23260
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -21347,11 +23431,11 @@ function installUnderlineFix(fab) {
|
|
|
21347
23431
|
if (!TextProto || typeof TextProto._renderTextDecoration !== "function") return;
|
|
21348
23432
|
const original = TextProto._renderTextDecoration;
|
|
21349
23433
|
const measureLineTextWidth = (obj, ctx, lineIndex) => {
|
|
21350
|
-
var _a3,
|
|
23434
|
+
var _a3, _b2, _c, _d, _e, _f;
|
|
21351
23435
|
const rawLine = (_a3 = obj._textLines) == null ? void 0 : _a3[lineIndex];
|
|
21352
23436
|
const lineText = Array.isArray(rawLine) ? rawLine.join("") : String(rawLine ?? "");
|
|
21353
23437
|
if (!lineText) return 0;
|
|
21354
|
-
const fontSize = Number(((
|
|
23438
|
+
const fontSize = Number(((_b2 = obj.getValueOfPropertyAt) == null ? void 0 : _b2.call(obj, lineIndex, 0, "fontSize")) ?? obj.fontSize ?? 0);
|
|
21355
23439
|
const fontStyle = String(((_c = obj.getValueOfPropertyAt) == null ? void 0 : _c.call(obj, lineIndex, 0, "fontStyle")) ?? obj.fontStyle ?? "normal");
|
|
21356
23440
|
const fontWeight = String(((_d = obj.getValueOfPropertyAt) == null ? void 0 : _d.call(obj, lineIndex, 0, "fontWeight")) ?? obj.fontWeight ?? "400");
|
|
21357
23441
|
const fontFamily = String(((_e = obj.getValueOfPropertyAt) == null ? void 0 : _e.call(obj, lineIndex, 0, "fontFamily")) ?? obj.fontFamily ?? "sans-serif");
|
|
@@ -21491,11 +23575,78 @@ function installTextboxBoxExtensions(fab) {
|
|
|
21491
23575
|
if (Array.isArray(stateProps2)) {
|
|
21492
23576
|
if (!stateProps2.includes("minBoxHeight")) stateProps2.push("minBoxHeight");
|
|
21493
23577
|
if (!stateProps2.includes("verticalAlign")) stateProps2.push("verticalAlign");
|
|
23578
|
+
if (!stateProps2.includes("smartWrap")) stateProps2.push("smartWrap");
|
|
21494
23579
|
}
|
|
21495
23580
|
const cacheProps2 = TextboxProto2.cacheProperties;
|
|
21496
23581
|
if (Array.isArray(cacheProps2)) {
|
|
21497
23582
|
if (!cacheProps2.includes("minBoxHeight")) cacheProps2.push("minBoxHeight");
|
|
21498
23583
|
if (!cacheProps2.includes("verticalAlign")) cacheProps2.push("verticalAlign");
|
|
23584
|
+
if (!cacheProps2.includes("smartWrap")) cacheProps2.push("smartWrap");
|
|
23585
|
+
}
|
|
23586
|
+
TextboxProto2.smartWrap = true;
|
|
23587
|
+
if (typeof TextboxProto2._wrapLine === "function" && !TextboxProto2.__pixldocsOrigWrapLine) {
|
|
23588
|
+
const origWrapLine = TextboxProto2._wrapLine;
|
|
23589
|
+
TextboxProto2.__pixldocsOrigWrapLine = origWrapLine;
|
|
23590
|
+
TextboxProto2._wrapLine = function(lineIndex, desiredWidth, ref, reservedSpace = 0) {
|
|
23591
|
+
var _a3;
|
|
23592
|
+
if (!this.smartWrap || this.splitByGrapheme) {
|
|
23593
|
+
return origWrapLine.call(this, lineIndex, desiredWidth, ref, reservedSpace);
|
|
23594
|
+
}
|
|
23595
|
+
try {
|
|
23596
|
+
const additionalSpace = this._getWidthOfCharSpacing();
|
|
23597
|
+
const data = ((_a3 = ref == null ? void 0 : ref.wordsData) == null ? void 0 : _a3[lineIndex]) || [];
|
|
23598
|
+
const effective = Math.max(1, desiredWidth - reservedSpace);
|
|
23599
|
+
const infix = " ";
|
|
23600
|
+
const infixWidth = this._measureWord([infix], lineIndex, 0);
|
|
23601
|
+
const graphemeLines = [];
|
|
23602
|
+
let line = [];
|
|
23603
|
+
let lineWidth = 0;
|
|
23604
|
+
let lineJustStarted = true;
|
|
23605
|
+
let largestWordWidth = 0;
|
|
23606
|
+
let offset = 0;
|
|
23607
|
+
const pushLine = () => {
|
|
23608
|
+
graphemeLines.push(line);
|
|
23609
|
+
line = [];
|
|
23610
|
+
lineWidth = 0;
|
|
23611
|
+
lineJustStarted = true;
|
|
23612
|
+
};
|
|
23613
|
+
for (let i = 0; i < data.length; i++) {
|
|
23614
|
+
const { word, width: wordWidth } = data[i];
|
|
23615
|
+
if (wordWidth <= effective) {
|
|
23616
|
+
if (wordWidth > largestWordWidth) largestWordWidth = wordWidth;
|
|
23617
|
+
const projected = lineJustStarted ? wordWidth : lineWidth + infixWidth + wordWidth - additionalSpace;
|
|
23618
|
+
if (!lineJustStarted && projected > effective) pushLine();
|
|
23619
|
+
if (!lineJustStarted) {
|
|
23620
|
+
line.push(infix);
|
|
23621
|
+
lineWidth += infixWidth;
|
|
23622
|
+
}
|
|
23623
|
+
line = line.concat(word);
|
|
23624
|
+
lineWidth += wordWidth;
|
|
23625
|
+
lineJustStarted = false;
|
|
23626
|
+
} else {
|
|
23627
|
+
if (!lineJustStarted) pushLine();
|
|
23628
|
+
for (const g of word) {
|
|
23629
|
+
const gw = this._measureWord([g], lineIndex, offset);
|
|
23630
|
+
if (gw > largestWordWidth) largestWordWidth = gw;
|
|
23631
|
+
const gProj = lineJustStarted ? gw : lineWidth + gw - additionalSpace;
|
|
23632
|
+
if (!lineJustStarted && gProj > effective) pushLine();
|
|
23633
|
+
line.push(g);
|
|
23634
|
+
lineWidth += gw;
|
|
23635
|
+
lineJustStarted = false;
|
|
23636
|
+
offset++;
|
|
23637
|
+
}
|
|
23638
|
+
offset -= word.length;
|
|
23639
|
+
}
|
|
23640
|
+
offset += word.length + 1;
|
|
23641
|
+
}
|
|
23642
|
+
if (line.length) graphemeLines.push(line);
|
|
23643
|
+
const minNeeded = Math.max(0, Math.min(largestWordWidth, effective) - additionalSpace + reservedSpace);
|
|
23644
|
+
if (minNeeded > this.dynamicMinWidth) this.dynamicMinWidth = minNeeded;
|
|
23645
|
+
return graphemeLines;
|
|
23646
|
+
} catch (e) {
|
|
23647
|
+
return origWrapLine.call(this, lineIndex, desiredWidth, ref, reservedSpace);
|
|
23648
|
+
}
|
|
23649
|
+
};
|
|
21499
23650
|
}
|
|
21500
23651
|
TextboxProto2.__pixldocsTextboxExtended = true;
|
|
21501
23652
|
__textboxBoxExtensionsInstalled = true;
|
|
@@ -21917,7 +24068,7 @@ class PixldocsRenderer {
|
|
|
21917
24068
|
await this.waitForCanvasScene(container, cloned, i);
|
|
21918
24069
|
}
|
|
21919
24070
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
21920
|
-
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
24071
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-De9vylBF.cjs"));
|
|
21921
24072
|
const prepared = preparePagesForExport(
|
|
21922
24073
|
cloned.pages,
|
|
21923
24074
|
canvasWidth,
|
|
@@ -22134,9 +24285,9 @@ class PixldocsRenderer {
|
|
|
22134
24285
|
}
|
|
22135
24286
|
waitForCanvasScene(container, config, pageIndex, maxWaitMs = 8e3, pollMs = 50) {
|
|
22136
24287
|
return new Promise((resolve) => {
|
|
22137
|
-
var _a2,
|
|
24288
|
+
var _a2, _b2;
|
|
22138
24289
|
const start = Date.now();
|
|
22139
|
-
const pageHasContent = (((
|
|
24290
|
+
const pageHasContent = (((_b2 = (_a2 = config.pages[pageIndex]) == null ? void 0 : _a2.children) == null ? void 0 : _b2.length) ?? 0) > 0;
|
|
22140
24291
|
const settle = () => requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
|
|
22141
24292
|
const check = () => {
|
|
22142
24293
|
const fabricCanvas = this.getFabricCanvasFromContainer(container);
|
|
@@ -22211,9 +24362,9 @@ class PixldocsRenderer {
|
|
|
22211
24362
|
return normalized;
|
|
22212
24363
|
}
|
|
22213
24364
|
paintPageBackground(ctx, page, width, height) {
|
|
22214
|
-
var _a2,
|
|
24365
|
+
var _a2, _b2;
|
|
22215
24366
|
const backgroundColor = ((_a2 = page == null ? void 0 : page.settings) == null ? void 0 : _a2.backgroundColor) || "#ffffff";
|
|
22216
|
-
const gradient = (
|
|
24367
|
+
const gradient = (_b2 = page == null ? void 0 : page.settings) == null ? void 0 : _b2.backgroundGradient;
|
|
22217
24368
|
ctx.clearRect(0, 0, width, height);
|
|
22218
24369
|
ctx.fillStyle = backgroundColor;
|
|
22219
24370
|
ctx.fillRect(0, 0, width, height);
|
|
@@ -22461,7 +24612,7 @@ class PixldocsRenderer {
|
|
|
22461
24612
|
};
|
|
22462
24613
|
const onReady = () => {
|
|
22463
24614
|
this.waitForCanvasScene(container, renderConfig, pageIndex).then(async () => {
|
|
22464
|
-
var _a2,
|
|
24615
|
+
var _a2, _b2;
|
|
22465
24616
|
try {
|
|
22466
24617
|
const expectedImageIds = this.getExpectedImageIds(renderConfig, pageIndex);
|
|
22467
24618
|
await this.waitForCanvasImages(container, expectedImageIds);
|
|
@@ -22480,7 +24631,7 @@ class PixldocsRenderer {
|
|
|
22480
24631
|
);
|
|
22481
24632
|
const page = renderConfig.pages[pageIndex];
|
|
22482
24633
|
const backgroundColor = ((_a2 = page == null ? void 0 : page.settings) == null ? void 0 : _a2.backgroundColor) || "#ffffff";
|
|
22483
|
-
const backgroundGradient = (
|
|
24634
|
+
const backgroundGradient = (_b2 = page == null ? void 0 : page.settings) == null ? void 0 : _b2.backgroundGradient;
|
|
22484
24635
|
cleanup();
|
|
22485
24636
|
resolve({
|
|
22486
24637
|
svg: svgString,
|
|
@@ -22601,7 +24752,7 @@ class PixldocsRenderer {
|
|
|
22601
24752
|
logJsonLine("[canvas-renderer][fabric-text-parity]", { stage, textboxes: sample.length, sample });
|
|
22602
24753
|
}
|
|
22603
24754
|
async waitForStableTextMetrics(container, config, options = {}) {
|
|
22604
|
-
var _a2,
|
|
24755
|
+
var _a2, _b2, _c;
|
|
22605
24756
|
if (typeof document !== "undefined") {
|
|
22606
24757
|
void ensureFontsForResolvedConfig(config);
|
|
22607
24758
|
await this.waitForRelevantFonts(config);
|
|
@@ -22643,7 +24794,7 @@ class PixldocsRenderer {
|
|
|
22643
24794
|
}
|
|
22644
24795
|
fabricInstance.getObjects().forEach(primeCharBounds);
|
|
22645
24796
|
(_a2 = fabricInstance.calcOffset) == null ? void 0 : _a2.call(fabricInstance);
|
|
22646
|
-
(
|
|
24797
|
+
(_b2 = fabricInstance.renderAll) == null ? void 0 : _b2.call(fabricInstance);
|
|
22647
24798
|
await waitForPaint();
|
|
22648
24799
|
(_c = fabricInstance.renderAll) == null ? void 0 : _c.call(fabricInstance);
|
|
22649
24800
|
await waitForPaint();
|
|
@@ -22684,7 +24835,7 @@ function dumpSvgTextDiagnostics(svgStr, pageIndex, tag, stage, maxItems = 30) {
|
|
|
22684
24835
|
};
|
|
22685
24836
|
logParityJson(tag, stage, { kind: "summary", ...summary });
|
|
22686
24837
|
const sample = texts.slice(0, maxItems).map((t, idx) => {
|
|
22687
|
-
var _a2,
|
|
24838
|
+
var _a2, _b2;
|
|
22688
24839
|
const tspans = Array.from(t.querySelectorAll("tspan"));
|
|
22689
24840
|
const tspanInfo = tspans.slice(0, 8).map((s) => ({
|
|
22690
24841
|
x: s.getAttribute("x"),
|
|
@@ -22701,7 +24852,7 @@ function dumpSvgTextDiagnostics(svgStr, pageIndex, tag, stage, maxItems = 30) {
|
|
|
22701
24852
|
while (cursor && !containerWidth) {
|
|
22702
24853
|
containerWidth = (_a2 = cursor.getAttribute) == null ? void 0 : _a2.call(cursor, "width");
|
|
22703
24854
|
cursor = cursor.parentElement;
|
|
22704
|
-
if (cursor && ((
|
|
24855
|
+
if (cursor && ((_b2 = cursor.tagName) == null ? void 0 : _b2.toLowerCase()) === "svg") break;
|
|
22705
24856
|
}
|
|
22706
24857
|
return {
|
|
22707
24858
|
idx,
|
|
@@ -23089,10 +25240,10 @@ function normalizeSvgExplicitColors(svg) {
|
|
|
23089
25240
|
return normalizeGradientPaintRef(v);
|
|
23090
25241
|
};
|
|
23091
25242
|
const hasExplicitNonePaint = (el, attr) => {
|
|
23092
|
-
var _a2,
|
|
25243
|
+
var _a2, _b2;
|
|
23093
25244
|
const raw = (el.getAttribute(attr) ?? ((_a2 = el.style) == null ? void 0 : _a2.getPropertyValue(attr)) ?? "").trim().toLowerCase();
|
|
23094
25245
|
if (raw === "none" || raw === "transparent") return true;
|
|
23095
|
-
const rawOpacity = (el.getAttribute(`${attr}-opacity`) ?? ((
|
|
25246
|
+
const rawOpacity = (el.getAttribute(`${attr}-opacity`) ?? ((_b2 = el.style) == null ? void 0 : _b2.getPropertyValue(`${attr}-opacity`)) ?? "").trim().toLowerCase();
|
|
23096
25247
|
return rawOpacity === "0" || rawOpacity === "0%" || rawOpacity === "0.0";
|
|
23097
25248
|
};
|
|
23098
25249
|
function walk(el, parentFill, parentStroke, parentColor) {
|
|
@@ -23159,14 +25310,14 @@ function normalizeSvgExplicitColors(svg) {
|
|
|
23159
25310
|
function bakeGroupOpacityIntoChildren(svg) {
|
|
23160
25311
|
const DRAWABLE = /* @__PURE__ */ new Set(["path", "rect", "circle", "ellipse", "polygon", "polyline", "line", "text", "tspan"]);
|
|
23161
25312
|
function walkAndBake(el, inheritedOpacity) {
|
|
23162
|
-
var _a2,
|
|
25313
|
+
var _a2, _b2, _c, _d;
|
|
23163
25314
|
if (isInSvgDefinitionSubtree(el)) {
|
|
23164
25315
|
for (let i = 0; i < el.children.length; i++) walkAndBake(el.children[i], 1);
|
|
23165
25316
|
return;
|
|
23166
25317
|
}
|
|
23167
25318
|
const tag = ((_a2 = el.tagName) == null ? void 0 : _a2.toLowerCase()) ?? "";
|
|
23168
25319
|
const opacityAttr = parseSvgOpacity(el.getAttribute("opacity"));
|
|
23169
|
-
const styleOpacity = parseSvgOpacity(((
|
|
25320
|
+
const styleOpacity = parseSvgOpacity(((_b2 = el.style) == null ? void 0 : _b2.getPropertyValue("opacity")) || null);
|
|
23170
25321
|
const ownOpacity = opacityAttr ?? styleOpacity ?? 1;
|
|
23171
25322
|
const combinedOpacity = inheritedOpacity * ownOpacity;
|
|
23172
25323
|
if (ownOpacity < 0.999 && tag !== "image") {
|
|
@@ -23689,10 +25840,10 @@ function getFirstExplicitColorFromSvg(svg) {
|
|
|
23689
25840
|
return getGradientStopColorAsHex(svg, gradientId);
|
|
23690
25841
|
};
|
|
23691
25842
|
function walk(el) {
|
|
23692
|
-
var _a2,
|
|
25843
|
+
var _a2, _b2;
|
|
23693
25844
|
if (fill && stroke) return;
|
|
23694
25845
|
const f = el.getAttribute("fill") ?? ((_a2 = el.style) == null ? void 0 : _a2.getPropertyValue("fill"));
|
|
23695
|
-
const s = el.getAttribute("stroke") ?? ((
|
|
25846
|
+
const s = el.getAttribute("stroke") ?? ((_b2 = el.style) == null ? void 0 : _b2.getPropertyValue("stroke"));
|
|
23696
25847
|
if (!fill) {
|
|
23697
25848
|
if (isRealColor(f)) fill = f;
|
|
23698
25849
|
else if (f) {
|
|
@@ -23720,8 +25871,8 @@ function isNearWhite(hex) {
|
|
|
23720
25871
|
return r >= 250 && g >= 250 && b >= 250;
|
|
23721
25872
|
}
|
|
23722
25873
|
function getStopColorRaw(stop) {
|
|
23723
|
-
var _a2,
|
|
23724
|
-
return stop.getAttribute("stop-color") ?? ((
|
|
25874
|
+
var _a2, _b2;
|
|
25875
|
+
return stop.getAttribute("stop-color") ?? ((_b2 = (_a2 = stop.style) == null ? void 0 : _a2.getPropertyValue("stop-color")) == null ? void 0 : _b2.trim()) ?? getInlineStyleValue(stop, "stop-color");
|
|
23725
25876
|
}
|
|
23726
25877
|
function getGradientStopColorAsHex(svgRoot, gradientId, visited = /* @__PURE__ */ new Set()) {
|
|
23727
25878
|
var _a2;
|
|
@@ -23785,12 +25936,12 @@ async function convertTextDecorationsToLines(svg) {
|
|
|
23785
25936
|
else el.removeAttribute("style");
|
|
23786
25937
|
};
|
|
23787
25938
|
const resolveInheritedSvgValue = (el, attr, styleProp = attr) => {
|
|
23788
|
-
var _a2,
|
|
25939
|
+
var _a2, _b2;
|
|
23789
25940
|
let current = el;
|
|
23790
25941
|
while (current) {
|
|
23791
25942
|
const attrValue = (_a2 = current.getAttribute(attr)) == null ? void 0 : _a2.trim();
|
|
23792
25943
|
if (attrValue) return attrValue;
|
|
23793
|
-
const styleValue = (
|
|
25944
|
+
const styleValue = (_b2 = getInlineStyleValue(current, styleProp)) == null ? void 0 : _b2.trim();
|
|
23794
25945
|
if (styleValue) return styleValue;
|
|
23795
25946
|
current = current.parentElement;
|
|
23796
25947
|
}
|
|
@@ -23968,7 +26119,7 @@ async function convertSvgTextDecorationsToLinesString(svgStr) {
|
|
|
23968
26119
|
}
|
|
23969
26120
|
}
|
|
23970
26121
|
async function rasterizeShadowMarkers(svg) {
|
|
23971
|
-
var _a2,
|
|
26122
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
23972
26123
|
if (typeof window === "undefined" || typeof document === "undefined") return;
|
|
23973
26124
|
const markers = Array.from(svg.querySelectorAll("g.__pdShadowRaster"));
|
|
23974
26125
|
if (markers.length === 0) return;
|
|
@@ -23992,7 +26143,7 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
23992
26143
|
const alphaRaw = parseFloat(marker.getAttribute("data-alpha") || "1");
|
|
23993
26144
|
const shadowAlpha = Number.isFinite(alphaRaw) ? Math.max(0, Math.min(1, alphaRaw)) : 1;
|
|
23994
26145
|
if (!Number.isFinite(bw) || !Number.isFinite(bh) || bw <= 0 || bh <= 0) {
|
|
23995
|
-
(
|
|
26146
|
+
(_b2 = marker.parentNode) == null ? void 0 : _b2.removeChild(marker);
|
|
23996
26147
|
continue;
|
|
23997
26148
|
}
|
|
23998
26149
|
const innerXml = restoreSourceFontsForShadowRaster(
|
|
@@ -24237,7 +26388,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
24237
26388
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
24238
26389
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
24239
26390
|
try {
|
|
24240
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
26391
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-De9vylBF.cjs"));
|
|
24241
26392
|
try {
|
|
24242
26393
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
24243
26394
|
} catch {
|
|
@@ -24253,7 +26404,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
24253
26404
|
}
|
|
24254
26405
|
}
|
|
24255
26406
|
function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundColor, backgroundGradient) {
|
|
24256
|
-
var _a2,
|
|
26407
|
+
var _a2, _b2;
|
|
24257
26408
|
if (backgroundGradient && ((_a2 = backgroundGradient.stops) == null ? void 0 : _a2.length) >= 2) {
|
|
24258
26409
|
const grad = backgroundGradient;
|
|
24259
26410
|
const colorStops = grad.stops.map((s) => {
|
|
@@ -24308,7 +26459,7 @@ function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundCol
|
|
|
24308
26459
|
doc.fill({ key: patternKey, matrix: doc.Matrix(1, 0, 0, 1, 0, 0) });
|
|
24309
26460
|
});
|
|
24310
26461
|
} catch {
|
|
24311
|
-
const fallback = ((
|
|
26462
|
+
const fallback = ((_b2 = colorStops[0]) == null ? void 0 : _b2.color) || [255, 255, 255];
|
|
24312
26463
|
pdf.setFillColor(fallback[0], fallback[1], fallback[2]);
|
|
24313
26464
|
pdf.rect(0, 0, pageWidth, pageHeight, "F");
|
|
24314
26465
|
}
|
|
@@ -24321,7 +26472,7 @@ function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundCol
|
|
|
24321
26472
|
}
|
|
24322
26473
|
}
|
|
24323
26474
|
async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
24324
|
-
var _a2,
|
|
26475
|
+
var _a2, _b2;
|
|
24325
26476
|
if (svgResults.length === 0) throw new Error("No pages to export");
|
|
24326
26477
|
const { title, stripPageBackground } = options;
|
|
24327
26478
|
const firstPage = svgResults[0];
|
|
@@ -24354,7 +26505,7 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
24354
26505
|
const pageOrientation = page.width > page.height ? "landscape" : "portrait";
|
|
24355
26506
|
pdf.addPage([page.width, page.height], pageOrientation);
|
|
24356
26507
|
}
|
|
24357
|
-
const hasGradient = !!((
|
|
26508
|
+
const hasGradient = !!((_b2 = (_a2 = page.backgroundGradient) == null ? void 0 : _a2.stops) == null ? void 0 : _b2.length);
|
|
24358
26509
|
drawPageBackground(pdf, i, page.width, page.height, page.backgroundColor, page.backgroundGradient);
|
|
24359
26510
|
const shouldStripBg = stripPageBackground ?? hasGradient;
|
|
24360
26511
|
const textMode = options.textMode ?? (options.outlineText === true ? "pixel-perfect" : "selectable");
|
|
@@ -24634,4 +26785,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
24634
26785
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
24635
26786
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
24636
26787
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
24637
|
-
//# sourceMappingURL=index-
|
|
26788
|
+
//# sourceMappingURL=index-YCh9sTg1.cjs.map
|