@pixldocs/canvas-renderer 0.5.241 → 0.5.243
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-DtyVze4W.js → index-C5mQ2kl5.js} +2300 -345
- package/dist/index-C5mQ2kl5.js.map +1 -0
- package/dist/{index-BRI84Wy6.cjs → index-UuNicsNZ.cjs} +2300 -345
- package/dist/index-UuNicsNZ.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-BBY4avH9.js → vectorPdfExport-DJD1vq7N.js} +4 -4
- package/dist/{vectorPdfExport-BBY4avH9.js.map → vectorPdfExport-DJD1vq7N.js.map} +1 -1
- package/dist/{vectorPdfExport-BQhOl3Zh.cjs → vectorPdfExport-V2qBQ4Xs.cjs} +4 -4
- package/dist/{vectorPdfExport-BQhOl3Zh.cjs.map → vectorPdfExport-V2qBQ4Xs.cjs.map} +1 -1
- package/package.json +1 -1
- package/dist/index-BRI84Wy6.cjs.map +0 -1
- package/dist/index-DtyVze4W.js.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,
|
|
@@ -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();
|
|
@@ -5756,6 +5788,7 @@ function getObjectSnapPoints(obj) {
|
|
|
5756
5788
|
function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold) {
|
|
5757
5789
|
if (!snapToGuides) return { guides: [], snapDx: 0, snapDy: 0 };
|
|
5758
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;
|
|
@@ -5858,6 +5909,8 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5858
5909
|
const equalGap = Math.round(newLeft - bestPair.A.right);
|
|
5859
5910
|
const bracketY = (Math.max(bestPair.A.top, projectedTop, bestPair.B.top) + Math.min(bestPair.A.bottom, projectedBottom, bestPair.B.bottom)) / 2;
|
|
5860
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 };
|
|
5861
5914
|
newGuides.push({
|
|
5862
5915
|
type: "horizontal",
|
|
5863
5916
|
position: bracketY,
|
|
@@ -5865,7 +5918,8 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5865
5918
|
gap: equalGap,
|
|
5866
5919
|
start: bestPair.A.right,
|
|
5867
5920
|
end: newLeft,
|
|
5868
|
-
bracketAt: bracketY
|
|
5921
|
+
bracketAt: bracketY,
|
|
5922
|
+
targetBoundsList: [aTb, bTb]
|
|
5869
5923
|
});
|
|
5870
5924
|
newGuides.push({
|
|
5871
5925
|
type: "horizontal",
|
|
@@ -5874,7 +5928,8 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5874
5928
|
gap: equalGap,
|
|
5875
5929
|
start: newRight,
|
|
5876
5930
|
end: bestPair.B.left,
|
|
5877
|
-
bracketAt: bracketY
|
|
5931
|
+
bracketAt: bracketY,
|
|
5932
|
+
targetBoundsList: [aTb, bTb]
|
|
5878
5933
|
});
|
|
5879
5934
|
}
|
|
5880
5935
|
}
|
|
@@ -5906,6 +5961,8 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5906
5961
|
const equalGap = Math.round(newTop - bestPair.A.bottom);
|
|
5907
5962
|
const bracketX = (Math.max(bestPair.A.left, projectedLeft, bestPair.B.left) + Math.min(bestPair.A.right, projectedRight, bestPair.B.right)) / 2;
|
|
5908
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 };
|
|
5909
5966
|
newGuides.push({
|
|
5910
5967
|
type: "vertical",
|
|
5911
5968
|
position: bracketX,
|
|
@@ -5913,7 +5970,8 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5913
5970
|
gap: equalGap,
|
|
5914
5971
|
start: bestPair.A.bottom,
|
|
5915
5972
|
end: newTop,
|
|
5916
|
-
bracketAt: bracketX
|
|
5973
|
+
bracketAt: bracketX,
|
|
5974
|
+
targetBoundsList: [aTb, bTb]
|
|
5917
5975
|
});
|
|
5918
5976
|
newGuides.push({
|
|
5919
5977
|
type: "vertical",
|
|
@@ -5922,16 +5980,17 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5922
5980
|
gap: equalGap,
|
|
5923
5981
|
start: newBottom,
|
|
5924
5982
|
end: bestPair.B.top,
|
|
5925
|
-
bracketAt: bracketX
|
|
5983
|
+
bracketAt: bracketX,
|
|
5984
|
+
targetBoundsList: [aTb, bTb]
|
|
5926
5985
|
});
|
|
5927
5986
|
}
|
|
5928
5987
|
}
|
|
5929
5988
|
}
|
|
5930
5989
|
return { guides: newGuides, snapDx, snapDy };
|
|
5931
5990
|
}
|
|
5932
|
-
function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold) {
|
|
5991
|
+
function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold, additionalBounds = []) {
|
|
5933
5992
|
if (!snapToGuides) return [];
|
|
5934
|
-
const threshold = snapThreshold
|
|
5993
|
+
const threshold = snapThreshold;
|
|
5935
5994
|
const newGuides = [];
|
|
5936
5995
|
const scaling = getObjectSnapPoints(scalingObj);
|
|
5937
5996
|
const scalingId = getObjectId(scalingObj);
|
|
@@ -5944,7 +6003,7 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5944
6003
|
const checkVerticalSnap = (edgePosition, targetPosition, guide) => {
|
|
5945
6004
|
const dist = Math.abs(edgePosition - targetPosition);
|
|
5946
6005
|
if (dist < threshold) {
|
|
5947
|
-
newGuides.push({ ...guide,
|
|
6006
|
+
newGuides.push({ ...guide, kind: "alignment" });
|
|
5948
6007
|
return true;
|
|
5949
6008
|
}
|
|
5950
6009
|
return false;
|
|
@@ -5952,7 +6011,7 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5952
6011
|
const checkHorizontalSnap = (edgePosition, targetPosition, guide) => {
|
|
5953
6012
|
const dist = Math.abs(edgePosition - targetPosition);
|
|
5954
6013
|
if (dist < threshold) {
|
|
5955
|
-
newGuides.push({ ...guide,
|
|
6014
|
+
newGuides.push({ ...guide, kind: "alignment" });
|
|
5956
6015
|
return true;
|
|
5957
6016
|
}
|
|
5958
6017
|
return false;
|
|
@@ -5974,12 +6033,39 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5974
6033
|
checkHorizontalSnap(scaling.bottom, canvasCenterY, { type: "horizontal", position: canvasCenterY });
|
|
5975
6034
|
}
|
|
5976
6035
|
const rawObjects = canvas.getObjects();
|
|
6036
|
+
const objectBounds = [];
|
|
5977
6037
|
for (const obj of rawObjects) {
|
|
5978
6038
|
if (obj === scalingObj) continue;
|
|
5979
6039
|
const objId = getObjectId(obj);
|
|
5980
6040
|
if (objId === "__background__") continue;
|
|
5981
6041
|
if (objId && objId === scalingId) continue;
|
|
5982
|
-
|
|
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
|
+
}
|
|
5983
6069
|
if (resizingLeft) {
|
|
5984
6070
|
checkVerticalSnap(scaling.left, other.left, {
|
|
5985
6071
|
type: "vertical",
|
|
@@ -6061,6 +6147,18 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
6061
6147
|
});
|
|
6062
6148
|
}
|
|
6063
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
|
+
}
|
|
6064
6162
|
const seen = /* @__PURE__ */ new Set();
|
|
6065
6163
|
return newGuides.filter((guide) => {
|
|
6066
6164
|
const key = `${guide.type}-${guide.position.toFixed(1)}`;
|
|
@@ -6069,6 +6167,349 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
6069
6167
|
return true;
|
|
6070
6168
|
});
|
|
6071
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
|
+
}
|
|
6072
6513
|
const clamp01$1 = (v) => Math.max(0, Math.min(1, Number.isFinite(v) ? v : 0));
|
|
6073
6514
|
function arcPath(w, sag, up) {
|
|
6074
6515
|
if (sag <= 0.5) return `M 0 0 L ${w} 0`;
|
|
@@ -6239,12 +6680,87 @@ if (Array.isArray(stateProps)) {
|
|
|
6239
6680
|
if (!stateProps.includes("minBoxHeight")) stateProps.push("minBoxHeight");
|
|
6240
6681
|
if (!stateProps.includes("verticalAlign")) stateProps.push("verticalAlign");
|
|
6241
6682
|
if (!stateProps.includes("textPath")) stateProps.push("textPath");
|
|
6683
|
+
if (!stateProps.includes("smartWrap")) stateProps.push("smartWrap");
|
|
6242
6684
|
}
|
|
6243
6685
|
const cacheProps = fabric__namespace.Textbox.prototype.cacheProperties;
|
|
6244
6686
|
if (Array.isArray(cacheProps)) {
|
|
6245
6687
|
if (!cacheProps.includes("minBoxHeight")) cacheProps.push("minBoxHeight");
|
|
6246
6688
|
if (!cacheProps.includes("verticalAlign")) cacheProps.push("verticalAlign");
|
|
6247
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
|
+
};
|
|
6248
6764
|
}
|
|
6249
6765
|
const hasActiveTextPath = (obj) => {
|
|
6250
6766
|
const tp = obj.textPath;
|
|
@@ -6401,14 +6917,14 @@ function scaleLocalToScreen(target, p) {
|
|
|
6401
6917
|
return new fabric__namespace.Point(p.x * sx * zx, p.y * sy * zy);
|
|
6402
6918
|
}
|
|
6403
6919
|
function applyTextPathControls(textbox) {
|
|
6404
|
-
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;
|
|
6405
6921
|
const obj = textbox;
|
|
6406
6922
|
if (!hasActiveTextPath(obj)) {
|
|
6407
6923
|
obj.__pdTextPathHovered = false;
|
|
6408
6924
|
if (obj.__pdTextPathControls) {
|
|
6409
6925
|
try {
|
|
6410
6926
|
const cu2 = fabric__namespace.controlsUtils;
|
|
6411
|
-
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));
|
|
6412
6928
|
if (defaults) obj.controls = defaults;
|
|
6413
6929
|
} catch {
|
|
6414
6930
|
}
|
|
@@ -6672,7 +7188,7 @@ function applyTextPathControls(textbox) {
|
|
|
6672
7188
|
actionName: "tpPivot",
|
|
6673
7189
|
positionHandler: (_d2, finalMatrix, fabricObject) => scaleLocalToScreen(fabricObject, getPivotLocalCentered(fabricObject)).transform(finalMatrix),
|
|
6674
7190
|
actionHandler: (_e2, transform, x, y) => {
|
|
6675
|
-
var _a3,
|
|
7191
|
+
var _a3, _b3;
|
|
6676
7192
|
const target = transform.target;
|
|
6677
7193
|
const state = transform.__pdCirclePivotDrag || (transform.__pdCirclePivotDrag = {
|
|
6678
7194
|
startMatrix: target.calcTransformMatrix(),
|
|
@@ -6689,7 +7205,7 @@ function applyTextPathControls(textbox) {
|
|
|
6689
7205
|
y: (state.startOffset.y || 0) + dy
|
|
6690
7206
|
};
|
|
6691
7207
|
target.setCoords();
|
|
6692
|
-
(
|
|
7208
|
+
(_b3 = target.canvas) == null ? void 0 : _b3.requestRenderAll();
|
|
6693
7209
|
return true;
|
|
6694
7210
|
},
|
|
6695
7211
|
render: renderPivot
|
|
@@ -6740,13 +7256,13 @@ function applyTextPathControls(textbox) {
|
|
|
6740
7256
|
}
|
|
6741
7257
|
if (!obj.__pdCirclePivotDblWired) {
|
|
6742
7258
|
obj.on("mousedblclick", () => {
|
|
6743
|
-
var _a3,
|
|
7259
|
+
var _a3, _b3;
|
|
6744
7260
|
if (((_a3 = obj.textPath) == null ? void 0 : _a3.preset) !== "circle") return;
|
|
6745
7261
|
if (obj.__corner !== "tpPivot") return;
|
|
6746
7262
|
if (!obj.textPath.pivot) return;
|
|
6747
7263
|
obj.textPath.pivot = { x: 0, y: 0 };
|
|
6748
7264
|
obj.setCoords();
|
|
6749
|
-
(
|
|
7265
|
+
(_b3 = obj.canvas) == null ? void 0 : _b3.requestRenderAll();
|
|
6750
7266
|
});
|
|
6751
7267
|
obj.__pdCirclePivotDblWired = true;
|
|
6752
7268
|
}
|
|
@@ -7114,10 +7630,10 @@ function textPathBoundsContainScenePoint(obj, point) {
|
|
|
7114
7630
|
}
|
|
7115
7631
|
}
|
|
7116
7632
|
function drawTextPathBounds(ctx, obj, bounds, hostCanvas) {
|
|
7117
|
-
var _a2,
|
|
7633
|
+
var _a2, _b2, _c;
|
|
7118
7634
|
const host = hostCanvas || obj.canvas || ((_a2 = obj.group) == null ? void 0 : _a2.canvas);
|
|
7119
7635
|
if (!host) return;
|
|
7120
|
-
const retina = ((
|
|
7636
|
+
const retina = ((_b2 = host.getRetinaScaling) == null ? void 0 : _b2.call(host)) || ((_c = obj.getCanvasRetinaScaling) == null ? void 0 : _c.call(obj)) || 1;
|
|
7121
7637
|
const matrix = fabric__namespace.util.multiplyTransformMatrices(host.viewportTransform || [1, 0, 0, 1, 0, 0], obj.calcTransformMatrix());
|
|
7122
7638
|
const corners = [
|
|
7123
7639
|
new fabric__namespace.Point(bounds.minX, bounds.minY),
|
|
@@ -7139,8 +7655,8 @@ function drawTextPathBounds(ctx, obj, bounds, hostCanvas) {
|
|
|
7139
7655
|
}
|
|
7140
7656
|
if (typeof TextboxProto._renderControls === "function" && !TextboxProto.__pixldocsOrigRenderControls) {
|
|
7141
7657
|
let drawWarpGuides = function(ctx) {
|
|
7142
|
-
var _a2,
|
|
7143
|
-
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);
|
|
7144
7660
|
if (!hostCanvas) return;
|
|
7145
7661
|
const hoverBounds = getTextPathHitBounds(this);
|
|
7146
7662
|
const active = (_d = hostCanvas.getActiveObject) == null ? void 0 : _d.call(hostCanvas);
|
|
@@ -7563,12 +8079,12 @@ function buildRoundedRectPath2D(ctx, x, y, w, h, rTL, rTR, rBR, rBL) {
|
|
|
7563
8079
|
ctx.closePath();
|
|
7564
8080
|
}
|
|
7565
8081
|
function measureLineGlyphWidth(obj, lineIndex) {
|
|
7566
|
-
var _a2,
|
|
8082
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
7567
8083
|
try {
|
|
7568
8084
|
const rawLine = (_a2 = obj == null ? void 0 : obj._textLines) == null ? void 0 : _a2[lineIndex];
|
|
7569
8085
|
const lineText = Array.isArray(rawLine) ? rawLine.join("") : String(rawLine ?? "");
|
|
7570
8086
|
if (!lineText) return 0;
|
|
7571
|
-
const fontSize = Number(((
|
|
8087
|
+
const fontSize = Number(((_b2 = obj.getValueOfPropertyAt) == null ? void 0 : _b2.call(obj, lineIndex, 0, "fontSize")) ?? obj.fontSize ?? 0);
|
|
7572
8088
|
if (!fontSize) return 0;
|
|
7573
8089
|
const fontStyle = String(((_c = obj.getValueOfPropertyAt) == null ? void 0 : _c.call(obj, lineIndex, 0, "fontStyle")) ?? obj.fontStyle ?? "normal");
|
|
7574
8090
|
const fontWeight = String(((_d = obj.getValueOfPropertyAt) == null ? void 0 : _d.call(obj, lineIndex, 0, "fontWeight")) ?? obj.fontWeight ?? "400");
|
|
@@ -7837,7 +8353,7 @@ function applyTextBackground(obj, cfg) {
|
|
|
7837
8353
|
const originalToSVG = (_a2 = obj.toSVG) == null ? void 0 : _a2.bind(obj);
|
|
7838
8354
|
if (typeof originalToSVG === "function") {
|
|
7839
8355
|
obj.toSVG = function(reviver) {
|
|
7840
|
-
var _a3,
|
|
8356
|
+
var _a3, _b2;
|
|
7841
8357
|
let svg = originalToSVG(reviver);
|
|
7842
8358
|
const bg = this[PD_BG_KEY];
|
|
7843
8359
|
const shadow = this.shadow;
|
|
@@ -7886,7 +8402,7 @@ function applyTextBackground(obj, cfg) {
|
|
|
7886
8402
|
const bgOpacityAttr = bgOpacity < 1 ? ` fill-opacity="${bgOpacity}"` : "";
|
|
7887
8403
|
let bgGradDefs = "";
|
|
7888
8404
|
let bgFillAttr = escapeXmlAttr(bgFill);
|
|
7889
|
-
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) {
|
|
7890
8406
|
const bounds = ribbonD ? computeRibbonBoundsFor(this, pT, pR, pB, pL) : unionBounds(rects);
|
|
7891
8407
|
const gid = `__pdBgGrad_${Math.random().toString(36).slice(2, 9)}`;
|
|
7892
8408
|
const def = buildSvgGradientDef(bg.gradient, gid, bounds.x, bounds.y, bounds.w, bounds.h);
|
|
@@ -8915,9 +9431,9 @@ function createShape(element) {
|
|
|
8915
9431
|
});
|
|
8916
9432
|
}
|
|
8917
9433
|
case "circle": {
|
|
8918
|
-
|
|
8919
|
-
|
|
8920
|
-
|
|
9434
|
+
return new fabric__namespace.Ellipse({
|
|
9435
|
+
rx: w / 2,
|
|
9436
|
+
ry: h / 2,
|
|
8921
9437
|
fill,
|
|
8922
9438
|
stroke,
|
|
8923
9439
|
strokeWidth,
|
|
@@ -8926,8 +9442,7 @@ function createShape(element) {
|
|
|
8926
9442
|
objectCaching: true,
|
|
8927
9443
|
strokeUniform: true,
|
|
8928
9444
|
strokeLineJoin: "round",
|
|
8929
|
-
strokeLineCap: "round"
|
|
8930
|
-
lockUniScaling: true
|
|
9445
|
+
strokeLineCap: "round"
|
|
8931
9446
|
});
|
|
8932
9447
|
}
|
|
8933
9448
|
case "triangle": {
|
|
@@ -8962,7 +9477,7 @@ function createShape(element) {
|
|
|
8962
9477
|
}
|
|
8963
9478
|
}
|
|
8964
9479
|
function createText(element) {
|
|
8965
|
-
var _a2,
|
|
9480
|
+
var _a2, _b2, _c, _d, _e;
|
|
8966
9481
|
const overflowPolicy = element.overflowPolicy || "grow-and-push";
|
|
8967
9482
|
let text = element.text || "Text";
|
|
8968
9483
|
let fontSize = element.fontSize || 16;
|
|
@@ -9163,7 +9678,7 @@ function createText(element) {
|
|
|
9163
9678
|
textbox.setCoords();
|
|
9164
9679
|
const widthAfterSet = textbox.width ?? 0;
|
|
9165
9680
|
try {
|
|
9166
|
-
(
|
|
9681
|
+
(_b2 = textbox.setControlsVisibility) == null ? void 0 : _b2.call(textbox, {
|
|
9167
9682
|
tl: true,
|
|
9168
9683
|
tr: true,
|
|
9169
9684
|
bl: true,
|
|
@@ -9962,34 +10477,595 @@ function bakeEdgeFade(source, fade) {
|
|
|
9962
10477
|
return canvas;
|
|
9963
10478
|
}
|
|
9964
10479
|
const SELECTION_PRIMARY = "hsl(217, 91%, 60%)";
|
|
10480
|
+
const SELECTION_BORDER_SCALE = 2;
|
|
10481
|
+
let ensureCanvaControlRenders = () => {
|
|
10482
|
+
};
|
|
9965
10483
|
try {
|
|
9966
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
|
+
}
|
|
9967
10494
|
if (InteractiveBase == null ? void 0 : InteractiveBase.ownDefaults) {
|
|
9968
10495
|
Object.assign(InteractiveBase.ownDefaults, {
|
|
9969
10496
|
borderColor: SELECTION_PRIMARY,
|
|
9970
|
-
borderScaleFactor:
|
|
10497
|
+
borderScaleFactor: SELECTION_BORDER_SCALE,
|
|
9971
10498
|
cornerColor: SELECTION_PRIMARY,
|
|
9972
10499
|
cornerStrokeColor: "#ffffff",
|
|
9973
|
-
cornerStyle: "
|
|
10500
|
+
cornerStyle: "circle",
|
|
9974
10501
|
transparentCorners: false,
|
|
9975
|
-
cornerSize:
|
|
10502
|
+
cornerSize: 10,
|
|
9976
10503
|
borderOpacityWhenMoving: 0.9
|
|
9977
10504
|
});
|
|
9978
10505
|
} else if (InteractiveBase == null ? void 0 : InteractiveBase.prototype) {
|
|
9979
10506
|
Object.assign(InteractiveBase.prototype, {
|
|
9980
10507
|
borderColor: SELECTION_PRIMARY,
|
|
9981
|
-
borderScaleFactor:
|
|
10508
|
+
borderScaleFactor: SELECTION_BORDER_SCALE,
|
|
9982
10509
|
cornerColor: SELECTION_PRIMARY,
|
|
9983
10510
|
cornerStrokeColor: "#ffffff",
|
|
9984
|
-
cornerStyle: "
|
|
10511
|
+
cornerStyle: "circle",
|
|
9985
10512
|
transparentCorners: false,
|
|
9986
|
-
cornerSize:
|
|
10513
|
+
cornerSize: 10,
|
|
9987
10514
|
borderOpacityWhenMoving: 0.9
|
|
9988
10515
|
});
|
|
9989
10516
|
}
|
|
9990
10517
|
} catch (e) {
|
|
9991
10518
|
console.warn("[PageCanvas] Failed to apply global selection defaults:", e);
|
|
9992
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
|
+
};
|
|
9993
11069
|
function applyWarpAwareSelectionBorders(selection) {
|
|
9994
11070
|
if (selection.__pixldocsOrigASHasBorders !== void 0) {
|
|
9995
11071
|
selection.hasBorders = selection.__pixldocsOrigASHasBorders;
|
|
@@ -10057,6 +11133,8 @@ const PageCanvas = react.forwardRef(
|
|
|
10057
11133
|
const hasRunPostReadyReflowForPageRef = react.useRef(null);
|
|
10058
11134
|
const hasNotifiedReadyForPageRef = react.useRef(null);
|
|
10059
11135
|
const hasClearedCachesBeforeFirstSyncRef = react.useRef(false);
|
|
11136
|
+
const projectSettingsRef = react.useRef(projectSettings);
|
|
11137
|
+
projectSettingsRef.current = projectSettings;
|
|
10060
11138
|
const [guides, setGuides] = react.useState([]);
|
|
10061
11139
|
const [gridResizeLabel, setGridResizeLabel] = react.useState(null);
|
|
10062
11140
|
const [hoverBounds, setHoverBounds] = react.useState(null);
|
|
@@ -10126,7 +11204,8 @@ const PageCanvas = react.forwardRef(
|
|
|
10126
11204
|
react.useRef(null);
|
|
10127
11205
|
react.useRef(null);
|
|
10128
11206
|
react.useRef(/* @__PURE__ */ new Map());
|
|
10129
|
-
react.useRef(null);
|
|
11207
|
+
const groupResizeActiveSnapRef = react.useRef(null);
|
|
11208
|
+
const objectResizeActiveSnapRef = react.useRef(null);
|
|
10130
11209
|
react.useRef(null);
|
|
10131
11210
|
react.useRef(null);
|
|
10132
11211
|
react.useRef(null);
|
|
@@ -10268,33 +11347,358 @@ const PageCanvas = react.forwardRef(
|
|
|
10268
11347
|
(movingObj) => {
|
|
10269
11348
|
const fabricCanvas = fabricRef.current;
|
|
10270
11349
|
if (!fabricCanvas) return { guides: [], snapDx: 0, snapDy: 0 };
|
|
11350
|
+
const ps = projectSettingsRef.current;
|
|
10271
11351
|
return calculateSnapGuides(
|
|
10272
11352
|
movingObj,
|
|
10273
11353
|
fabricCanvas,
|
|
10274
11354
|
canvasWidth,
|
|
10275
11355
|
canvasHeight,
|
|
10276
|
-
|
|
10277
|
-
|
|
11356
|
+
ps.snapToGuides,
|
|
11357
|
+
ps.snapThreshold
|
|
10278
11358
|
);
|
|
10279
11359
|
},
|
|
10280
|
-
[canvasWidth, canvasHeight
|
|
11360
|
+
[canvasWidth, canvasHeight]
|
|
10281
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]);
|
|
10282
11430
|
const calculateScaleSnapGuidesCallback = react.useCallback(
|
|
10283
11431
|
(scalingObj, corner) => {
|
|
10284
11432
|
const fabricCanvas = fabricRef.current;
|
|
10285
11433
|
if (!fabricCanvas) return [];
|
|
11434
|
+
const ps = projectSettingsRef.current;
|
|
11435
|
+
const excludeIds = getResizeExcludeIdsCallback(scalingObj);
|
|
10286
11436
|
return calculateScaleSnapGuides(
|
|
10287
11437
|
scalingObj,
|
|
10288
11438
|
corner,
|
|
10289
11439
|
fabricCanvas,
|
|
10290
11440
|
canvasWidth,
|
|
10291
11441
|
canvasHeight,
|
|
10292
|
-
|
|
10293
|
-
|
|
11442
|
+
ps.snapToGuides,
|
|
11443
|
+
ps.snapThreshold || 4,
|
|
11444
|
+
getLogicalGroupSnapBoundsCallback(excludeIds)
|
|
10294
11445
|
);
|
|
10295
11446
|
},
|
|
10296
|
-
[canvasWidth, canvasHeight,
|
|
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,
|
|
11470
|
+
canvasWidth,
|
|
11471
|
+
canvasHeight,
|
|
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
|
+
}
|
|
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();
|
|
11532
|
+
},
|
|
11533
|
+
[canvasWidth, canvasHeight, getLogicalGroupSnapBoundsCallback, getResizeExcludeIdsCallback]
|
|
10297
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]);
|
|
10298
11702
|
const isTransforming = react.useCallback((canvas2) => {
|
|
10299
11703
|
if (!canvas2) return false;
|
|
10300
11704
|
return !!canvas2._currentTransform || !!canvas2.__isUserTransforming;
|
|
@@ -10420,6 +11824,8 @@ const PageCanvas = react.forwardRef(
|
|
|
10420
11824
|
// Transparent so underlay (page bg + group bgs) shows through
|
|
10421
11825
|
backgroundColor: "transparent"
|
|
10422
11826
|
});
|
|
11827
|
+
fabricCanvas.hoverCursor = "default";
|
|
11828
|
+
fabricCanvas.moveCursor = "move";
|
|
10423
11829
|
if (!allowSelection) {
|
|
10424
11830
|
fabricCanvas.selection = false;
|
|
10425
11831
|
fabricCanvas.on("selection:created", () => {
|
|
@@ -10441,6 +11847,61 @@ const PageCanvas = react.forwardRef(
|
|
|
10441
11847
|
fabricRef.current = fabricCanvas;
|
|
10442
11848
|
const storeRegistryKey = registerFabricCanvas(pageId, fabricCanvas);
|
|
10443
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
|
+
}
|
|
10444
11905
|
const initFonts = async () => {
|
|
10445
11906
|
try {
|
|
10446
11907
|
await preloadAllFonts();
|
|
@@ -10530,6 +11991,17 @@ const PageCanvas = react.forwardRef(
|
|
|
10530
11991
|
});
|
|
10531
11992
|
fabricCanvas.on("mouse:up", () => {
|
|
10532
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
|
+
}
|
|
10533
12005
|
});
|
|
10534
12006
|
fabricCanvas.on("object:scaling", () => {
|
|
10535
12007
|
fabricCanvas.__isUserTransforming = true;
|
|
@@ -10576,7 +12048,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10576
12048
|
didTransformRef.current = true;
|
|
10577
12049
|
});
|
|
10578
12050
|
const syncSelectionToStore = () => {
|
|
10579
|
-
var _a2,
|
|
12051
|
+
var _a2, _b2, _c, _d;
|
|
10580
12052
|
if (!isActiveRef.current || isRebuildingRef.current || isSyncingSelectionToFabricRef.current || !allowSelection) return;
|
|
10581
12053
|
const walkToTopmostGroup = (childId, children, activeEditingGroupId) => {
|
|
10582
12054
|
let topmost = null;
|
|
@@ -10615,7 +12087,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10615
12087
|
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
10616
12088
|
const clickedId = ids[0];
|
|
10617
12089
|
const state = useEditorStore.getState();
|
|
10618
|
-
const currentPage2 = (
|
|
12090
|
+
const currentPage2 = (_b2 = state.canvas.pages) == null ? void 0 : _b2.find((p) => p.id === pageId);
|
|
10619
12091
|
const children = (currentPage2 == null ? void 0 : currentPage2.children) ?? [];
|
|
10620
12092
|
const parent = walkToTopmostGroup(clickedId, children, activeEditingGroupId);
|
|
10621
12093
|
const targetIsInCrop = !!(active instanceof fabric__namespace.Group && isCropGroupInCropMode(active) || (active == null ? void 0 : active.group) instanceof fabric__namespace.Group && isCropGroupInCropMode(active.group));
|
|
@@ -10762,8 +12234,10 @@ const PageCanvas = react.forwardRef(
|
|
|
10762
12234
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10763
12235
|
if (activeObj instanceof fabric__namespace.ActiveSelection) applyWarpAwareSelectionBorders(activeObj);
|
|
10764
12236
|
if (activeObj) applyControlSizeForZoom(fabricCanvas, activeObj);
|
|
12237
|
+
if (activeObj) ensureCanvaControlRenders(activeObj);
|
|
10765
12238
|
if (activeObj && !(activeObj instanceof fabric__namespace.ActiveSelection) && (((_a2 = activeObj._ct) == null ? void 0 : _a2.isCropGroup) || activeObj.__cropGroup)) {
|
|
10766
|
-
|
|
12239
|
+
installImageResizeControlsWithSnap(activeObj);
|
|
12240
|
+
ensureCanvaControlRenders(activeObj);
|
|
10767
12241
|
}
|
|
10768
12242
|
});
|
|
10769
12243
|
fabricCanvas.on("selection:updated", () => {
|
|
@@ -10775,12 +12249,14 @@ const PageCanvas = react.forwardRef(
|
|
|
10775
12249
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10776
12250
|
if (activeObj instanceof fabric__namespace.ActiveSelection) applyWarpAwareSelectionBorders(activeObj);
|
|
10777
12251
|
if (activeObj) applyControlSizeForZoom(fabricCanvas, activeObj);
|
|
12252
|
+
if (activeObj) ensureCanvaControlRenders(activeObj);
|
|
10778
12253
|
if (activeObj && !(activeObj instanceof fabric__namespace.ActiveSelection) && (((_a2 = activeObj._ct) == null ? void 0 : _a2.isCropGroup) || activeObj.__cropGroup)) {
|
|
10779
|
-
|
|
12254
|
+
installImageResizeControlsWithSnap(activeObj);
|
|
12255
|
+
ensureCanvaControlRenders(activeObj);
|
|
10780
12256
|
}
|
|
10781
12257
|
});
|
|
10782
12258
|
fabricCanvas.on("mouse:dblclick", (opt) => {
|
|
10783
|
-
var _a2,
|
|
12259
|
+
var _a2, _b2;
|
|
10784
12260
|
const target = opt == null ? void 0 : opt.target;
|
|
10785
12261
|
if (!target) return;
|
|
10786
12262
|
if (target.isEditing) return;
|
|
@@ -10804,7 +12280,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10804
12280
|
const childId = getObjectId(hitChild);
|
|
10805
12281
|
if (!childId) return;
|
|
10806
12282
|
const stateNow = useEditorStore.getState();
|
|
10807
|
-
const pageNow = (
|
|
12283
|
+
const pageNow = (_b2 = stateNow.canvas.pages) == null ? void 0 : _b2.find((p) => p.id === pageId);
|
|
10808
12284
|
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
10809
12285
|
const chain = [];
|
|
10810
12286
|
{
|
|
@@ -10931,7 +12407,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10931
12407
|
transformingIdsRef.current.clear();
|
|
10932
12408
|
};
|
|
10933
12409
|
const prepareGroupSelectionTransformStart = (target) => {
|
|
10934
|
-
var _a2,
|
|
12410
|
+
var _a2, _b2;
|
|
10935
12411
|
const active = target instanceof fabric__namespace.ActiveSelection ? target : fabricCanvas.getActiveObject();
|
|
10936
12412
|
if (!(active instanceof fabric__namespace.ActiveSelection)) return;
|
|
10937
12413
|
if (!activeSelectionMoveStartRef.current || activeSelectionMoveStartRef.current.selection !== active) {
|
|
@@ -10945,7 +12421,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10945
12421
|
const groupId = active.__pixldocsGroupSelection;
|
|
10946
12422
|
if (!groupId) return;
|
|
10947
12423
|
if (((_a2 = groupSelectionTransformStartRef.current) == null ? void 0 : _a2.groupId) === groupId && groupSelectionTransformStartRef.current.selection === active) return;
|
|
10948
|
-
const pageChildren2 = ((
|
|
12424
|
+
const pageChildren2 = ((_b2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
|
|
10949
12425
|
const groupNode = findNodeById(pageChildren2, groupId);
|
|
10950
12426
|
if (!groupNode) return;
|
|
10951
12427
|
const groupAbs = getAbsoluteBounds(groupNode, pageChildren2);
|
|
@@ -11029,7 +12505,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11029
12505
|
};
|
|
11030
12506
|
let pendingShiftMultiSelect = null;
|
|
11031
12507
|
const applyShiftMultiSelect = (target, event, baselineActive = fabricCanvas.getActiveObject(), baselineObjects = fabricCanvas.getActiveObjects()) => {
|
|
11032
|
-
var _a2,
|
|
12508
|
+
var _a2, _b2, _c;
|
|
11033
12509
|
if (!target || !target.selectable) return false;
|
|
11034
12510
|
const active = baselineActive;
|
|
11035
12511
|
if (!active || ((_a2 = active.getActiveControl) == null ? void 0 : _a2.call(active))) return false;
|
|
@@ -11063,7 +12539,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11063
12539
|
isSyncingSelectionToFabricRef.current = false;
|
|
11064
12540
|
});
|
|
11065
12541
|
}
|
|
11066
|
-
(
|
|
12542
|
+
(_b2 = event == null ? void 0 : event.preventDefault) == null ? void 0 : _b2.call(event);
|
|
11067
12543
|
(_c = event == null ? void 0 : event.stopPropagation) == null ? void 0 : _c.call(event);
|
|
11068
12544
|
return true;
|
|
11069
12545
|
};
|
|
@@ -11114,9 +12590,9 @@ const PageCanvas = react.forwardRef(
|
|
|
11114
12590
|
return !!(((_a2 = o == null ? void 0 : o._ct) == null ? void 0 : _a2.isCropGroup) || (o == null ? void 0 : o.__cropGroup));
|
|
11115
12591
|
};
|
|
11116
12592
|
const promoteToCropGroup = (opt) => {
|
|
11117
|
-
var _a2,
|
|
12593
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
11118
12594
|
const t = opt.target;
|
|
11119
|
-
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") {
|
|
11120
12596
|
if (t && isCropGroup2(t)) {
|
|
11121
12597
|
fabricCanvas._hoveredTarget = t;
|
|
11122
12598
|
} else if ((t == null ? void 0 : t.group) && isCropGroup2(t.group)) {
|
|
@@ -11132,6 +12608,8 @@ const PageCanvas = react.forwardRef(
|
|
|
11132
12608
|
const objects = fabricCanvas.getObjects();
|
|
11133
12609
|
for (const obj of objects) {
|
|
11134
12610
|
if (isCropGroup2(obj) && obj.containsPoint(pointer)) {
|
|
12611
|
+
installImageResizeControlsWithSnap(obj);
|
|
12612
|
+
ensureCanvaControlRenders(obj);
|
|
11135
12613
|
fabricCanvas.setActiveObject(obj);
|
|
11136
12614
|
opt.target = obj;
|
|
11137
12615
|
fabricCanvas._hoveredTarget = obj;
|
|
@@ -11142,12 +12620,16 @@ const PageCanvas = react.forwardRef(
|
|
|
11142
12620
|
}
|
|
11143
12621
|
const g = t.group;
|
|
11144
12622
|
if (g && isCropGroup2(g)) {
|
|
12623
|
+
installImageResizeControlsWithSnap(g);
|
|
12624
|
+
ensureCanvaControlRenders(g);
|
|
11145
12625
|
fabricCanvas.setActiveObject(g);
|
|
11146
12626
|
opt.target = g;
|
|
11147
12627
|
fabricCanvas._hoveredTarget = g;
|
|
11148
12628
|
return;
|
|
11149
12629
|
}
|
|
11150
12630
|
if (isCropGroup2(t)) {
|
|
12631
|
+
installImageResizeControlsWithSnap(t);
|
|
12632
|
+
ensureCanvaControlRenders(t);
|
|
11151
12633
|
fabricCanvas.setActiveObject(t);
|
|
11152
12634
|
t.set({
|
|
11153
12635
|
selectable: true,
|
|
@@ -11200,7 +12682,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11200
12682
|
});
|
|
11201
12683
|
}
|
|
11202
12684
|
fabricCanvas.on("mouse:down", (opt) => {
|
|
11203
|
-
var _a2,
|
|
12685
|
+
var _a2, _b2;
|
|
11204
12686
|
if (pendingShiftMultiSelect) {
|
|
11205
12687
|
const pending = pendingShiftMultiSelect;
|
|
11206
12688
|
pendingShiftMultiSelect = null;
|
|
@@ -11208,17 +12690,19 @@ const PageCanvas = react.forwardRef(
|
|
|
11208
12690
|
return;
|
|
11209
12691
|
}
|
|
11210
12692
|
const target = opt.target;
|
|
11211
|
-
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;
|
|
11212
12694
|
if (cropGroup) {
|
|
11213
12695
|
lockEdits();
|
|
11214
12696
|
didTransformRef.current = false;
|
|
12697
|
+
installImageResizeControlsWithSnap(cropGroup);
|
|
12698
|
+
ensureCanvaControlRenders(cropGroup);
|
|
11215
12699
|
fabricCanvas.setActiveObject(cropGroup);
|
|
11216
12700
|
cropGroup.setCoords();
|
|
11217
12701
|
fabricCanvas.requestRenderAll();
|
|
11218
12702
|
}
|
|
11219
12703
|
});
|
|
11220
12704
|
const groupFabricUnionBBox = (g) => {
|
|
11221
|
-
var _a2,
|
|
12705
|
+
var _a2, _b2;
|
|
11222
12706
|
const memberIds = new Set(getAllElementIds(g.children ?? []));
|
|
11223
12707
|
if (memberIds.size === 0) return null;
|
|
11224
12708
|
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
@@ -11226,7 +12710,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11226
12710
|
for (const o of fabricCanvas.getObjects()) {
|
|
11227
12711
|
const oid = getObjectId(o);
|
|
11228
12712
|
if (!oid || !memberIds.has(oid)) continue;
|
|
11229
|
-
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));
|
|
11230
12714
|
if (!br) continue;
|
|
11231
12715
|
minX = Math.min(minX, br.left);
|
|
11232
12716
|
minY = Math.min(minY, br.top);
|
|
@@ -11252,13 +12736,13 @@ const PageCanvas = react.forwardRef(
|
|
|
11252
12736
|
return pick;
|
|
11253
12737
|
};
|
|
11254
12738
|
fabricCanvas.on("mouse:down:before", (opt) => {
|
|
11255
|
-
var _a2,
|
|
12739
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
|
|
11256
12740
|
if (editLockRef.current) {
|
|
11257
12741
|
const active = fabricCanvas.getActiveObject();
|
|
11258
12742
|
if (active && (((_a2 = active._ct) == null ? void 0 : _a2.isCropGroup) || active.__cropGroup)) {
|
|
11259
12743
|
opt.target = active;
|
|
11260
12744
|
if (opt.e) {
|
|
11261
|
-
(_c = (
|
|
12745
|
+
(_c = (_b2 = opt.e).preventDefault) == null ? void 0 : _c.call(_b2);
|
|
11262
12746
|
(_e = (_d = opt.e).stopPropagation) == null ? void 0 : _e.call(_d);
|
|
11263
12747
|
}
|
|
11264
12748
|
}
|
|
@@ -11268,11 +12752,34 @@ const PageCanvas = react.forwardRef(
|
|
|
11268
12752
|
syncLockedRef.current = true;
|
|
11269
12753
|
lockEdits();
|
|
11270
12754
|
}
|
|
11271
|
-
|
|
11272
|
-
|
|
12755
|
+
let target = opt.target;
|
|
12756
|
+
let targetId = target ? getObjectId(target) : null;
|
|
12757
|
+
if (target instanceof fabric__namespace.ActiveSelection && target.__pixldocsGroupSelection && target === fabricCanvas.getActiveObject()) {
|
|
12758
|
+
try {
|
|
12759
|
+
const pointer = fabricCanvas.getViewportPoint(opt.e);
|
|
12760
|
+
const members = target.getObjects();
|
|
12761
|
+
for (let i = members.length - 1; i >= 0; i--) {
|
|
12762
|
+
const m = members[i];
|
|
12763
|
+
if (m.visible === false) continue;
|
|
12764
|
+
if (typeof m.containsPoint === "function" && m.containsPoint(pointer)) {
|
|
12765
|
+
const mid = getObjectId(m);
|
|
12766
|
+
if (mid) {
|
|
12767
|
+
target = m;
|
|
12768
|
+
targetId = mid;
|
|
12769
|
+
}
|
|
12770
|
+
break;
|
|
12771
|
+
}
|
|
12772
|
+
}
|
|
12773
|
+
} catch {
|
|
12774
|
+
}
|
|
12775
|
+
}
|
|
11273
12776
|
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
11274
12777
|
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
11275
12778
|
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
12779
|
+
if (target instanceof fabric__namespace.Textbox && target.__corner && (target.__corner === "ml" || target.__corner === "mr")) {
|
|
12780
|
+
const sourceEl = targetId ? elementsRef.current.find((el) => el.id === targetId) : void 0;
|
|
12781
|
+
bakeTextboxScaleIntoTypography(target, sourceEl);
|
|
12782
|
+
}
|
|
11276
12783
|
if (isMultiSelectModifier(opt.e)) {
|
|
11277
12784
|
const manualTarget = target && !(target instanceof fabric__namespace.ActiveSelection) && targetId && targetId !== "__background__" ? target : pickSelectableObjectAtPointer(opt.e);
|
|
11278
12785
|
if (manualTarget) {
|
|
@@ -11299,11 +12806,39 @@ const PageCanvas = react.forwardRef(
|
|
|
11299
12806
|
return topmost;
|
|
11300
12807
|
};
|
|
11301
12808
|
if (target && targetId && targetId !== "__background__") {
|
|
11302
|
-
|
|
11303
|
-
|
|
12809
|
+
let effectiveTarget = target;
|
|
12810
|
+
let effectiveTargetId = targetId;
|
|
12811
|
+
const activeNowEarly = fabricCanvas.getActiveObject();
|
|
12812
|
+
const asGroupId = target instanceof fabric__namespace.ActiveSelection ? target.__pixldocsGroupSelection : void 0;
|
|
12813
|
+
if (target instanceof fabric__namespace.ActiveSelection && asGroupId && target === activeNowEarly) {
|
|
12814
|
+
try {
|
|
12815
|
+
const pointer = fabricCanvas.getViewportPoint(opt.e);
|
|
12816
|
+
const members = target.getObjects();
|
|
12817
|
+
for (let i = members.length - 1; i >= 0; i--) {
|
|
12818
|
+
const m = members[i];
|
|
12819
|
+
if (m.visible === false) continue;
|
|
12820
|
+
if (typeof m.containsPoint === "function" && m.containsPoint(pointer)) {
|
|
12821
|
+
const mid = getObjectId(m);
|
|
12822
|
+
if (mid) {
|
|
12823
|
+
effectiveTarget = m;
|
|
12824
|
+
effectiveTargetId = mid;
|
|
12825
|
+
}
|
|
12826
|
+
break;
|
|
12827
|
+
}
|
|
12828
|
+
}
|
|
12829
|
+
} catch {
|
|
12830
|
+
}
|
|
12831
|
+
}
|
|
12832
|
+
const parent = findTopmostPromotableGroup(effectiveTargetId);
|
|
12833
|
+
const targetIsInCrop = !!(effectiveTarget instanceof fabric__namespace.Group && isCropGroupInCropMode(effectiveTarget) || (effectiveTarget == null ? void 0 : effectiveTarget.group) instanceof fabric__namespace.Group && isCropGroupInCropMode(effectiveTarget.group));
|
|
11304
12834
|
const activeNow = fabricCanvas.getActiveObject();
|
|
11305
12835
|
const alreadyThisGroup = activeNow instanceof fabric__namespace.ActiveSelection && activeNow.__pixldocsGroupSelection === (parent == null ? void 0 : parent.id);
|
|
11306
12836
|
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));
|
|
12837
|
+
const isDeepSelectKey = !!((_i = opt.e) == null ? void 0 : _i.altKey);
|
|
12838
|
+
if (isDeepSelectKey) {
|
|
12839
|
+
pendingGroupPromotionRef.current = null;
|
|
12840
|
+
return;
|
|
12841
|
+
}
|
|
11307
12842
|
if (parent && !parent.backgroundColor && !targetIsInCrop && activeEditingGroupId !== parent.id && !alreadyThisGroup && !isMultiSelectKey) {
|
|
11308
12843
|
const memberIds = new Set(getAllElementIds(parent.children ?? []));
|
|
11309
12844
|
const memberObjs = fabricCanvas.getObjects().filter((o) => {
|
|
@@ -11327,10 +12862,33 @@ const PageCanvas = react.forwardRef(
|
|
|
11327
12862
|
opt.target = only;
|
|
11328
12863
|
pendingGroupPromotionRef.current = { groupId: parent.id, selection: only };
|
|
11329
12864
|
}
|
|
12865
|
+
} else if (parent && !parent.backgroundColor && !targetIsInCrop && alreadyThisGroup && !isMultiSelectKey && effectiveTarget !== activeNow) {
|
|
12866
|
+
try {
|
|
12867
|
+
skipSelectionClearOnDiscardRef.current = true;
|
|
12868
|
+
preserveEditingScopeOnSelectionClearRef.current = true;
|
|
12869
|
+
restoreSuppressedGroupBorders();
|
|
12870
|
+
fabricCanvas.discardActiveObject();
|
|
12871
|
+
} finally {
|
|
12872
|
+
skipSelectionClearOnDiscardRef.current = false;
|
|
12873
|
+
preserveEditingScopeOnSelectionClearRef.current = false;
|
|
12874
|
+
}
|
|
12875
|
+
fabricCanvas.__activeEditingGroupId = parent.id;
|
|
12876
|
+
delete effectiveTarget.__pixldocsGroupSelection;
|
|
12877
|
+
delete effectiveTarget.__pixldocsLogicalGroupIds;
|
|
12878
|
+
try {
|
|
12879
|
+
(_j = effectiveTarget.set) == null ? void 0 : _j.call(effectiveTarget, { selectable: true, evented: true, hasBorders: true, hasControls: true });
|
|
12880
|
+
} catch {
|
|
12881
|
+
}
|
|
12882
|
+
fabricCanvas.setActiveObject(effectiveTarget);
|
|
12883
|
+
effectiveTarget.setCoords();
|
|
12884
|
+
fabricCanvas._target = effectiveTarget;
|
|
12885
|
+
opt.target = effectiveTarget;
|
|
12886
|
+
pendingGroupPromotionRef.current = null;
|
|
11330
12887
|
}
|
|
11331
12888
|
} else if (!target || targetId === "__background__") {
|
|
11332
|
-
const isMultiSelectKey = !!(((
|
|
12889
|
+
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));
|
|
11333
12890
|
if (isMultiSelectKey) return;
|
|
12891
|
+
if ((_n = opt.e) == null ? void 0 : _n.altKey) return;
|
|
11334
12892
|
try {
|
|
11335
12893
|
const pointer = fabricCanvas.getPointer(opt.e);
|
|
11336
12894
|
const px = pointer.x;
|
|
@@ -11403,11 +12961,28 @@ const PageCanvas = react.forwardRef(
|
|
|
11403
12961
|
const tid = t ? getObjectId(t) : null;
|
|
11404
12962
|
try {
|
|
11405
12963
|
const activeIds = new Set(selectedIdsRef.current);
|
|
12964
|
+
const pointer = fabricCanvas.getPointer(opt.e);
|
|
12965
|
+
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
12966
|
+
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
12967
|
+
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
12968
|
+
const groupPick = pickGroupAtPointer(pointer.x, pointer.y, childrenNow, activeEditingGroupId);
|
|
12969
|
+
if (groupPick && !activeIds.has(groupPick.group.id)) {
|
|
12970
|
+
const b = groupFabricUnionBBox(groupPick.group);
|
|
12971
|
+
if (b) {
|
|
12972
|
+
setHoverBounds({
|
|
12973
|
+
left: b.left,
|
|
12974
|
+
top: b.top,
|
|
12975
|
+
width: b.right - b.left,
|
|
12976
|
+
height: b.bottom - b.top,
|
|
12977
|
+
angle: 0
|
|
12978
|
+
});
|
|
12979
|
+
return;
|
|
12980
|
+
}
|
|
12981
|
+
}
|
|
11406
12982
|
const isHoveringSelected = !!(tid && activeIds.has(tid));
|
|
11407
12983
|
if (t && tid && tid !== "__background__" && !isHoveringSelected) {
|
|
11408
|
-
|
|
11409
|
-
|
|
11410
|
-
const br = outer.getBoundingRect();
|
|
12984
|
+
t.setCoords();
|
|
12985
|
+
const br = t.getBoundingRect();
|
|
11411
12986
|
setHoverBounds({
|
|
11412
12987
|
left: br.left,
|
|
11413
12988
|
top: br.top,
|
|
@@ -11428,7 +13003,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11428
13003
|
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
11429
13004
|
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
11430
13005
|
const pick = pickGroupAtPointer(pointer.x, pointer.y, childrenNow, activeEditingGroupId);
|
|
11431
|
-
fabricCanvas.defaultCursor =
|
|
13006
|
+
fabricCanvas.defaultCursor = "default";
|
|
11432
13007
|
} catch {
|
|
11433
13008
|
fabricCanvas.defaultCursor = "default";
|
|
11434
13009
|
}
|
|
@@ -11436,6 +13011,11 @@ const PageCanvas = react.forwardRef(
|
|
|
11436
13011
|
fabricCanvas.on("mouse:out", () => {
|
|
11437
13012
|
setHoverBounds(null);
|
|
11438
13013
|
});
|
|
13014
|
+
fabricCanvas.on("mouse:down", () => {
|
|
13015
|
+
setHoverBounds(null);
|
|
13016
|
+
});
|
|
13017
|
+
fabricCanvas.on("selection:created", () => setHoverBounds(null));
|
|
13018
|
+
fabricCanvas.on("selection:updated", () => setHoverBounds(null));
|
|
11439
13019
|
fabricCanvas.on("mouse:down", (ev) => {
|
|
11440
13020
|
if (fabricCanvas._currentTransform) {
|
|
11441
13021
|
lockEdits();
|
|
@@ -11451,6 +13031,8 @@ const PageCanvas = react.forwardRef(
|
|
|
11451
13031
|
setGuides([]);
|
|
11452
13032
|
setRotationLabel(null);
|
|
11453
13033
|
setSizeLabel(null);
|
|
13034
|
+
objectResizeActiveSnapRef.current = null;
|
|
13035
|
+
groupResizeActiveSnapRef.current = null;
|
|
11454
13036
|
dragStarted = false;
|
|
11455
13037
|
const pendingPromotion = pendingGroupPromotionRef.current;
|
|
11456
13038
|
pendingGroupPromotionRef.current = null;
|
|
@@ -11605,7 +13187,9 @@ const PageCanvas = react.forwardRef(
|
|
|
11605
13187
|
const intrH = obj.height ?? 1;
|
|
11606
13188
|
let newW = Math.max(1, intrW * Math.abs(sx));
|
|
11607
13189
|
let newH = Math.max(1, intrH * Math.abs(sy));
|
|
11608
|
-
if (obj instanceof fabric__namespace.
|
|
13190
|
+
if (obj instanceof fabric__namespace.Ellipse) {
|
|
13191
|
+
obj.set({ rx: newW / 2, ry: newH / 2 });
|
|
13192
|
+
} else if (obj instanceof fabric__namespace.Circle) {
|
|
11609
13193
|
const diameter = Math.max(1, Math.min(newW, newH));
|
|
11610
13194
|
newW = diameter;
|
|
11611
13195
|
newH = diameter;
|
|
@@ -11722,8 +13306,128 @@ const PageCanvas = react.forwardRef(
|
|
|
11722
13306
|
}
|
|
11723
13307
|
const transform = e.transform;
|
|
11724
13308
|
const corner = (transform == null ? void 0 : transform.corner) || "";
|
|
13309
|
+
if (obj instanceof fabric__namespace.ActiveSelection && (corner === "ml" || corner === "mr" || corner === "mt" || corner === "mb")) {
|
|
13310
|
+
const isXSide = corner === "ml" || corner === "mr";
|
|
13311
|
+
const sAxis = isXSide ? Math.abs(obj.scaleX ?? 1) : Math.abs(obj.scaleY ?? 1);
|
|
13312
|
+
if (sAxis > 1e-3) {
|
|
13313
|
+
for (const child of obj.getObjects()) {
|
|
13314
|
+
if (!(child instanceof fabric__namespace.Textbox)) continue;
|
|
13315
|
+
if (isXSide) {
|
|
13316
|
+
if (child.__asLiveOrigW == null) {
|
|
13317
|
+
child.__asLiveOrigW = (child.width ?? 0) * (child.scaleX ?? 1);
|
|
13318
|
+
}
|
|
13319
|
+
const origW = child.__asLiveOrigW;
|
|
13320
|
+
const newW = Math.max(20, origW * sAxis);
|
|
13321
|
+
if (Math.abs((child.width ?? 0) - newW) > 0.5) {
|
|
13322
|
+
child.set({ width: newW, scaleX: 1 / sAxis });
|
|
13323
|
+
try {
|
|
13324
|
+
child.initDimensions();
|
|
13325
|
+
} catch {
|
|
13326
|
+
}
|
|
13327
|
+
child.dirty = true;
|
|
13328
|
+
}
|
|
13329
|
+
} else {
|
|
13330
|
+
if (child.__asLiveOrigH == null) {
|
|
13331
|
+
child.__asLiveOrigH = (child.height ?? 0) * (child.scaleY ?? 1);
|
|
13332
|
+
}
|
|
13333
|
+
const origH = child.__asLiveOrigH;
|
|
13334
|
+
const newH = Math.max(20, origH * sAxis);
|
|
13335
|
+
child.minBoxHeight = newH;
|
|
13336
|
+
child.set({ scaleY: 1 / sAxis });
|
|
13337
|
+
try {
|
|
13338
|
+
child.initDimensions();
|
|
13339
|
+
} catch {
|
|
13340
|
+
}
|
|
13341
|
+
child.dirty = true;
|
|
13342
|
+
}
|
|
13343
|
+
}
|
|
13344
|
+
}
|
|
13345
|
+
}
|
|
13346
|
+
snapDuringScaleCallback(obj, corner);
|
|
11725
13347
|
const scaleGuides = calculateScaleSnapGuidesCallback(obj, corner);
|
|
11726
|
-
|
|
13348
|
+
const gridGuidesForScale = [];
|
|
13349
|
+
try {
|
|
13350
|
+
const psGrid = projectSettingsRef.current;
|
|
13351
|
+
const canApplyGridSnap = psGrid.snapToGrid && corner && !obj.__cropGroup && !obj.__resizeSnapHandler;
|
|
13352
|
+
if (canApplyGridSnap) {
|
|
13353
|
+
const gridX = psGrid.gridSizeX ?? psGrid.gridSize ?? 0;
|
|
13354
|
+
const gridY = psGrid.gridSizeY ?? psGrid.gridSize ?? 0;
|
|
13355
|
+
if (gridX > 0 && gridY > 0) {
|
|
13356
|
+
obj.setCoords();
|
|
13357
|
+
const br = obj.getBoundingRect();
|
|
13358
|
+
if (br.width > 1 && br.height > 1) {
|
|
13359
|
+
const hasL = corner.includes("l");
|
|
13360
|
+
const hasR = corner.includes("r");
|
|
13361
|
+
const hasT = corner.includes("t");
|
|
13362
|
+
const hasB = corner.includes("b");
|
|
13363
|
+
const anchorRight = br.left + br.width;
|
|
13364
|
+
const anchorBottom = br.top + br.height;
|
|
13365
|
+
let newLeft = br.left;
|
|
13366
|
+
let newTop = br.top;
|
|
13367
|
+
let newWidth = br.width;
|
|
13368
|
+
let newHeight = br.height;
|
|
13369
|
+
const xAlreadySnapped = scaleGuides.some((g) => g.type === "vertical");
|
|
13370
|
+
const yAlreadySnapped = scaleGuides.some((g) => g.type === "horizontal");
|
|
13371
|
+
if (!xAlreadySnapped) {
|
|
13372
|
+
if (hasL) {
|
|
13373
|
+
const nL = Math.round(br.left / gridX) * gridX;
|
|
13374
|
+
newWidth = Math.max(20, anchorRight - nL);
|
|
13375
|
+
newLeft = anchorRight - newWidth;
|
|
13376
|
+
} else if (hasR) {
|
|
13377
|
+
const nR = Math.round(anchorRight / gridX) * gridX;
|
|
13378
|
+
newWidth = Math.max(20, nR - br.left);
|
|
13379
|
+
}
|
|
13380
|
+
}
|
|
13381
|
+
if (!yAlreadySnapped) {
|
|
13382
|
+
if (hasT) {
|
|
13383
|
+
const nT = Math.round(br.top / gridY) * gridY;
|
|
13384
|
+
newHeight = Math.max(20, anchorBottom - nT);
|
|
13385
|
+
newTop = anchorBottom - newHeight;
|
|
13386
|
+
} else if (hasB) {
|
|
13387
|
+
const nB = Math.round(anchorBottom / gridY) * gridY;
|
|
13388
|
+
newHeight = Math.max(20, nB - br.top);
|
|
13389
|
+
}
|
|
13390
|
+
}
|
|
13391
|
+
const widthChanged = Math.abs(newWidth - br.width) > 0.5;
|
|
13392
|
+
const heightChanged = Math.abs(newHeight - br.height) > 0.5;
|
|
13393
|
+
if (widthChanged || heightChanged) {
|
|
13394
|
+
const isTextWidth = obj instanceof fabric__namespace.Textbox && widthChanged && !heightChanged;
|
|
13395
|
+
if (isTextWidth) {
|
|
13396
|
+
obj.set({ width: Math.max(20, newWidth) });
|
|
13397
|
+
try {
|
|
13398
|
+
obj.initDimensions();
|
|
13399
|
+
} catch {
|
|
13400
|
+
}
|
|
13401
|
+
} else {
|
|
13402
|
+
const ratioX = widthChanged ? newWidth / br.width : 1;
|
|
13403
|
+
const ratioY = heightChanged ? newHeight / br.height : 1;
|
|
13404
|
+
const curSx = obj.scaleX ?? 1;
|
|
13405
|
+
const curSy = obj.scaleY ?? 1;
|
|
13406
|
+
obj.set({ scaleX: curSx * ratioX, scaleY: curSy * ratioY });
|
|
13407
|
+
}
|
|
13408
|
+
obj.setCoords();
|
|
13409
|
+
const after = obj.getBoundingRect();
|
|
13410
|
+
const dx = newLeft - after.left;
|
|
13411
|
+
const dy = newTop - after.top;
|
|
13412
|
+
if (Math.abs(dx) > 0.01 || Math.abs(dy) > 0.01) {
|
|
13413
|
+
obj.set({ left: (obj.left ?? 0) + dx, top: (obj.top ?? 0) + dy });
|
|
13414
|
+
obj.setCoords();
|
|
13415
|
+
}
|
|
13416
|
+
if (!xAlreadySnapped) {
|
|
13417
|
+
if (hasL) gridGuidesForScale.push({ type: "vertical", position: newLeft, kind: "grid" });
|
|
13418
|
+
else if (hasR) gridGuidesForScale.push({ type: "vertical", position: newLeft + newWidth, kind: "grid" });
|
|
13419
|
+
}
|
|
13420
|
+
if (!yAlreadySnapped) {
|
|
13421
|
+
if (hasT) gridGuidesForScale.push({ type: "horizontal", position: newTop, kind: "grid" });
|
|
13422
|
+
else if (hasB) gridGuidesForScale.push({ type: "horizontal", position: newTop + newHeight, kind: "grid" });
|
|
13423
|
+
}
|
|
13424
|
+
}
|
|
13425
|
+
}
|
|
13426
|
+
}
|
|
13427
|
+
}
|
|
13428
|
+
} catch {
|
|
13429
|
+
}
|
|
13430
|
+
setGuides(gridGuidesForScale.length ? [...scaleGuides, ...gridGuidesForScale] : scaleGuides);
|
|
11727
13431
|
});
|
|
11728
13432
|
fabricCanvas.on("object:resizing", (e) => {
|
|
11729
13433
|
if (!isActiveRef.current) return;
|
|
@@ -11749,13 +13453,70 @@ const PageCanvas = react.forwardRef(
|
|
|
11749
13453
|
}
|
|
11750
13454
|
const transform = e.transform;
|
|
11751
13455
|
const corner = (transform == null ? void 0 : transform.corner) || "";
|
|
13456
|
+
if (obj instanceof fabric__namespace.Textbox && (corner === "ml" || corner === "mr")) {
|
|
13457
|
+
const objId = getObjectId(obj);
|
|
13458
|
+
const sourceEl = objId ? elementsRef.current.find((el) => el.id === objId) : void 0;
|
|
13459
|
+
bakeTextboxScaleIntoTypography(obj, sourceEl);
|
|
13460
|
+
}
|
|
13461
|
+
snapDuringScaleCallback(obj, corner);
|
|
11752
13462
|
const scaleGuides = calculateScaleSnapGuidesCallback(obj, corner);
|
|
11753
|
-
|
|
13463
|
+
const gridGuidesForTextResize = [];
|
|
13464
|
+
try {
|
|
13465
|
+
const psGrid = projectSettingsRef.current;
|
|
13466
|
+
if (psGrid.snapToGrid && corner && obj instanceof fabric__namespace.Textbox && (corner === "ml" || corner === "mr")) {
|
|
13467
|
+
const gridX = psGrid.gridSizeX ?? psGrid.gridSize ?? 0;
|
|
13468
|
+
if (gridX > 0) {
|
|
13469
|
+
obj.setCoords();
|
|
13470
|
+
const br = obj.getBoundingRect();
|
|
13471
|
+
const xAlreadySnapped = scaleGuides.some((g) => g.type === "vertical");
|
|
13472
|
+
if (!xAlreadySnapped && br.width > 1) {
|
|
13473
|
+
const anchorRight = br.left + br.width;
|
|
13474
|
+
let newLeft = br.left;
|
|
13475
|
+
let newWidth = br.width;
|
|
13476
|
+
if (corner === "ml") {
|
|
13477
|
+
const nL = Math.round(br.left / gridX) * gridX;
|
|
13478
|
+
newWidth = Math.max(20, anchorRight - nL);
|
|
13479
|
+
newLeft = anchorRight - newWidth;
|
|
13480
|
+
} else {
|
|
13481
|
+
const nR = Math.round(anchorRight / gridX) * gridX;
|
|
13482
|
+
newWidth = Math.max(20, nR - br.left);
|
|
13483
|
+
}
|
|
13484
|
+
if (Math.abs(newWidth - br.width) > 0.5) {
|
|
13485
|
+
obj.set({ width: Math.max(20, newWidth) });
|
|
13486
|
+
try {
|
|
13487
|
+
obj.initDimensions();
|
|
13488
|
+
} catch {
|
|
13489
|
+
}
|
|
13490
|
+
obj.setCoords();
|
|
13491
|
+
const after = obj.getBoundingRect();
|
|
13492
|
+
const dx = newLeft - after.left;
|
|
13493
|
+
if (Math.abs(dx) > 0.01) {
|
|
13494
|
+
obj.set({ left: (obj.left ?? 0) + dx });
|
|
13495
|
+
obj.setCoords();
|
|
13496
|
+
}
|
|
13497
|
+
gridGuidesForTextResize.push({
|
|
13498
|
+
type: "vertical",
|
|
13499
|
+
position: corner === "ml" ? newLeft : newLeft + newWidth,
|
|
13500
|
+
kind: "grid"
|
|
13501
|
+
});
|
|
13502
|
+
}
|
|
13503
|
+
}
|
|
13504
|
+
}
|
|
13505
|
+
}
|
|
13506
|
+
} catch {
|
|
13507
|
+
}
|
|
13508
|
+
setGuides(gridGuidesForTextResize.length ? [...scaleGuides, ...gridGuidesForTextResize] : scaleGuides);
|
|
11754
13509
|
});
|
|
11755
13510
|
fabricCanvas.on("object:rotating", (e) => {
|
|
11756
13511
|
markSimpleTransform(e);
|
|
11757
13512
|
didTransformRef.current = true;
|
|
11758
13513
|
const tr = e.target;
|
|
13514
|
+
try {
|
|
13515
|
+
const getCursor = fabricCanvas.__pixldocsGetRotateCursor;
|
|
13516
|
+
const upper = fabricCanvas.upperCanvasEl;
|
|
13517
|
+
if (typeof getCursor === "function" && upper && tr) upper.style.cursor = getCursor(tr);
|
|
13518
|
+
} catch {
|
|
13519
|
+
}
|
|
11759
13520
|
const rotateTargetId = tr ? getObjectId(tr) : null;
|
|
11760
13521
|
if (rotateTargetId && rotateTargetId !== "__background__") {
|
|
11761
13522
|
preserveSelectionAfterTransformIdRef.current = rotateTargetId;
|
|
@@ -11782,6 +13543,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11782
13543
|
prepareGroupSelectionTransformStart(e.target);
|
|
11783
13544
|
markTransforming(e.target);
|
|
11784
13545
|
didTransformRef.current = true;
|
|
13546
|
+
if (e.target) e.target.__pixldocsDragMoved = true;
|
|
11785
13547
|
const moveTargetId = e.target ? getObjectId(e.target) : null;
|
|
11786
13548
|
if (moveTargetId && moveTargetId !== "__background__") {
|
|
11787
13549
|
preserveSelectionAfterTransformIdRef.current = moveTargetId;
|
|
@@ -11798,20 +13560,57 @@ const PageCanvas = react.forwardRef(
|
|
|
11798
13560
|
if (!obj) return;
|
|
11799
13561
|
const snapTarget = fabricCanvas.getActiveObject() ?? obj;
|
|
11800
13562
|
const { guides: newGuides, snapDx, snapDy } = calculateSnapGuidesCallback(snapTarget);
|
|
11801
|
-
|
|
13563
|
+
let finalDx = snapDx;
|
|
13564
|
+
let finalDy = snapDy;
|
|
13565
|
+
let mergedGuides = newGuides;
|
|
13566
|
+
const psLive = projectSettingsRef.current;
|
|
13567
|
+
const gridX = psLive.gridSizeX ?? psLive.gridSize ?? 0;
|
|
13568
|
+
const gridY = psLive.gridSizeY ?? psLive.gridSize ?? 0;
|
|
13569
|
+
if (psLive.snapToGrid && gridX > 0 && gridY > 0) {
|
|
13570
|
+
try {
|
|
13571
|
+
snapTarget.setCoords();
|
|
13572
|
+
} catch {
|
|
13573
|
+
}
|
|
13574
|
+
const br = snapTarget.getBoundingRect();
|
|
13575
|
+
const gridGuides = [];
|
|
13576
|
+
if (finalDx === 0) {
|
|
13577
|
+
const newLeft = Math.round(br.left / gridX) * gridX;
|
|
13578
|
+
finalDx = newLeft - br.left;
|
|
13579
|
+
gridGuides.push({ type: "vertical", position: newLeft, kind: "grid" });
|
|
13580
|
+
}
|
|
13581
|
+
if (finalDy === 0) {
|
|
13582
|
+
const newTop = Math.round(br.top / gridY) * gridY;
|
|
13583
|
+
finalDy = newTop - br.top;
|
|
13584
|
+
gridGuides.push({ type: "horizontal", position: newTop, kind: "grid" });
|
|
13585
|
+
}
|
|
13586
|
+
if (gridGuides.length) mergedGuides = [...newGuides, ...gridGuides];
|
|
13587
|
+
}
|
|
13588
|
+
setGuides(mergedGuides);
|
|
11802
13589
|
setHoverBounds(null);
|
|
11803
|
-
if (
|
|
11804
|
-
snapTarget.set({ left: (snapTarget.left ?? 0) +
|
|
13590
|
+
if (finalDx !== 0 || finalDy !== 0) {
|
|
13591
|
+
snapTarget.set({ left: (snapTarget.left ?? 0) + finalDx, top: (snapTarget.top ?? 0) + finalDy });
|
|
11805
13592
|
}
|
|
11806
13593
|
});
|
|
11807
13594
|
let cropGroupSaveTimer = null;
|
|
11808
13595
|
fabricCanvas.on("object:modified", (e) => {
|
|
11809
|
-
var _a2,
|
|
13596
|
+
var _a2, _b2, _c, _d, _e, _f, _g;
|
|
11810
13597
|
try {
|
|
11811
13598
|
dragStarted = false;
|
|
11812
13599
|
setGuides([]);
|
|
11813
13600
|
setGroupOverlayLiveBoundsRef.current(null);
|
|
13601
|
+
objectResizeActiveSnapRef.current = null;
|
|
13602
|
+
groupResizeActiveSnapRef.current = null;
|
|
11814
13603
|
onDragEnd == null ? void 0 : onDragEnd();
|
|
13604
|
+
try {
|
|
13605
|
+
const t = e.target;
|
|
13606
|
+
if (t instanceof fabric__namespace.ActiveSelection) {
|
|
13607
|
+
for (const child of t.getObjects()) {
|
|
13608
|
+
delete child.__asLiveOrigW;
|
|
13609
|
+
delete child.__asLiveOrigH;
|
|
13610
|
+
}
|
|
13611
|
+
}
|
|
13612
|
+
} catch {
|
|
13613
|
+
}
|
|
11815
13614
|
lockEdits();
|
|
11816
13615
|
const modifiedTarget = e.target;
|
|
11817
13616
|
const modifiedTargetId = modifiedTarget ? getObjectId(modifiedTarget) : null;
|
|
@@ -11920,7 +13719,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11920
13719
|
useEditorStore.getState().reflowStackGroupInPage(pageId, groupId);
|
|
11921
13720
|
}
|
|
11922
13721
|
const stateAfter = useEditorStore.getState();
|
|
11923
|
-
const pageAfter = ((
|
|
13722
|
+
const pageAfter = ((_b2 = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
|
|
11924
13723
|
const groupNodeAfter = findNodeById(pageAfter, groupId);
|
|
11925
13724
|
if (groupNodeAfter) {
|
|
11926
13725
|
const abs = getAbsoluteBounds(groupNodeAfter, pageAfter);
|
|
@@ -11947,11 +13746,11 @@ const PageCanvas = react.forwardRef(
|
|
|
11947
13746
|
clearTimeout(cropGroupSaveTimer);
|
|
11948
13747
|
}
|
|
11949
13748
|
cropGroupSaveTimer = setTimeout(() => {
|
|
11950
|
-
var _a3,
|
|
13749
|
+
var _a3, _b3, _c2;
|
|
11951
13750
|
const { updateElement: updateElement2 } = useEditorStore.getState();
|
|
11952
13751
|
const img = ct._img;
|
|
11953
13752
|
const zoom3 = ((_a3 = img == null ? void 0 : img._ct) == null ? void 0 : _a3.zoom) ?? 1;
|
|
11954
|
-
const panX = ((
|
|
13753
|
+
const panX = ((_b3 = img == null ? void 0 : img._ct) == null ? void 0 : _b3.panX) ?? 0.5;
|
|
11955
13754
|
const panY = ((_c2 = img == null ? void 0 : img._ct) == null ? void 0 : _c2.panY) ?? 0.5;
|
|
11956
13755
|
const stateCrop = useEditorStore.getState();
|
|
11957
13756
|
const pageCrop = stateCrop.canvas.pages.find((p) => p.id === pageId);
|
|
@@ -11970,6 +13769,8 @@ const PageCanvas = react.forwardRef(
|
|
|
11970
13769
|
cropZoom: zoom3
|
|
11971
13770
|
}, { recordHistory: false });
|
|
11972
13771
|
active.__isInternalCropUpdate = false;
|
|
13772
|
+
installImageResizeControlsWithSnap(active);
|
|
13773
|
+
ensureCanvaControlRenders(active);
|
|
11973
13774
|
fabricCanvas.setActiveObject(active);
|
|
11974
13775
|
setTimeout(() => justModifiedIdsRef.current.delete(objId), 150);
|
|
11975
13776
|
}, 0);
|
|
@@ -12223,6 +14024,10 @@ const PageCanvas = react.forwardRef(
|
|
|
12223
14024
|
for (const obj of activeObjects) {
|
|
12224
14025
|
const objId = getObjectId(obj);
|
|
12225
14026
|
if (!objId || objId === "__background__") continue;
|
|
14027
|
+
const sourceElement = elementsRef.current.find((el) => el.id === objId);
|
|
14028
|
+
if (obj instanceof fabric__namespace.Textbox && !isActiveSelection) {
|
|
14029
|
+
bakeTextboxScaleIntoTypography(obj, sourceElement);
|
|
14030
|
+
}
|
|
12226
14031
|
let intrinsicWidth;
|
|
12227
14032
|
let intrinsicHeight;
|
|
12228
14033
|
if (obj instanceof fabric__namespace.Circle) {
|
|
@@ -12289,7 +14094,6 @@ const PageCanvas = react.forwardRef(
|
|
|
12289
14094
|
absoluteLeft = (absoluteLeft ?? 0) - w / 2;
|
|
12290
14095
|
absoluteTop = (absoluteTop ?? 0) - h / 2;
|
|
12291
14096
|
}
|
|
12292
|
-
const sourceElement = elementsRef.current.find((el) => el.id === objId);
|
|
12293
14097
|
const preserveCornerGeometry = (sourceElement == null ? void 0 : sourceElement.type) === "shape" && (sourceElement.shapeType === "circle" || sourceElement.shapeType === "rounded-rect" || sourceElement.shapeType === "triangle");
|
|
12294
14098
|
let finalWidth = intrinsicWidth;
|
|
12295
14099
|
let finalHeight = intrinsicHeight;
|
|
@@ -12375,17 +14179,35 @@ const PageCanvas = react.forwardRef(
|
|
|
12375
14179
|
finalHeight = 0;
|
|
12376
14180
|
finalScaleX = 1;
|
|
12377
14181
|
finalScaleY = 1;
|
|
14182
|
+
} else if (obj instanceof fabric__namespace.Textbox && isActiveSelection && (Math.abs((decomposed.scaleX ?? 1) - 1) > 1e-3 || Math.abs((decomposed.scaleY ?? 1) - 1) > 1e-3)) {
|
|
14183
|
+
const sx = Math.abs(decomposed.scaleX || 1);
|
|
14184
|
+
const sy = Math.abs(decomposed.scaleY || 1);
|
|
14185
|
+
const bakedWidth = Math.max(20, intrinsicWidth * sx);
|
|
14186
|
+
const bakedHeight = Math.max(1, intrinsicHeight * sy);
|
|
14187
|
+
finalWidth = bakedWidth;
|
|
14188
|
+
finalHeight = bakedHeight;
|
|
14189
|
+
finalScaleX = 1;
|
|
14190
|
+
finalScaleY = 1;
|
|
14191
|
+
try {
|
|
14192
|
+
obj.set({ width: bakedWidth, scaleX: 1, scaleY: 1 });
|
|
14193
|
+
obj.initDimensions();
|
|
14194
|
+
obj.setCoords();
|
|
14195
|
+
} catch {
|
|
14196
|
+
}
|
|
14197
|
+
finalAbsoluteMatrix = fabric__namespace.util.composeMatrix({
|
|
14198
|
+
translateX: decomposed.translateX,
|
|
14199
|
+
translateY: decomposed.translateY,
|
|
14200
|
+
angle: decomposed.angle ?? 0,
|
|
14201
|
+
scaleX: 1,
|
|
14202
|
+
scaleY: 1,
|
|
14203
|
+
skewX: 0,
|
|
14204
|
+
skewY: 0
|
|
14205
|
+
});
|
|
12378
14206
|
} else if (preserveCornerGeometry) {
|
|
12379
14207
|
const scaledW = Math.max(1, intrinsicWidth * Math.abs(decomposed.scaleX || 1));
|
|
12380
14208
|
const scaledH = Math.max(1, intrinsicHeight * Math.abs(decomposed.scaleY || 1));
|
|
12381
|
-
|
|
12382
|
-
|
|
12383
|
-
finalWidth = diameter;
|
|
12384
|
-
finalHeight = diameter;
|
|
12385
|
-
} else {
|
|
12386
|
-
finalWidth = scaledW;
|
|
12387
|
-
finalHeight = scaledH;
|
|
12388
|
-
}
|
|
14209
|
+
finalWidth = scaledW;
|
|
14210
|
+
finalHeight = scaledH;
|
|
12389
14211
|
finalScaleX = 1;
|
|
12390
14212
|
finalScaleY = 1;
|
|
12391
14213
|
obj.set({ scaleX: 1, scaleY: 1 });
|
|
@@ -12424,6 +14246,11 @@ const PageCanvas = react.forwardRef(
|
|
|
12424
14246
|
transformMatrix: finalAbsoluteMatrix
|
|
12425
14247
|
};
|
|
12426
14248
|
if (obj instanceof fabric__namespace.Textbox) {
|
|
14249
|
+
const bakedTextScaleUpdates = obj.__pixldocsBakedTextScaleUpdates;
|
|
14250
|
+
if (bakedTextScaleUpdates && typeof bakedTextScaleUpdates === "object") {
|
|
14251
|
+
Object.assign(elementUpdate, bakedTextScaleUpdates);
|
|
14252
|
+
delete obj.__pixldocsBakedTextScaleUpdates;
|
|
14253
|
+
}
|
|
12427
14254
|
const baked = obj.minBoxHeight;
|
|
12428
14255
|
if (typeof baked === "number" && baked > 0) {
|
|
12429
14256
|
elementUpdate.minBoxHeight = baked;
|
|
@@ -12532,7 +14359,7 @@ const PageCanvas = react.forwardRef(
|
|
|
12532
14359
|
}
|
|
12533
14360
|
});
|
|
12534
14361
|
fabricCanvas.on("mouse:dblclick", (e) => {
|
|
12535
|
-
var _a2,
|
|
14362
|
+
var _a2, _b2;
|
|
12536
14363
|
if (!isActiveRef.current || !allowEditing) return;
|
|
12537
14364
|
let target = e.target;
|
|
12538
14365
|
if (!target) {
|
|
@@ -12542,7 +14369,7 @@ const PageCanvas = react.forwardRef(
|
|
|
12542
14369
|
if (target && target instanceof fabric__namespace.Group && target.__cropGroup) {
|
|
12543
14370
|
const ct = target.__cropData;
|
|
12544
14371
|
const innerImg = ct == null ? void 0 : ct._img;
|
|
12545
|
-
const innerSrc = ((_a2 = innerImg == null ? void 0 : innerImg.getSrc) == null ? void 0 : _a2.call(innerImg)) || ((
|
|
14372
|
+
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) || "";
|
|
12546
14373
|
const isPlaceholder = !innerSrc || innerSrc === EMPTY_IMAGE_PLACEHOLDER_DATA_URL;
|
|
12547
14374
|
if (innerImg && !isPlaceholder && !isCropGroupInCropMode(target)) {
|
|
12548
14375
|
enterCropMode(target);
|
|
@@ -12721,13 +14548,13 @@ const PageCanvas = react.forwardRef(
|
|
|
12721
14548
|
visibilityUpdateInProgressRef.current = false;
|
|
12722
14549
|
}
|
|
12723
14550
|
doSyncRef.current = () => {
|
|
12724
|
-
var _a2,
|
|
14551
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
12725
14552
|
const shouldSkipUpdates2 = syncLockedRef.current || editLockRef.current;
|
|
12726
14553
|
const state = useEditorStore.getState();
|
|
12727
14554
|
const elementsToSync = elements;
|
|
12728
14555
|
elementsRef.current = elementsToSync;
|
|
12729
14556
|
const pageTree = isPreviewMode && (pageChildren == null ? void 0 : pageChildren.length) ? pageChildren ?? [] : ((_a2 = state.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
|
|
12730
|
-
const selectedIdsFromStore = new Set(((
|
|
14557
|
+
const selectedIdsFromStore = new Set(((_b2 = state.canvas) == null ? void 0 : _b2.selectedIds) ?? []);
|
|
12731
14558
|
isRebuildingRef.current = true;
|
|
12732
14559
|
const allElementIds = new Set(elementsToSync.map((el) => el.id));
|
|
12733
14560
|
const sectionGroups = pageTree.filter(
|
|
@@ -12754,7 +14581,8 @@ const PageCanvas = react.forwardRef(
|
|
|
12754
14581
|
const activeObj = fc.getActiveObject();
|
|
12755
14582
|
const activeObjId = activeObj ? getObjectId(activeObj) : null;
|
|
12756
14583
|
const isTextBeingEdited = activeObjId && editingTextIdRef.current === activeObjId;
|
|
12757
|
-
|
|
14584
|
+
const isMultiSelect = activeObj instanceof fabric__namespace.ActiveSelection;
|
|
14585
|
+
if (activeObj && isMultiSelect && !(((_c = activeObj._ct) == null ? void 0 : _c.isCropGroup) || activeObj.__cropGroup) && !isTextBeingEdited) {
|
|
12758
14586
|
fc.discardActiveObject();
|
|
12759
14587
|
}
|
|
12760
14588
|
}
|
|
@@ -13074,7 +14902,7 @@ const PageCanvas = react.forwardRef(
|
|
|
13074
14902
|
updateCoverLayout(existingObj);
|
|
13075
14903
|
applyEdgeFadeFrameClipPath(existingObj, element, ct.frameW, ct.frameH, ct.shape || "rect", ct.rx || 0);
|
|
13076
14904
|
if (allowEditing) {
|
|
13077
|
-
|
|
14905
|
+
installImageResizeControlsWithSnap(existingObj);
|
|
13078
14906
|
} else {
|
|
13079
14907
|
existingObj.set({
|
|
13080
14908
|
hasControls: false,
|
|
@@ -13156,7 +14984,7 @@ const PageCanvas = react.forwardRef(
|
|
|
13156
14984
|
hoverCursor: isDynamicField && isPreviewMode ? "pointer" : void 0
|
|
13157
14985
|
});
|
|
13158
14986
|
if (allowEditing) {
|
|
13159
|
-
|
|
14987
|
+
installImageResizeControlsWithSnap(existingObj);
|
|
13160
14988
|
}
|
|
13161
14989
|
existingObj.setCoords();
|
|
13162
14990
|
fc.requestRenderAll();
|
|
@@ -13882,7 +15710,7 @@ const PageCanvas = react.forwardRef(
|
|
|
13882
15710
|
return unsub;
|
|
13883
15711
|
}, []);
|
|
13884
15712
|
const updateFabricObject = (obj, element, skipPositionUpdate = false) => {
|
|
13885
|
-
var _a2,
|
|
15713
|
+
var _a2, _b2, _c;
|
|
13886
15714
|
const fc = fabricRef.current;
|
|
13887
15715
|
if (fc && isTransforming(fc)) {
|
|
13888
15716
|
return;
|
|
@@ -13950,11 +15778,12 @@ const PageCanvas = react.forwardRef(
|
|
|
13950
15778
|
// Disable rotation for crop groups (simplifies resize math)
|
|
13951
15779
|
hasRotatingPoint: false,
|
|
13952
15780
|
// Hide rotation handle
|
|
13953
|
-
//
|
|
13954
|
-
|
|
13955
|
-
|
|
15781
|
+
// Handles are drawn in screen-space — keep them constant on-screen.
|
|
15782
|
+
// Match the global Canva-style defaults (circular dots, pill sides).
|
|
15783
|
+
cornerSize: 10,
|
|
15784
|
+
borderScaleFactor: SELECTION_BORDER_SCALE,
|
|
13956
15785
|
transparentCorners: false,
|
|
13957
|
-
cornerStyle: "
|
|
15786
|
+
cornerStyle: "circle",
|
|
13958
15787
|
cornerColor: SELECTION_PRIMARY,
|
|
13959
15788
|
cornerStrokeColor: "#ffffff",
|
|
13960
15789
|
borderColor: SELECTION_PRIMARY,
|
|
@@ -14064,7 +15893,8 @@ const PageCanvas = react.forwardRef(
|
|
|
14064
15893
|
obj.clipPath.dirty = true;
|
|
14065
15894
|
obj.clipPath.setCoords();
|
|
14066
15895
|
}
|
|
14067
|
-
|
|
15896
|
+
installImageResizeControlsWithSnap(obj);
|
|
15897
|
+
ensureCanvaControlRenders(obj);
|
|
14068
15898
|
obj.set({
|
|
14069
15899
|
selectable: true,
|
|
14070
15900
|
evented: true,
|
|
@@ -14159,7 +15989,7 @@ const PageCanvas = react.forwardRef(
|
|
|
14159
15989
|
obj.setCoords();
|
|
14160
15990
|
}
|
|
14161
15991
|
if (!isLine) {
|
|
14162
|
-
const angleTextPathActive = isTextbox && ((
|
|
15992
|
+
const angleTextPathActive = isTextbox && ((_b2 = element.textPath) == null ? void 0 : _b2.preset) === "rise";
|
|
14163
15993
|
const appliedSkewY = angleTextPathActive ? 0 : element.skewY ?? 0;
|
|
14164
15994
|
let posIfNotSkipped = skipPositionUpdate ? {} : { left: fabricPos.left, top: fabricPos.top };
|
|
14165
15995
|
if (!skipPositionUpdate && (obj instanceof fabric__namespace.FabricImage && obj.originX === "center" || obj instanceof fabric__namespace.Group && obj.__cropGroup)) {
|
|
@@ -14236,7 +16066,17 @@ const PageCanvas = react.forwardRef(
|
|
|
14236
16066
|
objectCaching: true
|
|
14237
16067
|
});
|
|
14238
16068
|
} else if (obj instanceof fabric__namespace.Ellipse) {
|
|
14239
|
-
obj.set({
|
|
16069
|
+
obj.set({
|
|
16070
|
+
rx: cornerSafeW / 2,
|
|
16071
|
+
ry: cornerSafeH / 2,
|
|
16072
|
+
fill: element.fill || "transparent",
|
|
16073
|
+
stroke: element.stroke || "transparent",
|
|
16074
|
+
strokeWidth: element.strokeWidth || 0,
|
|
16075
|
+
strokeUniform: true,
|
|
16076
|
+
strokeLineJoin: "round",
|
|
16077
|
+
strokeLineCap: "round",
|
|
16078
|
+
objectCaching: true
|
|
16079
|
+
});
|
|
14240
16080
|
} else if (obj instanceof fabric__namespace.Textbox) {
|
|
14241
16081
|
const overflowPolicy = element.overflowPolicy || "grow-and-push";
|
|
14242
16082
|
let text = element.text || "Text";
|
|
@@ -14430,6 +16270,16 @@ const PageCanvas = react.forwardRef(
|
|
|
14430
16270
|
strokeUniform: true,
|
|
14431
16271
|
objectCaching: true
|
|
14432
16272
|
});
|
|
16273
|
+
} else if (obj instanceof fabric__namespace.Ellipse) {
|
|
16274
|
+
obj.set({
|
|
16275
|
+
rx: cornerSafeW / 2,
|
|
16276
|
+
ry: cornerSafeH / 2,
|
|
16277
|
+
fill: element.fill || "transparent",
|
|
16278
|
+
stroke: element.stroke || "transparent",
|
|
16279
|
+
strokeWidth: element.strokeWidth || 0,
|
|
16280
|
+
strokeUniform: true,
|
|
16281
|
+
objectCaching: true
|
|
16282
|
+
});
|
|
14433
16283
|
} else if (obj instanceof fabric__namespace.Rect && element.shapeType === "rounded-rect") {
|
|
14434
16284
|
const toRadius = (value, fallback) => Number.isFinite(value) ? Math.max(0, Number(value)) : fallback;
|
|
14435
16285
|
const baseRx = Math.max(0, Number(element.rx ?? 0));
|
|
@@ -14689,7 +16539,7 @@ const PageCanvas = react.forwardRef(
|
|
|
14689
16539
|
return Math.max(min, Math.min(max, v));
|
|
14690
16540
|
};
|
|
14691
16541
|
const applyEdgeFadeFrameClipPath = (group, element, frameW, frameH, shape, rxRatio) => {
|
|
14692
|
-
var _a2,
|
|
16542
|
+
var _a2, _b2, _c;
|
|
14693
16543
|
const fadeElement = element;
|
|
14694
16544
|
const fadeGroup = group;
|
|
14695
16545
|
const inputKey = edgeFadeKey(fadeElement);
|
|
@@ -14810,7 +16660,7 @@ const PageCanvas = react.forwardRef(
|
|
|
14810
16660
|
delete fadeGroup.__edgeFadeRenderConfig;
|
|
14811
16661
|
delete fadeGroup.__edgeFadeKey;
|
|
14812
16662
|
delete fadeGroup.__edgeFadeInputKey;
|
|
14813
|
-
if ((
|
|
16663
|
+
if ((_b2 = group.clipPath) == null ? void 0 : _b2.__edgeFadeMask) {
|
|
14814
16664
|
group.clipPath = void 0;
|
|
14815
16665
|
updateCoverLayout(group);
|
|
14816
16666
|
}
|
|
@@ -14827,7 +16677,7 @@ const PageCanvas = react.forwardRef(
|
|
|
14827
16677
|
(_c = group.canvas) == null ? void 0 : _c.requestRenderAll();
|
|
14828
16678
|
};
|
|
14829
16679
|
const loadImageAsync2 = async (element, placeholder, fc) => {
|
|
14830
|
-
var _a2,
|
|
16680
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
14831
16681
|
const imageUrl = element.src || element.imageUrl;
|
|
14832
16682
|
if (!imageUrl) return;
|
|
14833
16683
|
const elementId = element.id;
|
|
@@ -14858,7 +16708,7 @@ const PageCanvas = react.forwardRef(
|
|
|
14858
16708
|
await normalizeSvgImageDimensions(img, imageUrl, element.sourceFormat);
|
|
14859
16709
|
if (!isLatestRequest()) return;
|
|
14860
16710
|
const imageFitForFade = element.imageFit || ((_a2 = element.style) == null ? void 0 : _a2.imageFit) || "cover";
|
|
14861
|
-
const clipShapeForFade = element.clipShape ?? ((
|
|
16711
|
+
const clipShapeForFade = element.clipShape ?? ((_b2 = element.style) == null ? void 0 : _b2.imageFrameShape) ?? (isPreviewMode ? "rectangle" : "none");
|
|
14862
16712
|
const willUseCropGroupForFade = imageFitForFade !== "fill" || clipShapeForFade && clipShapeForFade !== "none";
|
|
14863
16713
|
try {
|
|
14864
16714
|
if (hasEdgeFade(element) && !willUseCropGroupForFade) {
|
|
@@ -15076,7 +16926,7 @@ const PageCanvas = react.forwardRef(
|
|
|
15076
16926
|
evented: canBeEvented && !isHidden
|
|
15077
16927
|
});
|
|
15078
16928
|
} else {
|
|
15079
|
-
|
|
16929
|
+
installImageResizeControlsWithSnap(cropGroup);
|
|
15080
16930
|
}
|
|
15081
16931
|
const cropImg = (_o = cropGroup.__cropData) == null ? void 0 : _o._img;
|
|
15082
16932
|
if (cropImg) {
|
|
@@ -15287,38 +17137,7 @@ const PageCanvas = react.forwardRef(
|
|
|
15287
17137
|
),
|
|
15288
17138
|
sectionsOverlay,
|
|
15289
17139
|
groupBoundsOverlay,
|
|
15290
|
-
|
|
15291
|
-
"svg",
|
|
15292
|
-
{
|
|
15293
|
-
className: "absolute inset-0 pointer-events-none",
|
|
15294
|
-
style: { width: scaledWidth, height: scaledHeight },
|
|
15295
|
-
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
15296
|
-
children: [
|
|
15297
|
-
/* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15298
|
-
"pattern",
|
|
15299
|
-
{
|
|
15300
|
-
id: `pixldocs-grid-${pageId}`,
|
|
15301
|
-
width: canvas.projectSettings.gridSize,
|
|
15302
|
-
height: canvas.projectSettings.gridSize,
|
|
15303
|
-
patternUnits: "userSpaceOnUse",
|
|
15304
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15305
|
-
"path",
|
|
15306
|
-
{
|
|
15307
|
-
d: `M ${canvas.projectSettings.gridSize} 0 L 0 0 0 ${canvas.projectSettings.gridSize}`,
|
|
15308
|
-
fill: "none",
|
|
15309
|
-
stroke: "currentColor",
|
|
15310
|
-
strokeWidth: 0.5,
|
|
15311
|
-
opacity: 0.18,
|
|
15312
|
-
className: "text-foreground"
|
|
15313
|
-
}
|
|
15314
|
-
)
|
|
15315
|
-
}
|
|
15316
|
-
) }),
|
|
15317
|
-
/* @__PURE__ */ jsxRuntime.jsx("rect", { width: canvasWidth, height: canvasHeight, fill: `url(#pixldocs-grid-${pageId})` })
|
|
15318
|
-
]
|
|
15319
|
-
}
|
|
15320
|
-
),
|
|
15321
|
-
hoverBounds && !guides.length && /* @__PURE__ */ jsxRuntime.jsx(
|
|
17140
|
+
hoverBounds && !guides.length && !(selectedIdsRef.current && selectedIdsRef.current.length) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
15322
17141
|
"svg",
|
|
15323
17142
|
{
|
|
15324
17143
|
className: "absolute inset-0 pointer-events-none",
|
|
@@ -15332,108 +17151,177 @@ const PageCanvas = react.forwardRef(
|
|
|
15332
17151
|
width: hoverBounds.width,
|
|
15333
17152
|
height: hoverBounds.height,
|
|
15334
17153
|
fill: "none",
|
|
15335
|
-
stroke:
|
|
15336
|
-
strokeWidth:
|
|
17154
|
+
stroke: SELECTION_PRIMARY,
|
|
17155
|
+
strokeWidth: 2,
|
|
17156
|
+
vectorEffect: "non-scaling-stroke",
|
|
15337
17157
|
strokeDasharray: "0",
|
|
15338
|
-
opacity:
|
|
17158
|
+
opacity: 1
|
|
15339
17159
|
}
|
|
15340
17160
|
)
|
|
15341
17161
|
}
|
|
15342
17162
|
),
|
|
15343
|
-
|
|
17163
|
+
canvas.projectSettings.showGrid && (() => {
|
|
17164
|
+
const ps = canvas.projectSettings;
|
|
17165
|
+
const gx = Math.max(1, ps.gridSizeX ?? ps.gridSize ?? 0);
|
|
17166
|
+
const gy = Math.max(1, ps.gridSizeY ?? ps.gridSize ?? 0);
|
|
17167
|
+
if (gx <= 0 || gy <= 0) return null;
|
|
17168
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17169
|
+
"svg",
|
|
17170
|
+
{
|
|
17171
|
+
className: "absolute inset-0 pointer-events-none",
|
|
17172
|
+
style: { width: scaledWidth, height: scaledHeight },
|
|
17173
|
+
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
17174
|
+
children: [
|
|
17175
|
+
/* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17176
|
+
"pattern",
|
|
17177
|
+
{
|
|
17178
|
+
id: `pixldocs-grid-${pageId}`,
|
|
17179
|
+
width: gx,
|
|
17180
|
+
height: gy,
|
|
17181
|
+
patternUnits: "userSpaceOnUse",
|
|
17182
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17183
|
+
"path",
|
|
17184
|
+
{
|
|
17185
|
+
d: `M ${gx} 0 L 0 0 0 ${gy}`,
|
|
17186
|
+
fill: "none",
|
|
17187
|
+
stroke: ps.gridColor || "#0f172a",
|
|
17188
|
+
strokeWidth: 0.5,
|
|
17189
|
+
opacity: 0.22
|
|
17190
|
+
}
|
|
17191
|
+
)
|
|
17192
|
+
}
|
|
17193
|
+
) }),
|
|
17194
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { width: canvasWidth, height: canvasHeight, fill: `url(#pixldocs-grid-${pageId})` })
|
|
17195
|
+
]
|
|
17196
|
+
}
|
|
17197
|
+
);
|
|
17198
|
+
})(),
|
|
17199
|
+
guides.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15344
17200
|
"svg",
|
|
15345
17201
|
{
|
|
15346
17202
|
className: "absolute inset-0 pointer-events-none",
|
|
15347
17203
|
style: { width: scaledWidth, height: scaledHeight },
|
|
15348
17204
|
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
15349
|
-
children:
|
|
15350
|
-
|
|
15351
|
-
|
|
15352
|
-
|
|
15353
|
-
const
|
|
15354
|
-
|
|
15355
|
-
|
|
15356
|
-
|
|
15357
|
-
|
|
15358
|
-
|
|
15359
|
-
|
|
15360
|
-
|
|
15361
|
-
|
|
15362
|
-
|
|
15363
|
-
|
|
15364
|
-
|
|
15365
|
-
|
|
15366
|
-
|
|
17205
|
+
children: [
|
|
17206
|
+
(() => {
|
|
17207
|
+
const seenBoxes = /* @__PURE__ */ new Set();
|
|
17208
|
+
const boxes = [];
|
|
17209
|
+
for (const g of guides) {
|
|
17210
|
+
const list = g.targetBoundsList ?? (g.targetBounds ? [g.targetBounds] : []);
|
|
17211
|
+
for (const b of list) {
|
|
17212
|
+
const key = `${b.left.toFixed(1)}-${b.top.toFixed(1)}-${b.width.toFixed(1)}-${b.height.toFixed(1)}`;
|
|
17213
|
+
if (seenBoxes.has(key)) continue;
|
|
17214
|
+
seenBoxes.add(key);
|
|
17215
|
+
boxes.push(b);
|
|
17216
|
+
}
|
|
17217
|
+
}
|
|
17218
|
+
return boxes.map((b, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
17219
|
+
"rect",
|
|
17220
|
+
{
|
|
17221
|
+
x: b.left,
|
|
17222
|
+
y: b.top,
|
|
17223
|
+
width: b.width,
|
|
17224
|
+
height: b.height,
|
|
17225
|
+
fill: "none",
|
|
17226
|
+
stroke: "#f43f5e",
|
|
17227
|
+
strokeWidth: 1.5,
|
|
17228
|
+
strokeDasharray: "4,3",
|
|
17229
|
+
opacity: 0.9,
|
|
17230
|
+
vectorEffect: "non-scaling-stroke"
|
|
17231
|
+
},
|
|
17232
|
+
`tb-${i}`
|
|
17233
|
+
));
|
|
17234
|
+
})(),
|
|
17235
|
+
(() => {
|
|
17236
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17237
|
+
return guides.filter((guide) => {
|
|
17238
|
+
if (guide.kind === "gap") return true;
|
|
17239
|
+
const key = `${guide.type}-${guide.position.toFixed(1)}`;
|
|
17240
|
+
if (seen.has(key)) return false;
|
|
17241
|
+
seen.add(key);
|
|
17242
|
+
return true;
|
|
17243
|
+
}).map((guide, i) => {
|
|
17244
|
+
if (guide.kind === "gap" && guide.gap != null && guide.start != null && guide.end != null) {
|
|
17245
|
+
const gapColor = "#ec4899";
|
|
17246
|
+
const label = `${guide.gap}`;
|
|
17247
|
+
const labelW2 = Math.max(22, label.length * 7 + 8);
|
|
17248
|
+
if (guide.type === "horizontal") {
|
|
17249
|
+
const y = guide.bracketAt ?? guide.position;
|
|
17250
|
+
const x1 = guide.start;
|
|
17251
|
+
const x2 = guide.end;
|
|
17252
|
+
const mid = (x1 + x2) / 2;
|
|
17253
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
17254
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1, y1: y, x2, y2: y, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17255
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1, y1: y - 4, x2: x1, y2: y + 4, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17256
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: x2, y1: y - 4, x2, y2: y + 4, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17257
|
+
/* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${mid}, ${y - 12})`, children: [
|
|
17258
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: -labelW2 / 2, y: -9, width: labelW2, height: 16, rx: 4, fill: gapColor }),
|
|
17259
|
+
/* @__PURE__ */ jsxRuntime.jsx("text", { x: 0, y: 3, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 600, children: label })
|
|
17260
|
+
] })
|
|
17261
|
+
] }, i);
|
|
17262
|
+
} else {
|
|
17263
|
+
const x = guide.bracketAt ?? guide.position;
|
|
17264
|
+
const y1 = guide.start;
|
|
17265
|
+
const y2 = guide.end;
|
|
17266
|
+
const mid = (y1 + y2) / 2;
|
|
17267
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
17268
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: x, y1, x2: x, y2, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17269
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: x - 4, y1, x2: x + 4, y2: y1, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17270
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: x - 4, y1: y2, x2: x + 4, y2, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17271
|
+
/* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x + 12}, ${mid})`, children: [
|
|
17272
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: -labelW2 / 2, y: -9, width: labelW2, height: 16, rx: 4, fill: gapColor }),
|
|
17273
|
+
/* @__PURE__ */ jsxRuntime.jsx("text", { x: 0, y: 3, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 600, children: label })
|
|
17274
|
+
] })
|
|
17275
|
+
] }, i);
|
|
17276
|
+
}
|
|
17277
|
+
}
|
|
17278
|
+
const isElementRelative = guide.start !== void 0 && guide.end !== void 0;
|
|
17279
|
+
const isActive2 = guide.active === true;
|
|
17280
|
+
const isGrid = guide.kind === "grid";
|
|
17281
|
+
const strokeColor = isGrid ? "#f59e0b" : isActive2 ? "#22c55e" : isElementRelative ? "#f43f5e" : "#ec4899";
|
|
17282
|
+
const strokeWidth = isGrid ? 1.75 : 1.75;
|
|
17283
|
+
const strokeDasharray = isGrid ? "2,3" : isActive2 ? "none" : isElementRelative ? "3,3" : "4,4";
|
|
17284
|
+
const showDistance = typeof guide.distance === "number";
|
|
17285
|
+
const labelText = showDistance ? String(Math.round(guide.distance)) : "";
|
|
17286
|
+
const labelW = Math.max(24, labelText.length * 7);
|
|
17287
|
+
if (guide.type === "vertical") {
|
|
17288
|
+
const padding = isElementRelative || isActive2 ? 20 : 0;
|
|
17289
|
+
const y1 = guide.start != null && guide.end != null ? Math.max(0, guide.start - padding) : 0;
|
|
17290
|
+
const y2 = guide.start != null && guide.end != null ? Math.min(canvasHeight, guide.end + padding) : canvasHeight;
|
|
17291
|
+
const labelY = guide.start != null && guide.end != null ? (guide.start + guide.end) / 2 : canvasHeight / 2;
|
|
15367
17292
|
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
15368
|
-
/* @__PURE__ */ jsxRuntime.jsx("line", { x1, y1
|
|
15369
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
15370
|
-
/* @__PURE__ */ jsxRuntime.
|
|
15371
|
-
|
|
15372
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
15373
|
-
|
|
17293
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: guide.position, y1, x2: guide.position, y2, stroke: strokeColor, strokeWidth, strokeDasharray, vectorEffect: "non-scaling-stroke" }),
|
|
17294
|
+
isActive2 && /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: guide.position, cy: y2, r: 4, fill: "#22c55e", opacity: 0.9 }),
|
|
17295
|
+
isElementRelative && !isActive2 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
17296
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: guide.position, cy: y1, r: 2, fill: "#f43f5e" }),
|
|
17297
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: guide.position, cy: y2, r: 2, fill: "#f43f5e" })
|
|
17298
|
+
] }),
|
|
17299
|
+
showDistance && /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${guide.position + 6}, ${labelY})`, children: [
|
|
17300
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: -2, y: -9, width: labelW, height: 16, rx: 4, fill: "rgba(0,0,0,0.75)" }),
|
|
17301
|
+
/* @__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 })
|
|
15374
17302
|
] })
|
|
15375
17303
|
] }, i);
|
|
15376
17304
|
} else {
|
|
15377
|
-
const
|
|
15378
|
-
const
|
|
15379
|
-
const
|
|
15380
|
-
const
|
|
17305
|
+
const padding = isElementRelative || isActive2 ? 20 : 0;
|
|
17306
|
+
const x1 = guide.start != null && guide.end != null ? Math.max(0, guide.start - padding) : 0;
|
|
17307
|
+
const x2 = guide.start != null && guide.end != null ? Math.min(canvasWidth, guide.end + padding) : canvasWidth;
|
|
17308
|
+
const labelX = guide.start != null && guide.end != null ? (guide.start + guide.end) / 2 : canvasWidth / 2;
|
|
15381
17309
|
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
15382
|
-
/* @__PURE__ */ jsxRuntime.jsx("line", { x1
|
|
15383
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
15384
|
-
/* @__PURE__ */ jsxRuntime.
|
|
15385
|
-
|
|
15386
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
15387
|
-
|
|
17310
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1, y1: guide.position, x2, y2: guide.position, stroke: strokeColor, strokeWidth, strokeDasharray, vectorEffect: "non-scaling-stroke" }),
|
|
17311
|
+
isActive2 && /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x2, cy: guide.position, r: 4, fill: "#22c55e", opacity: 0.9 }),
|
|
17312
|
+
isElementRelative && !isActive2 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
17313
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x1, cy: guide.position, r: 2, fill: "#f43f5e" }),
|
|
17314
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x2, cy: guide.position, r: 2, fill: "#f43f5e" })
|
|
17315
|
+
] }),
|
|
17316
|
+
showDistance && /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${labelX}, ${guide.position - 10})`, children: [
|
|
17317
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: -2, y: -9, width: labelW, height: 16, rx: 4, fill: "rgba(0,0,0,0.75)" }),
|
|
17318
|
+
/* @__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 })
|
|
15388
17319
|
] })
|
|
15389
17320
|
] }, i);
|
|
15390
17321
|
}
|
|
15391
|
-
}
|
|
15392
|
-
|
|
15393
|
-
|
|
15394
|
-
const strokeColor = isActive2 ? "#22c55e" : isElementRelative ? "#f43f5e" : "#3b82f6";
|
|
15395
|
-
const strokeWidth = isActive2 ? 2.5 : 1;
|
|
15396
|
-
const strokeDasharray = isActive2 ? "none" : isElementRelative ? "3,3" : "4,4";
|
|
15397
|
-
const showDistance = typeof guide.distance === "number";
|
|
15398
|
-
const labelText = showDistance ? String(Math.round(guide.distance)) : "";
|
|
15399
|
-
const labelW = Math.max(24, labelText.length * 7);
|
|
15400
|
-
if (guide.type === "vertical") {
|
|
15401
|
-
const padding = isElementRelative || isActive2 ? 20 : 0;
|
|
15402
|
-
const y1 = guide.start != null && guide.end != null ? Math.max(0, guide.start - padding) : 0;
|
|
15403
|
-
const y2 = guide.start != null && guide.end != null ? Math.min(canvasHeight, guide.end + padding) : canvasHeight;
|
|
15404
|
-
const labelY = guide.start != null && guide.end != null ? (guide.start + guide.end) / 2 : canvasHeight / 2;
|
|
15405
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
15406
|
-
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: guide.position, y1, x2: guide.position, y2, stroke: strokeColor, strokeWidth, strokeDasharray }),
|
|
15407
|
-
isActive2 && /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: guide.position, cy: y2, r: 4, fill: "#22c55e", opacity: 0.9 }),
|
|
15408
|
-
isElementRelative && !isActive2 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
15409
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: guide.position, cy: y1, r: 2, fill: "#f43f5e" }),
|
|
15410
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: guide.position, cy: y2, r: 2, fill: "#f43f5e" })
|
|
15411
|
-
] }),
|
|
15412
|
-
showDistance && /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${guide.position + 6}, ${labelY})`, children: [
|
|
15413
|
-
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: -2, y: -9, width: labelW, height: 16, rx: 4, fill: "rgba(0,0,0,0.75)" }),
|
|
15414
|
-
/* @__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 })
|
|
15415
|
-
] })
|
|
15416
|
-
] }, i);
|
|
15417
|
-
} else {
|
|
15418
|
-
const padding = isElementRelative || isActive2 ? 20 : 0;
|
|
15419
|
-
const x1 = guide.start != null && guide.end != null ? Math.max(0, guide.start - padding) : 0;
|
|
15420
|
-
const x2 = guide.start != null && guide.end != null ? Math.min(canvasWidth, guide.end + padding) : canvasWidth;
|
|
15421
|
-
const labelX = guide.start != null && guide.end != null ? (guide.start + guide.end) / 2 : canvasWidth / 2;
|
|
15422
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
15423
|
-
/* @__PURE__ */ jsxRuntime.jsx("line", { x1, y1: guide.position, x2, y2: guide.position, stroke: strokeColor, strokeWidth, strokeDasharray }),
|
|
15424
|
-
isActive2 && /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x2, cy: guide.position, r: 4, fill: "#22c55e", opacity: 0.9 }),
|
|
15425
|
-
isElementRelative && !isActive2 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
15426
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x1, cy: guide.position, r: 2, fill: "#f43f5e" }),
|
|
15427
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x2, cy: guide.position, r: 2, fill: "#f43f5e" })
|
|
15428
|
-
] }),
|
|
15429
|
-
showDistance && /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${labelX}, ${guide.position - 10})`, children: [
|
|
15430
|
-
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: -2, y: -9, width: labelW, height: 16, rx: 4, fill: "rgba(0,0,0,0.75)" }),
|
|
15431
|
-
/* @__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 })
|
|
15432
|
-
] })
|
|
15433
|
-
] }, i);
|
|
15434
|
-
}
|
|
15435
|
-
});
|
|
15436
|
-
})()
|
|
17322
|
+
});
|
|
17323
|
+
})()
|
|
17324
|
+
]
|
|
15437
17325
|
}
|
|
15438
17326
|
),
|
|
15439
17327
|
gridResizeLabel && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -15569,13 +17457,13 @@ function PreviewCanvas({
|
|
|
15569
17457
|
onDynamicFieldClick,
|
|
15570
17458
|
onReady
|
|
15571
17459
|
}) {
|
|
15572
|
-
var _a2,
|
|
17460
|
+
var _a2, _b2, _c, _d, _e;
|
|
15573
17461
|
const canvasRef = react.useRef(null);
|
|
15574
17462
|
const containerRef = react.useRef(null);
|
|
15575
17463
|
const [containerWidth, setContainerWidth] = react.useState(0);
|
|
15576
17464
|
const [hoveredFieldId, setHoveredFieldId] = react.useState(null);
|
|
15577
17465
|
const page = (_a2 = config == null ? void 0 : config.pages) == null ? void 0 : _a2[pageIndex];
|
|
15578
|
-
const canvasWidth = ((
|
|
17466
|
+
const canvasWidth = ((_b2 = config == null ? void 0 : config.canvas) == null ? void 0 : _b2.width) || 612;
|
|
15579
17467
|
const canvasHeight = ((_c = config == null ? void 0 : config.canvas) == null ? void 0 : _c.height) || 792;
|
|
15580
17468
|
const elementToFieldMap = react.useMemo(
|
|
15581
17469
|
() => buildElementToFieldMap(config == null ? void 0 : config.dynamicFields),
|
|
@@ -15625,14 +17513,14 @@ function PreviewCanvas({
|
|
|
15625
17513
|
}
|
|
15626
17514
|
}, [elements]);
|
|
15627
17515
|
const pageSettings = react.useMemo(() => {
|
|
15628
|
-
var _a3,
|
|
17516
|
+
var _a3, _b3;
|
|
15629
17517
|
return {
|
|
15630
17518
|
backgroundColor: ((_a3 = page == null ? void 0 : page.settings) == null ? void 0 : _a3.backgroundColor) || "#ffffff",
|
|
15631
|
-
backgroundGradient: (
|
|
17519
|
+
backgroundGradient: (_b3 = page == null ? void 0 : page.settings) == null ? void 0 : _b3.backgroundGradient
|
|
15632
17520
|
};
|
|
15633
17521
|
}, [(_d = page == null ? void 0 : page.settings) == null ? void 0 : _d.backgroundColor, (_e = page == null ? void 0 : page.settings) == null ? void 0 : _e.backgroundGradient]);
|
|
15634
17522
|
const projectSettings = react.useMemo(() => {
|
|
15635
|
-
var _a3,
|
|
17523
|
+
var _a3, _b3, _c2;
|
|
15636
17524
|
const vars = ((_a3 = config.themeConfig) == null ? void 0 : _a3.variables) || {};
|
|
15637
17525
|
return {
|
|
15638
17526
|
showGrid: false,
|
|
@@ -15640,7 +17528,7 @@ function PreviewCanvas({
|
|
|
15640
17528
|
gridSize: 10,
|
|
15641
17529
|
snapToGuides: false,
|
|
15642
17530
|
snapThreshold: 5,
|
|
15643
|
-
primaryColor: (
|
|
17531
|
+
primaryColor: (_b3 = vars.primary) == null ? void 0 : _b3.value,
|
|
15644
17532
|
secondaryColor: (_c2 = vars.secondary) == null ? void 0 : _c2.value
|
|
15645
17533
|
};
|
|
15646
17534
|
}, [config.themeConfig]);
|
|
@@ -15792,7 +17680,7 @@ const PreviewCanvas$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
|
|
|
15792
17680
|
PreviewCanvas
|
|
15793
17681
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
15794
17682
|
function applyThemeToConfig(config, themeOverrides) {
|
|
15795
|
-
var _a2,
|
|
17683
|
+
var _a2, _b2, _c;
|
|
15796
17684
|
if (!themeOverrides || Object.keys(themeOverrides).length === 0) return config;
|
|
15797
17685
|
const cloned = JSON.parse(JSON.stringify(config));
|
|
15798
17686
|
if ((_a2 = cloned.themeConfig) == null ? void 0 : _a2.variables) {
|
|
@@ -15803,7 +17691,7 @@ function applyThemeToConfig(config, themeOverrides) {
|
|
|
15803
17691
|
}
|
|
15804
17692
|
}
|
|
15805
17693
|
const varMap = /* @__PURE__ */ new Map();
|
|
15806
|
-
if ((
|
|
17694
|
+
if ((_b2 = cloned.themeConfig) == null ? void 0 : _b2.variables) {
|
|
15807
17695
|
for (const [key, def] of Object.entries(cloned.themeConfig.variables)) {
|
|
15808
17696
|
varMap.set(key, themeOverrides[key] ?? def.value);
|
|
15809
17697
|
}
|
|
@@ -15840,7 +17728,7 @@ function mapFormDefFieldType(t) {
|
|
|
15840
17728
|
function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
15841
17729
|
const sections = [];
|
|
15842
17730
|
function convert(defs, parentId) {
|
|
15843
|
-
var _a2,
|
|
17731
|
+
var _a2, _b2;
|
|
15844
17732
|
for (const def of defs) {
|
|
15845
17733
|
const isRepeatable = def.repeatable === true || def.type === "repeatable";
|
|
15846
17734
|
const defFields = def.fields ?? def.entryFields ?? [];
|
|
@@ -15892,7 +17780,7 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
15892
17780
|
placeholder: f.placeholder
|
|
15893
17781
|
}))
|
|
15894
17782
|
});
|
|
15895
|
-
if ((
|
|
17783
|
+
if ((_b2 = def.children) == null ? void 0 : _b2.length) {
|
|
15896
17784
|
convert(def.children, def.id);
|
|
15897
17785
|
}
|
|
15898
17786
|
}
|
|
@@ -16521,7 +18409,7 @@ function findAllRepeatableElementsBySourceId(pages, baseNodeId, oneBasedIndex, s
|
|
|
16521
18409
|
return out;
|
|
16522
18410
|
}
|
|
16523
18411
|
function findNestedRepeatableElementBySourceId(pages, parentBaseNodeId, parentPi, childBaseNodeId, childCi, sourceElementId) {
|
|
16524
|
-
var _a2,
|
|
18412
|
+
var _a2, _b2;
|
|
16525
18413
|
const parentGroups = collectGroupsByBaseId(pages, parentBaseNodeId);
|
|
16526
18414
|
const parentGroup = parentGroups[parentPi - 1];
|
|
16527
18415
|
if (!parentGroup || !isGroup(parentGroup) || !((_a2 = parentGroup.children) == null ? void 0 : _a2.length)) return void 0;
|
|
@@ -16536,7 +18424,7 @@ function findNestedRepeatableElementBySourceId(pages, parentBaseNodeId, parentPi
|
|
|
16536
18424
|
}
|
|
16537
18425
|
collectChild(parentGroup.children);
|
|
16538
18426
|
const childGroup = childGroups[childCi - 1];
|
|
16539
|
-
if (!childGroup || !isGroup(childGroup) || !((
|
|
18427
|
+
if (!childGroup || !isGroup(childGroup) || !((_b2 = childGroup.children) == null ? void 0 : _b2.length)) return void 0;
|
|
16540
18428
|
return findElementBySourceIdInSubtree(childGroup.children, sourceElementId) ?? (childGroup.__sourceId === sourceElementId ? childGroup.id : void 0);
|
|
16541
18429
|
}
|
|
16542
18430
|
function repeatableLabelKey(label) {
|
|
@@ -16586,7 +18474,7 @@ function getRepeatableFromConfig(pages) {
|
|
|
16586
18474
|
var _a2;
|
|
16587
18475
|
const result = [];
|
|
16588
18476
|
function walk(children) {
|
|
16589
|
-
var _a3,
|
|
18477
|
+
var _a3, _b2;
|
|
16590
18478
|
if (!children) return;
|
|
16591
18479
|
for (const node of children) {
|
|
16592
18480
|
if (isGroup(node) && isVerticalStackLayoutMode(node.layoutMode) && ((_a3 = node.children) == null ? void 0 : _a3.length)) {
|
|
@@ -16595,7 +18483,7 @@ function getRepeatableFromConfig(pages) {
|
|
|
16595
18483
|
if (rep == null ? void 0 : rep.label) result.push({ nodeId: child.id, label: rep.label });
|
|
16596
18484
|
}
|
|
16597
18485
|
}
|
|
16598
|
-
if (isGroup(node) && ((
|
|
18486
|
+
if (isGroup(node) && ((_b2 = node.children) == null ? void 0 : _b2.length)) walk(node.children);
|
|
16599
18487
|
}
|
|
16600
18488
|
}
|
|
16601
18489
|
for (const page of pages) if ((_a2 = page.children) == null ? void 0 : _a2.length) walk(page.children);
|
|
@@ -16611,7 +18499,7 @@ function findRepeatableByNodeIds(pages, nodeIds) {
|
|
|
16611
18499
|
return !!((_a3 = n.repeatableSection) == null ? void 0 : _a3.label);
|
|
16612
18500
|
};
|
|
16613
18501
|
function walk(children, parentRepeatableBaseId, parentInfo, parentRepeatableEntryIndex) {
|
|
16614
|
-
var _a3,
|
|
18502
|
+
var _a3, _b2;
|
|
16615
18503
|
if (!Array.isArray(children)) return;
|
|
16616
18504
|
for (let i = 0; i < children.length; i++) {
|
|
16617
18505
|
const node = children[i];
|
|
@@ -16654,7 +18542,7 @@ function findRepeatableByNodeIds(pages, nodeIds) {
|
|
|
16654
18542
|
if (isGroup(child) && Array.isArray(child.children)) walk(child.children, effectiveChildBase, void 0, childEntryIndex);
|
|
16655
18543
|
j += count;
|
|
16656
18544
|
}
|
|
16657
|
-
} else if (isGroup(node) && ((
|
|
18545
|
+
} else if (isGroup(node) && ((_b2 = node.children) == null ? void 0 : _b2.length)) {
|
|
16658
18546
|
const nodeBase = baseId(node.id);
|
|
16659
18547
|
const selfMatch = schemaBaseIds.has(node.id) || schemaBaseIds.has(nodeBase) || node.__baseNodeId != null && schemaBaseIds.has(node.__baseNodeId);
|
|
16660
18548
|
const isSelfRepeatable = selfMatch && hasRepeatableSection(node);
|
|
@@ -16743,7 +18631,7 @@ function getNestedRepeatableEntryCount(parentId, parentIndex, childId, formValue
|
|
|
16743
18631
|
return Math.max(1, maxIndex);
|
|
16744
18632
|
}
|
|
16745
18633
|
function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsFromSchema, repeatableEntryCounts, repeatableNestedEntryCounts, displayFormatMap, repeatablePagesFromSchema) {
|
|
16746
|
-
var _a2,
|
|
18634
|
+
var _a2, _b2, _c;
|
|
16747
18635
|
const cloned = JSON.parse(JSON.stringify(config));
|
|
16748
18636
|
if (!cloned.pages) return cloned;
|
|
16749
18637
|
const dynamicFields = cloned.dynamicFields;
|
|
@@ -16924,7 +18812,7 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
|
|
|
16924
18812
|
const { node, baseNodeId, startIndex, count } = block;
|
|
16925
18813
|
const occIdx = block.__occurrenceIndex ?? 1;
|
|
16926
18814
|
const N = computeN(baseNodeId, node.id);
|
|
16927
|
-
const entryFilter = ((
|
|
18815
|
+
const entryFilter = ((_b2 = node.repeatableSection) == null ? void 0 : _b2.entryFilter) ?? entryFilterFromList(baseNodeId);
|
|
16928
18816
|
let entryIndices;
|
|
16929
18817
|
if (entryFilter && entryFilter.mode === "range" && entryFilter.range) {
|
|
16930
18818
|
const parsed = parseEntryRange(entryFilter.range, N, entryMetaFromList(baseNodeId));
|
|
@@ -17381,7 +19269,7 @@ function findAllFlowStacks(pageChildren) {
|
|
|
17381
19269
|
return result;
|
|
17382
19270
|
}
|
|
17383
19271
|
function findNestedFlowStack(entry) {
|
|
17384
|
-
var _a2,
|
|
19272
|
+
var _a2, _b2;
|
|
17385
19273
|
const queue = [...entry.children ?? []];
|
|
17386
19274
|
while (queue.length > 0) {
|
|
17387
19275
|
const node = queue.shift();
|
|
@@ -17389,7 +19277,7 @@ function findNestedFlowStack(entry) {
|
|
|
17389
19277
|
const g = node;
|
|
17390
19278
|
const hasRepeatableChildren = ((_a2 = g.children) == null ? void 0 : _a2.length) && (g.children.some(hasBaseNodeId) || g.children.some((c) => isGroup(c)));
|
|
17391
19279
|
if (isVerticalStackLayoutMode(g.layoutMode) && hasRepeatableChildren) return g;
|
|
17392
|
-
if ((
|
|
19280
|
+
if ((_b2 = g.children) == null ? void 0 : _b2.length) queue.push(...g.children);
|
|
17393
19281
|
}
|
|
17394
19282
|
return null;
|
|
17395
19283
|
}
|
|
@@ -17520,9 +19408,9 @@ function splitNestedForOverflow(flowStack, stayChildren, overflowChildren, overf
|
|
|
17520
19408
|
return { stayChildren: newStay, overflowChildren: newOverflow };
|
|
17521
19409
|
}
|
|
17522
19410
|
function paginateSinglePage(sourcePage, pageOffsetIndex) {
|
|
17523
|
-
var _a2,
|
|
19411
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
17524
19412
|
const contentTop = (_a2 = sourcePage.settings) == null ? void 0 : _a2.contentTop;
|
|
17525
|
-
const contentBottom = (
|
|
19413
|
+
const contentBottom = (_b2 = sourcePage.settings) == null ? void 0 : _b2.contentBottom;
|
|
17526
19414
|
if (contentTop == null || contentBottom == null || contentBottom <= contentTop) {
|
|
17527
19415
|
return [sourcePage];
|
|
17528
19416
|
}
|
|
@@ -18712,7 +20600,7 @@ function splitIntoRuns(text, mainSupportsChar) {
|
|
|
18712
20600
|
return runs;
|
|
18713
20601
|
}
|
|
18714
20602
|
function rewriteSvgFontsForJsPDF(svgStr) {
|
|
18715
|
-
var _a2,
|
|
20603
|
+
var _a2, _b2;
|
|
18716
20604
|
const parser = new DOMParser();
|
|
18717
20605
|
const doc = parser.parseFromString(svgStr, "image/svg+xml");
|
|
18718
20606
|
const allTextEls = Array.from(doc.querySelectorAll("text, tspan, textPath"));
|
|
@@ -18817,7 +20705,7 @@ function rewriteSvgFontsForJsPDF(svgStr) {
|
|
|
18817
20705
|
for (const node of childNodes) {
|
|
18818
20706
|
if (node.nodeType !== 3 || !node.textContent) continue;
|
|
18819
20707
|
const runs = splitIntoRuns(node.textContent, mainSupportsChar);
|
|
18820
|
-
if (runs.length <= 1 && ((
|
|
20708
|
+
if (runs.length <= 1 && ((_b2 = runs[0]) == null ? void 0 : _b2.runType) === "main") continue;
|
|
18821
20709
|
const fragment = doc.createDocumentFragment();
|
|
18822
20710
|
for (const run of runs) {
|
|
18823
20711
|
const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan");
|
|
@@ -19127,9 +21015,9 @@ function appendDataUriFontFaceRule(family, weight, style, dataUri) {
|
|
|
19127
21015
|
styleEl.appendChild(document.createTextNode(cssText));
|
|
19128
21016
|
}
|
|
19129
21017
|
function resolveHarnessFontProxyUrl() {
|
|
19130
|
-
var _a2,
|
|
21018
|
+
var _a2, _b2;
|
|
19131
21019
|
try {
|
|
19132
|
-
const runtimeBase = typeof window !== "undefined" && (window.__PIXLDOCS_SUPABASE_URL || ((_a2 = window.__CONFIG__) == null ? void 0 : _a2.supabaseUrl)) || typeof globalThis !== "undefined" && (globalThis.__PIXLDOCS_SUPABASE_URL || ((
|
|
21020
|
+
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)) || "";
|
|
19133
21021
|
const base = String(runtimeBase || "").replace(/\/$/, "");
|
|
19134
21022
|
return base ? `${base}/functions/v1/font-proxy` : "";
|
|
19135
21023
|
} catch {
|
|
@@ -19791,7 +21679,7 @@ async function resolveTemplateData(options) {
|
|
|
19791
21679
|
};
|
|
19792
21680
|
}
|
|
19793
21681
|
async function resolveFromForm(options) {
|
|
19794
|
-
var _a2,
|
|
21682
|
+
var _a2, _b2, _c;
|
|
19795
21683
|
const { templateId, formSchemaId, sectionState, flatFormData: directFlatFormData, themeId, supabaseUrl, supabaseAnonKey, prefetched } = options;
|
|
19796
21684
|
const hasSectionStateInput = !!sectionState && Object.keys(sectionState).length > 0;
|
|
19797
21685
|
if (!formSchemaId && !hasSectionStateInput) {
|
|
@@ -19841,7 +21729,7 @@ async function resolveFromForm(options) {
|
|
|
19841
21729
|
inferredSections = inferFormSchemaFromTemplate(
|
|
19842
21730
|
templateConfig.dynamicFields,
|
|
19843
21731
|
groups,
|
|
19844
|
-
((
|
|
21732
|
+
((_b2 = templateConfig.pages) == null ? void 0 : _b2.length) ? { pages: templateConfig.pages } : void 0
|
|
19845
21733
|
);
|
|
19846
21734
|
} else {
|
|
19847
21735
|
inferredSections = [];
|
|
@@ -20028,10 +21916,10 @@ function themeBaseId(id) {
|
|
|
20028
21916
|
return out;
|
|
20029
21917
|
}
|
|
20030
21918
|
function applyThemeVariantToConfig(config, themeConfig, themeId) {
|
|
20031
|
-
var _a2,
|
|
21919
|
+
var _a2, _b2, _c, _d;
|
|
20032
21920
|
if (!themeConfig) return config;
|
|
20033
21921
|
const variant = themeId && themeId !== "default" ? (_a2 = themeConfig.variants) == null ? void 0 : _a2.find((v) => v.id === themeId) : null;
|
|
20034
|
-
const shouldApplyDefaults = !variant && ((
|
|
21922
|
+
const shouldApplyDefaults = !variant && ((_b2 = themeConfig.properties) == null ? void 0 : _b2.length);
|
|
20035
21923
|
if (!variant && !shouldApplyDefaults) return config;
|
|
20036
21924
|
if (!((_c = themeConfig.properties) == null ? void 0 : _c.length)) return config;
|
|
20037
21925
|
const result = JSON.parse(JSON.stringify(config));
|
|
@@ -20052,8 +21940,8 @@ function applyThemeVariantToConfig(config, themeConfig, themeId) {
|
|
|
20052
21940
|
if (stopMatch) {
|
|
20053
21941
|
const stopIndex = parseInt(stopMatch[1], 10);
|
|
20054
21942
|
result.pages.forEach((p) => {
|
|
20055
|
-
var _a3,
|
|
20056
|
-
if ((
|
|
21943
|
+
var _a3, _b3;
|
|
21944
|
+
if ((_b3 = (_a3 = p.settings.backgroundGradient) == null ? void 0 : _a3.stops) == null ? void 0 : _b3[stopIndex]) {
|
|
20057
21945
|
p.settings.backgroundGradient = {
|
|
20058
21946
|
...p.settings.backgroundGradient,
|
|
20059
21947
|
stops: p.settings.backgroundGradient.stops.map(
|
|
@@ -20130,7 +22018,7 @@ function normalizeLayoutModes(config) {
|
|
|
20130
22018
|
}
|
|
20131
22019
|
}
|
|
20132
22020
|
function paintRepeatableSections(config, repeatableSections, formSchema) {
|
|
20133
|
-
var _a2,
|
|
22021
|
+
var _a2, _b2;
|
|
20134
22022
|
const pages = config.pages ?? [];
|
|
20135
22023
|
const entryFilters = (formSchema == null ? void 0 : formSchema.entryFilters) ?? [];
|
|
20136
22024
|
const entryFilterBases = new Set(entryFilters.map((f) => baseId(f.nodeId)));
|
|
@@ -20158,7 +22046,7 @@ function paintRepeatableSections(config, repeatableSections, formSchema) {
|
|
|
20158
22046
|
return painted;
|
|
20159
22047
|
}
|
|
20160
22048
|
for (const section of repeatableSections) {
|
|
20161
|
-
const inlineRange = ((_a2 = section.entryFilter) == null ? void 0 : _a2.mode) === "range" ? (
|
|
22049
|
+
const inlineRange = ((_a2 = section.entryFilter) == null ? void 0 : _a2.mode) === "range" ? (_b2 = section.entryFilter.range) == null ? void 0 : _b2.trim() : void 0;
|
|
20162
22050
|
const shouldUseInlineFilter = !!inlineRange && !entryFilterBases.has(baseId(section.nodeId));
|
|
20163
22051
|
const payload = { label: section.label };
|
|
20164
22052
|
if (section.minEntries !== void 0) payload.minEntries = section.minEntries;
|
|
@@ -20194,7 +22082,7 @@ function paintRepeatableSections(config, repeatableSections, formSchema) {
|
|
|
20194
22082
|
}
|
|
20195
22083
|
}
|
|
20196
22084
|
async function getTemplateForm(options) {
|
|
20197
|
-
var _a2,
|
|
22085
|
+
var _a2, _b2;
|
|
20198
22086
|
const { templateId, supabaseUrl, supabaseAnonKey } = options;
|
|
20199
22087
|
if (!supabaseUrl || !supabaseAnonKey) {
|
|
20200
22088
|
throw new Error("[getTemplateForm] supabaseUrl and supabaseAnonKey are required");
|
|
@@ -20238,7 +22126,7 @@ async function getTemplateForm(options) {
|
|
|
20238
22126
|
sections = inferFormSchemaFromTemplate(
|
|
20239
22127
|
templateConfig.dynamicFields,
|
|
20240
22128
|
templateConfig.fieldGroups || [],
|
|
20241
|
-
((
|
|
22129
|
+
((_b2 = templateConfig.pages) == null ? void 0 : _b2.length) ? { pages: templateConfig.pages } : void 0
|
|
20242
22130
|
);
|
|
20243
22131
|
} else {
|
|
20244
22132
|
sections = [];
|
|
@@ -20622,7 +22510,7 @@ function computeFrostedBoundsForPage(config, pageIndex, extraBaseIds, extraExact
|
|
|
20622
22510
|
return out;
|
|
20623
22511
|
}
|
|
20624
22512
|
function PixldocsPreview(props) {
|
|
20625
|
-
var _a2,
|
|
22513
|
+
var _a2, _b2;
|
|
20626
22514
|
const {
|
|
20627
22515
|
pageIndex = 0,
|
|
20628
22516
|
zoom = 1,
|
|
@@ -20690,10 +22578,10 @@ function PixldocsPreview(props) {
|
|
|
20690
22578
|
supabaseUrl: p.supabaseUrl,
|
|
20691
22579
|
supabaseAnonKey: p.supabaseAnonKey
|
|
20692
22580
|
}).then((resolved) => {
|
|
20693
|
-
var _a3,
|
|
22581
|
+
var _a3, _b3;
|
|
20694
22582
|
if (!cancelled) {
|
|
20695
22583
|
console.log(PREVIEW_DEBUG_PREFIX, "resolve-done", {
|
|
20696
|
-
pages: ((
|
|
22584
|
+
pages: ((_b3 = (_a3 = resolved.config) == null ? void 0 : _a3.pages) == null ? void 0 : _b3.length) ?? 0,
|
|
20697
22585
|
underlinedNodes: countUnderlinedNodes(resolved.config)
|
|
20698
22586
|
});
|
|
20699
22587
|
setResolvedConfig(resolved.config);
|
|
@@ -20803,7 +22691,7 @@ function PixldocsPreview(props) {
|
|
|
20803
22691
|
const satPct = (frostedBlurOptions == null ? void 0 : frostedBlurOptions.saturatePct) ?? 130;
|
|
20804
22692
|
const bgTint = (frostedBlurOptions == null ? void 0 : frostedBlurOptions.background) ?? "rgba(255,255,255,0.12)";
|
|
20805
22693
|
const canvasW = getNum((_a2 = config == null ? void 0 : config.canvas) == null ? void 0 : _a2.width, 0);
|
|
20806
|
-
const canvasH = getNum((
|
|
22694
|
+
const canvasH = getNum((_b2 = config == null ? void 0 : config.canvas) == null ? void 0 : _b2.height, 0);
|
|
20807
22695
|
const hasOverlays = frostedBounds.length > 0 && canvasW > 0 && canvasH > 0;
|
|
20808
22696
|
if (isLoading) {
|
|
20809
22697
|
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..." }) });
|
|
@@ -20944,7 +22832,7 @@ function ensureFabricGradientDef(doc, obj, width, height) {
|
|
|
20944
22832
|
return `url(#${id})`;
|
|
20945
22833
|
}
|
|
20946
22834
|
function warpTextboxSvgAlongPath(svg, obj) {
|
|
20947
|
-
var _a2,
|
|
22835
|
+
var _a2, _b2, _c, _d, _e;
|
|
20948
22836
|
const tp = obj == null ? void 0 : obj.textPath;
|
|
20949
22837
|
if (!tp || !tp.preset || tp.preset === "none") return svg;
|
|
20950
22838
|
if (tp.preset === "rise" || tp.preset === "angle") {
|
|
@@ -21008,7 +22896,7 @@ function warpTextboxSvgAlongPath(svg, obj) {
|
|
|
21008
22896
|
}
|
|
21009
22897
|
for (const clone of Array.from(doc.querySelectorAll("g.__pdTextShadowClone"))) {
|
|
21010
22898
|
try {
|
|
21011
|
-
(
|
|
22899
|
+
(_b2 = clone.parentNode) == null ? void 0 : _b2.removeChild(clone);
|
|
21012
22900
|
} catch {
|
|
21013
22901
|
}
|
|
21014
22902
|
}
|
|
@@ -21028,9 +22916,9 @@ function warpTextboxSvgAlongPath(svg, obj) {
|
|
|
21028
22916
|
const fw = obj.fontWeight ?? 400;
|
|
21029
22917
|
const fst = obj.fontStyle || "normal";
|
|
21030
22918
|
const readFill = (el) => {
|
|
21031
|
-
var _a3,
|
|
22919
|
+
var _a3, _b3;
|
|
21032
22920
|
if (!el) return "";
|
|
21033
|
-
return el.getAttribute("fill") || ((
|
|
22921
|
+
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()) || "";
|
|
21034
22922
|
};
|
|
21035
22923
|
const w = Number(obj.width) || 0;
|
|
21036
22924
|
const h = Number(obj.height) || 0;
|
|
@@ -21383,9 +23271,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
21383
23271
|
}
|
|
21384
23272
|
return svgString;
|
|
21385
23273
|
}
|
|
21386
|
-
const resolvedPackageVersion = "0.5.
|
|
23274
|
+
const resolvedPackageVersion = "0.5.243";
|
|
21387
23275
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
21388
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
23276
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.243";
|
|
21389
23277
|
const roundParityValue = (value) => {
|
|
21390
23278
|
if (typeof value !== "number") return value;
|
|
21391
23279
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -21562,11 +23450,11 @@ function installUnderlineFix(fab) {
|
|
|
21562
23450
|
if (!TextProto || typeof TextProto._renderTextDecoration !== "function") return;
|
|
21563
23451
|
const original = TextProto._renderTextDecoration;
|
|
21564
23452
|
const measureLineTextWidth = (obj, ctx, lineIndex) => {
|
|
21565
|
-
var _a3,
|
|
23453
|
+
var _a3, _b2, _c, _d, _e, _f;
|
|
21566
23454
|
const rawLine = (_a3 = obj._textLines) == null ? void 0 : _a3[lineIndex];
|
|
21567
23455
|
const lineText = Array.isArray(rawLine) ? rawLine.join("") : String(rawLine ?? "");
|
|
21568
23456
|
if (!lineText) return 0;
|
|
21569
|
-
const fontSize = Number(((
|
|
23457
|
+
const fontSize = Number(((_b2 = obj.getValueOfPropertyAt) == null ? void 0 : _b2.call(obj, lineIndex, 0, "fontSize")) ?? obj.fontSize ?? 0);
|
|
21570
23458
|
const fontStyle = String(((_c = obj.getValueOfPropertyAt) == null ? void 0 : _c.call(obj, lineIndex, 0, "fontStyle")) ?? obj.fontStyle ?? "normal");
|
|
21571
23459
|
const fontWeight = String(((_d = obj.getValueOfPropertyAt) == null ? void 0 : _d.call(obj, lineIndex, 0, "fontWeight")) ?? obj.fontWeight ?? "400");
|
|
21572
23460
|
const fontFamily = String(((_e = obj.getValueOfPropertyAt) == null ? void 0 : _e.call(obj, lineIndex, 0, "fontFamily")) ?? obj.fontFamily ?? "sans-serif");
|
|
@@ -21706,11 +23594,78 @@ function installTextboxBoxExtensions(fab) {
|
|
|
21706
23594
|
if (Array.isArray(stateProps2)) {
|
|
21707
23595
|
if (!stateProps2.includes("minBoxHeight")) stateProps2.push("minBoxHeight");
|
|
21708
23596
|
if (!stateProps2.includes("verticalAlign")) stateProps2.push("verticalAlign");
|
|
23597
|
+
if (!stateProps2.includes("smartWrap")) stateProps2.push("smartWrap");
|
|
21709
23598
|
}
|
|
21710
23599
|
const cacheProps2 = TextboxProto2.cacheProperties;
|
|
21711
23600
|
if (Array.isArray(cacheProps2)) {
|
|
21712
23601
|
if (!cacheProps2.includes("minBoxHeight")) cacheProps2.push("minBoxHeight");
|
|
21713
23602
|
if (!cacheProps2.includes("verticalAlign")) cacheProps2.push("verticalAlign");
|
|
23603
|
+
if (!cacheProps2.includes("smartWrap")) cacheProps2.push("smartWrap");
|
|
23604
|
+
}
|
|
23605
|
+
TextboxProto2.smartWrap = true;
|
|
23606
|
+
if (typeof TextboxProto2._wrapLine === "function" && !TextboxProto2.__pixldocsOrigWrapLine) {
|
|
23607
|
+
const origWrapLine = TextboxProto2._wrapLine;
|
|
23608
|
+
TextboxProto2.__pixldocsOrigWrapLine = origWrapLine;
|
|
23609
|
+
TextboxProto2._wrapLine = function(lineIndex, desiredWidth, ref, reservedSpace = 0) {
|
|
23610
|
+
var _a3;
|
|
23611
|
+
if (!this.smartWrap || this.splitByGrapheme) {
|
|
23612
|
+
return origWrapLine.call(this, lineIndex, desiredWidth, ref, reservedSpace);
|
|
23613
|
+
}
|
|
23614
|
+
try {
|
|
23615
|
+
const additionalSpace = this._getWidthOfCharSpacing();
|
|
23616
|
+
const data = ((_a3 = ref == null ? void 0 : ref.wordsData) == null ? void 0 : _a3[lineIndex]) || [];
|
|
23617
|
+
const effective = Math.max(1, desiredWidth - reservedSpace);
|
|
23618
|
+
const infix = " ";
|
|
23619
|
+
const infixWidth = this._measureWord([infix], lineIndex, 0);
|
|
23620
|
+
const graphemeLines = [];
|
|
23621
|
+
let line = [];
|
|
23622
|
+
let lineWidth = 0;
|
|
23623
|
+
let lineJustStarted = true;
|
|
23624
|
+
let largestWordWidth = 0;
|
|
23625
|
+
let offset = 0;
|
|
23626
|
+
const pushLine = () => {
|
|
23627
|
+
graphemeLines.push(line);
|
|
23628
|
+
line = [];
|
|
23629
|
+
lineWidth = 0;
|
|
23630
|
+
lineJustStarted = true;
|
|
23631
|
+
};
|
|
23632
|
+
for (let i = 0; i < data.length; i++) {
|
|
23633
|
+
const { word, width: wordWidth } = data[i];
|
|
23634
|
+
if (wordWidth <= effective) {
|
|
23635
|
+
if (wordWidth > largestWordWidth) largestWordWidth = wordWidth;
|
|
23636
|
+
const projected = lineJustStarted ? wordWidth : lineWidth + infixWidth + wordWidth - additionalSpace;
|
|
23637
|
+
if (!lineJustStarted && projected > effective) pushLine();
|
|
23638
|
+
if (!lineJustStarted) {
|
|
23639
|
+
line.push(infix);
|
|
23640
|
+
lineWidth += infixWidth;
|
|
23641
|
+
}
|
|
23642
|
+
line = line.concat(word);
|
|
23643
|
+
lineWidth += wordWidth;
|
|
23644
|
+
lineJustStarted = false;
|
|
23645
|
+
} else {
|
|
23646
|
+
if (!lineJustStarted) pushLine();
|
|
23647
|
+
for (const g of word) {
|
|
23648
|
+
const gw = this._measureWord([g], lineIndex, offset);
|
|
23649
|
+
if (gw > largestWordWidth) largestWordWidth = gw;
|
|
23650
|
+
const gProj = lineJustStarted ? gw : lineWidth + gw - additionalSpace;
|
|
23651
|
+
if (!lineJustStarted && gProj > effective) pushLine();
|
|
23652
|
+
line.push(g);
|
|
23653
|
+
lineWidth += gw;
|
|
23654
|
+
lineJustStarted = false;
|
|
23655
|
+
offset++;
|
|
23656
|
+
}
|
|
23657
|
+
offset -= word.length;
|
|
23658
|
+
}
|
|
23659
|
+
offset += word.length + 1;
|
|
23660
|
+
}
|
|
23661
|
+
if (line.length) graphemeLines.push(line);
|
|
23662
|
+
const minNeeded = Math.max(0, Math.min(largestWordWidth, effective) - additionalSpace + reservedSpace);
|
|
23663
|
+
if (minNeeded > this.dynamicMinWidth) this.dynamicMinWidth = minNeeded;
|
|
23664
|
+
return graphemeLines;
|
|
23665
|
+
} catch (e) {
|
|
23666
|
+
return origWrapLine.call(this, lineIndex, desiredWidth, ref, reservedSpace);
|
|
23667
|
+
}
|
|
23668
|
+
};
|
|
21714
23669
|
}
|
|
21715
23670
|
TextboxProto2.__pixldocsTextboxExtended = true;
|
|
21716
23671
|
__textboxBoxExtensionsInstalled = true;
|
|
@@ -22132,7 +24087,7 @@ class PixldocsRenderer {
|
|
|
22132
24087
|
await this.waitForCanvasScene(container, cloned, i);
|
|
22133
24088
|
}
|
|
22134
24089
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
22135
|
-
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
24090
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-V2qBQ4Xs.cjs"));
|
|
22136
24091
|
const prepared = preparePagesForExport(
|
|
22137
24092
|
cloned.pages,
|
|
22138
24093
|
canvasWidth,
|
|
@@ -22349,9 +24304,9 @@ class PixldocsRenderer {
|
|
|
22349
24304
|
}
|
|
22350
24305
|
waitForCanvasScene(container, config, pageIndex, maxWaitMs = 8e3, pollMs = 50) {
|
|
22351
24306
|
return new Promise((resolve) => {
|
|
22352
|
-
var _a2,
|
|
24307
|
+
var _a2, _b2;
|
|
22353
24308
|
const start = Date.now();
|
|
22354
|
-
const pageHasContent = (((
|
|
24309
|
+
const pageHasContent = (((_b2 = (_a2 = config.pages[pageIndex]) == null ? void 0 : _a2.children) == null ? void 0 : _b2.length) ?? 0) > 0;
|
|
22355
24310
|
const settle = () => requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
|
|
22356
24311
|
const check = () => {
|
|
22357
24312
|
const fabricCanvas = this.getFabricCanvasFromContainer(container);
|
|
@@ -22426,9 +24381,9 @@ class PixldocsRenderer {
|
|
|
22426
24381
|
return normalized;
|
|
22427
24382
|
}
|
|
22428
24383
|
paintPageBackground(ctx, page, width, height) {
|
|
22429
|
-
var _a2,
|
|
24384
|
+
var _a2, _b2;
|
|
22430
24385
|
const backgroundColor = ((_a2 = page == null ? void 0 : page.settings) == null ? void 0 : _a2.backgroundColor) || "#ffffff";
|
|
22431
|
-
const gradient = (
|
|
24386
|
+
const gradient = (_b2 = page == null ? void 0 : page.settings) == null ? void 0 : _b2.backgroundGradient;
|
|
22432
24387
|
ctx.clearRect(0, 0, width, height);
|
|
22433
24388
|
ctx.fillStyle = backgroundColor;
|
|
22434
24389
|
ctx.fillRect(0, 0, width, height);
|
|
@@ -22676,7 +24631,7 @@ class PixldocsRenderer {
|
|
|
22676
24631
|
};
|
|
22677
24632
|
const onReady = () => {
|
|
22678
24633
|
this.waitForCanvasScene(container, renderConfig, pageIndex).then(async () => {
|
|
22679
|
-
var _a2,
|
|
24634
|
+
var _a2, _b2;
|
|
22680
24635
|
try {
|
|
22681
24636
|
const expectedImageIds = this.getExpectedImageIds(renderConfig, pageIndex);
|
|
22682
24637
|
await this.waitForCanvasImages(container, expectedImageIds);
|
|
@@ -22695,7 +24650,7 @@ class PixldocsRenderer {
|
|
|
22695
24650
|
);
|
|
22696
24651
|
const page = renderConfig.pages[pageIndex];
|
|
22697
24652
|
const backgroundColor = ((_a2 = page == null ? void 0 : page.settings) == null ? void 0 : _a2.backgroundColor) || "#ffffff";
|
|
22698
|
-
const backgroundGradient = (
|
|
24653
|
+
const backgroundGradient = (_b2 = page == null ? void 0 : page.settings) == null ? void 0 : _b2.backgroundGradient;
|
|
22699
24654
|
cleanup();
|
|
22700
24655
|
resolve({
|
|
22701
24656
|
svg: svgString,
|
|
@@ -22816,7 +24771,7 @@ class PixldocsRenderer {
|
|
|
22816
24771
|
logJsonLine("[canvas-renderer][fabric-text-parity]", { stage, textboxes: sample.length, sample });
|
|
22817
24772
|
}
|
|
22818
24773
|
async waitForStableTextMetrics(container, config, options = {}) {
|
|
22819
|
-
var _a2,
|
|
24774
|
+
var _a2, _b2, _c;
|
|
22820
24775
|
if (typeof document !== "undefined") {
|
|
22821
24776
|
void ensureFontsForResolvedConfig(config);
|
|
22822
24777
|
await this.waitForRelevantFonts(config);
|
|
@@ -22858,7 +24813,7 @@ class PixldocsRenderer {
|
|
|
22858
24813
|
}
|
|
22859
24814
|
fabricInstance.getObjects().forEach(primeCharBounds);
|
|
22860
24815
|
(_a2 = fabricInstance.calcOffset) == null ? void 0 : _a2.call(fabricInstance);
|
|
22861
|
-
(
|
|
24816
|
+
(_b2 = fabricInstance.renderAll) == null ? void 0 : _b2.call(fabricInstance);
|
|
22862
24817
|
await waitForPaint();
|
|
22863
24818
|
(_c = fabricInstance.renderAll) == null ? void 0 : _c.call(fabricInstance);
|
|
22864
24819
|
await waitForPaint();
|
|
@@ -22899,7 +24854,7 @@ function dumpSvgTextDiagnostics(svgStr, pageIndex, tag, stage, maxItems = 30) {
|
|
|
22899
24854
|
};
|
|
22900
24855
|
logParityJson(tag, stage, { kind: "summary", ...summary });
|
|
22901
24856
|
const sample = texts.slice(0, maxItems).map((t, idx) => {
|
|
22902
|
-
var _a2,
|
|
24857
|
+
var _a2, _b2;
|
|
22903
24858
|
const tspans = Array.from(t.querySelectorAll("tspan"));
|
|
22904
24859
|
const tspanInfo = tspans.slice(0, 8).map((s) => ({
|
|
22905
24860
|
x: s.getAttribute("x"),
|
|
@@ -22916,7 +24871,7 @@ function dumpSvgTextDiagnostics(svgStr, pageIndex, tag, stage, maxItems = 30) {
|
|
|
22916
24871
|
while (cursor && !containerWidth) {
|
|
22917
24872
|
containerWidth = (_a2 = cursor.getAttribute) == null ? void 0 : _a2.call(cursor, "width");
|
|
22918
24873
|
cursor = cursor.parentElement;
|
|
22919
|
-
if (cursor && ((
|
|
24874
|
+
if (cursor && ((_b2 = cursor.tagName) == null ? void 0 : _b2.toLowerCase()) === "svg") break;
|
|
22920
24875
|
}
|
|
22921
24876
|
return {
|
|
22922
24877
|
idx,
|
|
@@ -23304,10 +25259,10 @@ function normalizeSvgExplicitColors(svg) {
|
|
|
23304
25259
|
return normalizeGradientPaintRef(v);
|
|
23305
25260
|
};
|
|
23306
25261
|
const hasExplicitNonePaint = (el, attr) => {
|
|
23307
|
-
var _a2,
|
|
25262
|
+
var _a2, _b2;
|
|
23308
25263
|
const raw = (el.getAttribute(attr) ?? ((_a2 = el.style) == null ? void 0 : _a2.getPropertyValue(attr)) ?? "").trim().toLowerCase();
|
|
23309
25264
|
if (raw === "none" || raw === "transparent") return true;
|
|
23310
|
-
const rawOpacity = (el.getAttribute(`${attr}-opacity`) ?? ((
|
|
25265
|
+
const rawOpacity = (el.getAttribute(`${attr}-opacity`) ?? ((_b2 = el.style) == null ? void 0 : _b2.getPropertyValue(`${attr}-opacity`)) ?? "").trim().toLowerCase();
|
|
23311
25266
|
return rawOpacity === "0" || rawOpacity === "0%" || rawOpacity === "0.0";
|
|
23312
25267
|
};
|
|
23313
25268
|
function walk(el, parentFill, parentStroke, parentColor) {
|
|
@@ -23374,14 +25329,14 @@ function normalizeSvgExplicitColors(svg) {
|
|
|
23374
25329
|
function bakeGroupOpacityIntoChildren(svg) {
|
|
23375
25330
|
const DRAWABLE = /* @__PURE__ */ new Set(["path", "rect", "circle", "ellipse", "polygon", "polyline", "line", "text", "tspan"]);
|
|
23376
25331
|
function walkAndBake(el, inheritedOpacity) {
|
|
23377
|
-
var _a2,
|
|
25332
|
+
var _a2, _b2, _c, _d;
|
|
23378
25333
|
if (isInSvgDefinitionSubtree(el)) {
|
|
23379
25334
|
for (let i = 0; i < el.children.length; i++) walkAndBake(el.children[i], 1);
|
|
23380
25335
|
return;
|
|
23381
25336
|
}
|
|
23382
25337
|
const tag = ((_a2 = el.tagName) == null ? void 0 : _a2.toLowerCase()) ?? "";
|
|
23383
25338
|
const opacityAttr = parseSvgOpacity(el.getAttribute("opacity"));
|
|
23384
|
-
const styleOpacity = parseSvgOpacity(((
|
|
25339
|
+
const styleOpacity = parseSvgOpacity(((_b2 = el.style) == null ? void 0 : _b2.getPropertyValue("opacity")) || null);
|
|
23385
25340
|
const ownOpacity = opacityAttr ?? styleOpacity ?? 1;
|
|
23386
25341
|
const combinedOpacity = inheritedOpacity * ownOpacity;
|
|
23387
25342
|
if (ownOpacity < 0.999 && tag !== "image") {
|
|
@@ -23904,10 +25859,10 @@ function getFirstExplicitColorFromSvg(svg) {
|
|
|
23904
25859
|
return getGradientStopColorAsHex(svg, gradientId);
|
|
23905
25860
|
};
|
|
23906
25861
|
function walk(el) {
|
|
23907
|
-
var _a2,
|
|
25862
|
+
var _a2, _b2;
|
|
23908
25863
|
if (fill && stroke) return;
|
|
23909
25864
|
const f = el.getAttribute("fill") ?? ((_a2 = el.style) == null ? void 0 : _a2.getPropertyValue("fill"));
|
|
23910
|
-
const s = el.getAttribute("stroke") ?? ((
|
|
25865
|
+
const s = el.getAttribute("stroke") ?? ((_b2 = el.style) == null ? void 0 : _b2.getPropertyValue("stroke"));
|
|
23911
25866
|
if (!fill) {
|
|
23912
25867
|
if (isRealColor(f)) fill = f;
|
|
23913
25868
|
else if (f) {
|
|
@@ -23935,8 +25890,8 @@ function isNearWhite(hex) {
|
|
|
23935
25890
|
return r >= 250 && g >= 250 && b >= 250;
|
|
23936
25891
|
}
|
|
23937
25892
|
function getStopColorRaw(stop) {
|
|
23938
|
-
var _a2,
|
|
23939
|
-
return stop.getAttribute("stop-color") ?? ((
|
|
25893
|
+
var _a2, _b2;
|
|
25894
|
+
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");
|
|
23940
25895
|
}
|
|
23941
25896
|
function getGradientStopColorAsHex(svgRoot, gradientId, visited = /* @__PURE__ */ new Set()) {
|
|
23942
25897
|
var _a2;
|
|
@@ -24000,12 +25955,12 @@ async function convertTextDecorationsToLines(svg) {
|
|
|
24000
25955
|
else el.removeAttribute("style");
|
|
24001
25956
|
};
|
|
24002
25957
|
const resolveInheritedSvgValue = (el, attr, styleProp = attr) => {
|
|
24003
|
-
var _a2,
|
|
25958
|
+
var _a2, _b2;
|
|
24004
25959
|
let current = el;
|
|
24005
25960
|
while (current) {
|
|
24006
25961
|
const attrValue = (_a2 = current.getAttribute(attr)) == null ? void 0 : _a2.trim();
|
|
24007
25962
|
if (attrValue) return attrValue;
|
|
24008
|
-
const styleValue = (
|
|
25963
|
+
const styleValue = (_b2 = getInlineStyleValue(current, styleProp)) == null ? void 0 : _b2.trim();
|
|
24009
25964
|
if (styleValue) return styleValue;
|
|
24010
25965
|
current = current.parentElement;
|
|
24011
25966
|
}
|
|
@@ -24183,7 +26138,7 @@ async function convertSvgTextDecorationsToLinesString(svgStr) {
|
|
|
24183
26138
|
}
|
|
24184
26139
|
}
|
|
24185
26140
|
async function rasterizeShadowMarkers(svg) {
|
|
24186
|
-
var _a2,
|
|
26141
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
24187
26142
|
if (typeof window === "undefined" || typeof document === "undefined") return;
|
|
24188
26143
|
const markers = Array.from(svg.querySelectorAll("g.__pdShadowRaster"));
|
|
24189
26144
|
if (markers.length === 0) return;
|
|
@@ -24207,7 +26162,7 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
24207
26162
|
const alphaRaw = parseFloat(marker.getAttribute("data-alpha") || "1");
|
|
24208
26163
|
const shadowAlpha = Number.isFinite(alphaRaw) ? Math.max(0, Math.min(1, alphaRaw)) : 1;
|
|
24209
26164
|
if (!Number.isFinite(bw) || !Number.isFinite(bh) || bw <= 0 || bh <= 0) {
|
|
24210
|
-
(
|
|
26165
|
+
(_b2 = marker.parentNode) == null ? void 0 : _b2.removeChild(marker);
|
|
24211
26166
|
continue;
|
|
24212
26167
|
}
|
|
24213
26168
|
const innerXml = restoreSourceFontsForShadowRaster(
|
|
@@ -24452,7 +26407,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
24452
26407
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
24453
26408
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
24454
26409
|
try {
|
|
24455
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
26410
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-V2qBQ4Xs.cjs"));
|
|
24456
26411
|
try {
|
|
24457
26412
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
24458
26413
|
} catch {
|
|
@@ -24468,7 +26423,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
24468
26423
|
}
|
|
24469
26424
|
}
|
|
24470
26425
|
function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundColor, backgroundGradient) {
|
|
24471
|
-
var _a2,
|
|
26426
|
+
var _a2, _b2;
|
|
24472
26427
|
if (backgroundGradient && ((_a2 = backgroundGradient.stops) == null ? void 0 : _a2.length) >= 2) {
|
|
24473
26428
|
const grad = backgroundGradient;
|
|
24474
26429
|
const colorStops = grad.stops.map((s) => {
|
|
@@ -24523,7 +26478,7 @@ function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundCol
|
|
|
24523
26478
|
doc.fill({ key: patternKey, matrix: doc.Matrix(1, 0, 0, 1, 0, 0) });
|
|
24524
26479
|
});
|
|
24525
26480
|
} catch {
|
|
24526
|
-
const fallback = ((
|
|
26481
|
+
const fallback = ((_b2 = colorStops[0]) == null ? void 0 : _b2.color) || [255, 255, 255];
|
|
24527
26482
|
pdf.setFillColor(fallback[0], fallback[1], fallback[2]);
|
|
24528
26483
|
pdf.rect(0, 0, pageWidth, pageHeight, "F");
|
|
24529
26484
|
}
|
|
@@ -24536,7 +26491,7 @@ function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundCol
|
|
|
24536
26491
|
}
|
|
24537
26492
|
}
|
|
24538
26493
|
async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
24539
|
-
var _a2,
|
|
26494
|
+
var _a2, _b2;
|
|
24540
26495
|
if (svgResults.length === 0) throw new Error("No pages to export");
|
|
24541
26496
|
const { title, stripPageBackground } = options;
|
|
24542
26497
|
const firstPage = svgResults[0];
|
|
@@ -24569,7 +26524,7 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
24569
26524
|
const pageOrientation = page.width > page.height ? "landscape" : "portrait";
|
|
24570
26525
|
pdf.addPage([page.width, page.height], pageOrientation);
|
|
24571
26526
|
}
|
|
24572
|
-
const hasGradient = !!((
|
|
26527
|
+
const hasGradient = !!((_b2 = (_a2 = page.backgroundGradient) == null ? void 0 : _a2.stops) == null ? void 0 : _b2.length);
|
|
24573
26528
|
drawPageBackground(pdf, i, page.width, page.height, page.backgroundColor, page.backgroundGradient);
|
|
24574
26529
|
const shouldStripBg = stripPageBackground ?? hasGradient;
|
|
24575
26530
|
const textMode = options.textMode ?? (options.outlineText === true ? "pixel-perfect" : "selectable");
|
|
@@ -24849,4 +26804,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
24849
26804
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
24850
26805
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
24851
26806
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
24852
|
-
//# sourceMappingURL=index-
|
|
26807
|
+
//# sourceMappingURL=index-UuNicsNZ.cjs.map
|