@pixldocs/canvas-renderer 0.5.240 → 0.5.242
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-B2H1tQ0S.js → index-BQ5V2uT8.js} +2429 -278
- package/dist/index-BQ5V2uT8.js.map +1 -0
- package/dist/{index-DBOS1ouN.cjs → index-YCh9sTg1.cjs} +2429 -278
- package/dist/index-YCh9sTg1.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-CHVrwSi7.js → vectorPdfExport-CsrQStE8.js} +4 -4
- package/dist/{vectorPdfExport-CHVrwSi7.js.map → vectorPdfExport-CsrQStE8.js.map} +1 -1
- package/dist/{vectorPdfExport-D1yCN3sm.cjs → vectorPdfExport-De9vylBF.cjs} +4 -4
- package/dist/{vectorPdfExport-D1yCN3sm.cjs.map → vectorPdfExport-De9vylBF.cjs.map} +1 -1
- package/package.json +1 -1
- package/dist/index-B2H1tQ0S.js.map +0 -1
- package/dist/index-DBOS1ouN.cjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
-
var _a;
|
|
4
|
+
var _a, _b;
|
|
5
5
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
6
6
|
import { forwardRef, useRef, useState, useCallback, useMemo, useEffect, useImperativeHandle, createElement } from "react";
|
|
7
7
|
import { flushSync } from "react-dom";
|
|
@@ -273,13 +273,13 @@ function lineToString(line) {
|
|
|
273
273
|
return Array.isArray(line) ? line.join("") : String(line ?? "");
|
|
274
274
|
}
|
|
275
275
|
function measureTextLineWithCanvas(textbox, lineText, lineIndex) {
|
|
276
|
-
var _a2,
|
|
276
|
+
var _a2, _b2, _c, _d, _e;
|
|
277
277
|
if (!lineText) return 0;
|
|
278
278
|
const ctx = getMeasureContext();
|
|
279
279
|
if (!ctx) return null;
|
|
280
280
|
const tb = textbox;
|
|
281
281
|
const fontSize = Number(((_a2 = tb.getValueOfPropertyAt) == null ? void 0 : _a2.call(tb, lineIndex, 0, "fontSize")) ?? textbox.fontSize ?? 16);
|
|
282
|
-
const fontStyle = String(((
|
|
282
|
+
const fontStyle = String(((_b2 = tb.getValueOfPropertyAt) == null ? void 0 : _b2.call(tb, lineIndex, 0, "fontStyle")) ?? textbox.fontStyle ?? "normal");
|
|
283
283
|
const fontWeight = String(((_c = tb.getValueOfPropertyAt) == null ? void 0 : _c.call(tb, lineIndex, 0, "fontWeight")) ?? textbox.fontWeight ?? "400");
|
|
284
284
|
const fontFamily = String(((_d = tb.getValueOfPropertyAt) == null ? void 0 : _d.call(tb, lineIndex, 0, "fontFamily")) ?? textbox.fontFamily ?? "Open Sans");
|
|
285
285
|
const charSpacing = Number(((_e = tb.getValueOfPropertyAt) == null ? void 0 : _e.call(tb, lineIndex, 0, "charSpacing")) ?? textbox.charSpacing ?? 0);
|
|
@@ -768,7 +768,7 @@ function resolveStackGroupEffectivePositions(group, pageChildren, options) {
|
|
|
768
768
|
return out;
|
|
769
769
|
}
|
|
770
770
|
function groupBoundsFromChildren(group, pageChildren, options) {
|
|
771
|
-
var _a2,
|
|
771
|
+
var _a2, _b2;
|
|
772
772
|
const kids = group.children ?? [];
|
|
773
773
|
if (kids.length === 0) {
|
|
774
774
|
const w = group.width;
|
|
@@ -784,7 +784,7 @@ function groupBoundsFromChildren(group, pageChildren, options) {
|
|
|
784
784
|
return { width: b.width, height: b.height };
|
|
785
785
|
})();
|
|
786
786
|
const cl = positions ? ((_a2 = positions.get(child.id)) == null ? void 0 : _a2.left) ?? getNodeLeft(child) : getNodeLeft(child);
|
|
787
|
-
const ct = positions ? ((
|
|
787
|
+
const ct = positions ? ((_b2 = positions.get(child.id)) == null ? void 0 : _b2.top) ?? getNodeTop(child) : getNodeTop(child);
|
|
788
788
|
minX = Math.min(minX, cl);
|
|
789
789
|
minY = Math.min(minY, ct);
|
|
790
790
|
maxX = Math.max(maxX, cl + sz.width);
|
|
@@ -822,14 +822,14 @@ function getNodeBoundsFromChildren(node) {
|
|
|
822
822
|
return getNodeBounds(node);
|
|
823
823
|
}
|
|
824
824
|
function absoluteBoundsRecur(node, pageChildren, options) {
|
|
825
|
-
var _a2,
|
|
825
|
+
var _a2, _b2;
|
|
826
826
|
const parent = pageChildren ? findParentGroup(pageChildren, node.id) : null;
|
|
827
827
|
const b = getNodeBounds(node, pageChildren);
|
|
828
828
|
if (!parent) return b;
|
|
829
829
|
const parentAbs = absoluteBoundsRecur(parent, pageChildren);
|
|
830
830
|
const isStackParent = isStackLayoutMode(parent.layoutMode);
|
|
831
831
|
const inParentLeft = isStackParent ? ((_a2 = resolveStackGroupEffectivePositions(parent, pageChildren).get(node.id)) == null ? void 0 : _a2.left) ?? b.left : b.left;
|
|
832
|
-
const inParentTop = isStackParent ? ((
|
|
832
|
+
const inParentTop = isStackParent ? ((_b2 = resolveStackGroupEffectivePositions(parent, pageChildren).get(node.id)) == null ? void 0 : _b2.top) ?? b.top : b.top;
|
|
833
833
|
return {
|
|
834
834
|
left: parentAbs.left + inParentLeft,
|
|
835
835
|
top: parentAbs.top + inParentTop,
|
|
@@ -1009,7 +1009,7 @@ const defaultProjectSettings = {
|
|
|
1009
1009
|
snapToGrid: false,
|
|
1010
1010
|
gridSize: 20,
|
|
1011
1011
|
snapToGuides: true,
|
|
1012
|
-
snapThreshold:
|
|
1012
|
+
snapThreshold: 8
|
|
1013
1013
|
};
|
|
1014
1014
|
const defaultPageSettings = {
|
|
1015
1015
|
backgroundColor: "#ffffff"
|
|
@@ -3547,7 +3547,7 @@ const clearFontCacheAndRerender = (canvas, options = {}) => {
|
|
|
3547
3547
|
}
|
|
3548
3548
|
};
|
|
3549
3549
|
const collectUnderlineMetrics = (obj) => {
|
|
3550
|
-
var _a2,
|
|
3550
|
+
var _a2, _b2;
|
|
3551
3551
|
if (obj instanceof fabric.Textbox) {
|
|
3552
3552
|
if (!obj.underline) return [];
|
|
3553
3553
|
const lineWidths = obj.__lineWidths;
|
|
@@ -3562,7 +3562,7 @@ const clearFontCacheAndRerender = (canvas, options = {}) => {
|
|
|
3562
3562
|
height: obj.height ?? null,
|
|
3563
3563
|
scaleX: obj.scaleX,
|
|
3564
3564
|
scaleY: obj.scaleY,
|
|
3565
|
-
lineCount: ((
|
|
3565
|
+
lineCount: ((_b2 = obj.textLines) == null ? void 0 : _b2.length) ?? 0,
|
|
3566
3566
|
maxLineWidth: lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : null
|
|
3567
3567
|
}];
|
|
3568
3568
|
}
|
|
@@ -3592,13 +3592,13 @@ const clearFontCacheAndRerender = (canvas, options = {}) => {
|
|
|
3592
3592
|
canvas.requestRenderAll();
|
|
3593
3593
|
};
|
|
3594
3594
|
const ensureFontLoaded = async (fontFamily) => {
|
|
3595
|
-
var _a2,
|
|
3595
|
+
var _a2, _b2, _c;
|
|
3596
3596
|
if (!fontFamily) return;
|
|
3597
3597
|
if (LOCAL_FONTS.has(fontFamily)) {
|
|
3598
3598
|
try {
|
|
3599
3599
|
const isLoaded = (_a2 = document.fonts) == null ? void 0 : _a2.check(`16px "${fontFamily}"`);
|
|
3600
3600
|
if (isLoaded) return;
|
|
3601
|
-
await ((
|
|
3601
|
+
await ((_b2 = document.fonts) == null ? void 0 : _b2.load(`16px "${fontFamily}"`));
|
|
3602
3602
|
await ((_c = document.fonts) == null ? void 0 : _c.load(`bold 16px "${fontFamily}"`));
|
|
3603
3603
|
} catch (e) {
|
|
3604
3604
|
console.warn(`Failed to ensure local font loaded: ${fontFamily}`, e);
|
|
@@ -4093,7 +4093,7 @@ function createImageClipPath(element, imgWidth, imgHeight) {
|
|
|
4093
4093
|
}
|
|
4094
4094
|
}
|
|
4095
4095
|
async function loadImageAsync(element, placeholder, fc, fabricRef, syncLockedRef, isTransforming) {
|
|
4096
|
-
var _a2,
|
|
4096
|
+
var _a2, _b2, _c, _d;
|
|
4097
4097
|
const imageUrl = element.src || element.imageUrl;
|
|
4098
4098
|
if (!imageUrl) return;
|
|
4099
4099
|
const nextSvgColorMap = element.svgColorMap ? JSON.stringify(element.svgColorMap) : "";
|
|
@@ -4257,7 +4257,7 @@ async function loadImageAsync(element, placeholder, fc, fabricRef, syncLockedRef
|
|
|
4257
4257
|
if (existingCropGroup) {
|
|
4258
4258
|
const existingImg = (_a2 = existingCropGroup.__cropData) == null ? void 0 : _a2._img;
|
|
4259
4259
|
if (existingImg) {
|
|
4260
|
-
panX = ((
|
|
4260
|
+
panX = ((_b2 = existingImg._ct) == null ? void 0 : _b2.panX) ?? existingImg.__panX ?? 0.5;
|
|
4261
4261
|
panY = ((_c = existingImg._ct) == null ? void 0 : _c.panY) ?? existingImg.__panY ?? 0.5;
|
|
4262
4262
|
zoom = ((_d = existingImg._ct) == null ? void 0 : _d.zoom) ?? 1;
|
|
4263
4263
|
}
|
|
@@ -4465,11 +4465,11 @@ function isLuminanceMaskClipPath(clipPath) {
|
|
|
4465
4465
|
return Boolean(clipPath && clipPath.__svgMaskType === "luminance");
|
|
4466
4466
|
}
|
|
4467
4467
|
function syncSvgMaskClipPath(cropGroup) {
|
|
4468
|
-
var _a2,
|
|
4468
|
+
var _a2, _b2;
|
|
4469
4469
|
const clipPath = cropGroup.clipPath;
|
|
4470
4470
|
if (!isCropGroup(cropGroup)) return;
|
|
4471
4471
|
const frameW = ((_a2 = cropGroup._ct) == null ? void 0 : _a2.frameW) ?? cropGroup.width ?? 0;
|
|
4472
|
-
const frameH = ((
|
|
4472
|
+
const frameH = ((_b2 = cropGroup._ct) == null ? void 0 : _b2.frameH) ?? cropGroup.height ?? 0;
|
|
4473
4473
|
if (frameW <= 0 || frameH <= 0) return;
|
|
4474
4474
|
if (isSvgMaskClipPath(clipPath)) {
|
|
4475
4475
|
fitMaskGroupToFrame(clipPath, frameW, frameH);
|
|
@@ -4493,12 +4493,12 @@ async function detectMaskType(svgUrl) {
|
|
|
4493
4493
|
}
|
|
4494
4494
|
}
|
|
4495
4495
|
async function applySvgMaskToCropGroup(cropGroup, svgUrl) {
|
|
4496
|
-
var _a2,
|
|
4496
|
+
var _a2, _b2, _c;
|
|
4497
4497
|
if (!isCropGroup(cropGroup)) {
|
|
4498
4498
|
throw new Error("Selected object is not a crop group / image");
|
|
4499
4499
|
}
|
|
4500
4500
|
const frameW = ((_a2 = cropGroup._ct) == null ? void 0 : _a2.frameW) ?? cropGroup.width ?? 0;
|
|
4501
|
-
const frameH = ((
|
|
4501
|
+
const frameH = ((_b2 = cropGroup._ct) == null ? void 0 : _b2.frameH) ?? cropGroup.height ?? 0;
|
|
4502
4502
|
if (frameW <= 0 || frameH <= 0) {
|
|
4503
4503
|
throw new Error("Crop group has no frame dimensions");
|
|
4504
4504
|
}
|
|
@@ -4584,12 +4584,12 @@ async function buildLuminanceAlphaCanvas(svgUrl, frameW, frameH) {
|
|
|
4584
4584
|
return canvas;
|
|
4585
4585
|
}
|
|
4586
4586
|
async function applyLuminanceMaskToCropGroup(cropGroup, svgUrl) {
|
|
4587
|
-
var _a2,
|
|
4587
|
+
var _a2, _b2, _c;
|
|
4588
4588
|
if (!isCropGroup(cropGroup)) {
|
|
4589
4589
|
throw new Error("Selected object is not a crop group / image");
|
|
4590
4590
|
}
|
|
4591
4591
|
const frameW = ((_a2 = cropGroup._ct) == null ? void 0 : _a2.frameW) ?? cropGroup.width ?? 0;
|
|
4592
|
-
const frameH = ((
|
|
4592
|
+
const frameH = ((_b2 = cropGroup._ct) == null ? void 0 : _b2.frameH) ?? cropGroup.height ?? 0;
|
|
4593
4593
|
if (frameW <= 0 || frameH <= 0) {
|
|
4594
4594
|
throw new Error("Crop group has no frame dimensions");
|
|
4595
4595
|
}
|
|
@@ -4638,10 +4638,10 @@ function getAppliedSvgMaskType(obj) {
|
|
|
4638
4638
|
return t === "luminance" || t === "shape" ? t : null;
|
|
4639
4639
|
}
|
|
4640
4640
|
function clearSvgMaskFromCropGroup(cropGroup) {
|
|
4641
|
-
var _a2,
|
|
4641
|
+
var _a2, _b2, _c;
|
|
4642
4642
|
if (!isCropGroup(cropGroup)) return;
|
|
4643
4643
|
const frameW = ((_a2 = cropGroup._ct) == null ? void 0 : _a2.frameW) ?? cropGroup.width ?? 0;
|
|
4644
|
-
const frameH = ((
|
|
4644
|
+
const frameH = ((_b2 = cropGroup._ct) == null ? void 0 : _b2.frameH) ?? cropGroup.height ?? 0;
|
|
4645
4645
|
const rect = new fabric.Rect({
|
|
4646
4646
|
width: frameW,
|
|
4647
4647
|
height: frameH,
|
|
@@ -4675,17 +4675,16 @@ const svgMaskApply = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.define
|
|
|
4675
4675
|
isSvgMaskClipPath,
|
|
4676
4676
|
syncSvgMaskClipPath
|
|
4677
4677
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
4678
|
+
const SELECTION_BORDER_SCALE$1 = 2;
|
|
4678
4679
|
function clamp$1(v, min, max) {
|
|
4679
4680
|
return Math.max(min, Math.min(max, v));
|
|
4680
4681
|
}
|
|
4681
4682
|
function applyControlSizeForZoom(canvas, obj) {
|
|
4682
4683
|
if (!canvas || !obj) return;
|
|
4683
|
-
const z = canvas.getZoom() || 1;
|
|
4684
|
-
const size = Math.max(6, Math.round(8 * z));
|
|
4685
4684
|
obj.set({
|
|
4686
|
-
cornerSize:
|
|
4687
|
-
|
|
4688
|
-
borderScaleFactor:
|
|
4685
|
+
cornerSize: 10,
|
|
4686
|
+
touchCornerSize: 20,
|
|
4687
|
+
borderScaleFactor: SELECTION_BORDER_SCALE$1
|
|
4689
4688
|
});
|
|
4690
4689
|
obj.setCoords();
|
|
4691
4690
|
}
|
|
@@ -5062,6 +5061,21 @@ function resizeFrameFromSide(g, side, localDx, localDy) {
|
|
|
5062
5061
|
function installCanvaMaskControls(g) {
|
|
5063
5062
|
const ct = g.__cropData;
|
|
5064
5063
|
if (ct) ct.fit = ct.fit ?? "cover";
|
|
5064
|
+
const controlStyle = {
|
|
5065
|
+
cornerSize: 10,
|
|
5066
|
+
touchCornerSize: 20,
|
|
5067
|
+
borderScaleFactor: SELECTION_BORDER_SCALE$1,
|
|
5068
|
+
transparentCorners: false,
|
|
5069
|
+
cornerStyle: "circle",
|
|
5070
|
+
cornerColor: "hsl(217, 91%, 60%)",
|
|
5071
|
+
cornerStrokeColor: "#ffffff",
|
|
5072
|
+
borderColor: "hsl(217, 91%, 60%)"
|
|
5073
|
+
};
|
|
5074
|
+
g.set(controlStyle);
|
|
5075
|
+
const notifyResizeSnap = (target, corner) => {
|
|
5076
|
+
const handler = target.__resizeSnapHandler;
|
|
5077
|
+
if (typeof handler === "function") handler(target, corner);
|
|
5078
|
+
};
|
|
5065
5079
|
g.setControlsVisibility({
|
|
5066
5080
|
mt: true,
|
|
5067
5081
|
mb: true,
|
|
@@ -5091,6 +5105,7 @@ function installCanvaMaskControls(g) {
|
|
|
5091
5105
|
const { localDx, localDy } = getLocalDeltaStable(t, eventData);
|
|
5092
5106
|
t.__lockScaleDuringCrop = true;
|
|
5093
5107
|
resizeFrameFromSide(t, side, localDx, localDy);
|
|
5108
|
+
notifyResizeSnap(t, side);
|
|
5094
5109
|
(_a2 = t.canvas) == null ? void 0 : _a2.requestRenderAll();
|
|
5095
5110
|
return true;
|
|
5096
5111
|
}
|
|
@@ -5115,7 +5130,9 @@ function installCanvaMaskControls(g) {
|
|
|
5115
5130
|
if (canvas && canvas.__editLockRef) {
|
|
5116
5131
|
canvas.__editLockRef.current = true;
|
|
5117
5132
|
}
|
|
5118
|
-
|
|
5133
|
+
const resized = resizeFrameFromCornerUniform(eventData, transform);
|
|
5134
|
+
if (resized) notifyResizeSnap(t, key);
|
|
5135
|
+
return resized;
|
|
5119
5136
|
}
|
|
5120
5137
|
});
|
|
5121
5138
|
};
|
|
@@ -5124,6 +5141,8 @@ function installCanvaMaskControls(g) {
|
|
|
5124
5141
|
g.controls.bl = makeCornerControl("bl", -0.5, 0.5, "nesw-resize");
|
|
5125
5142
|
g.controls.br = makeCornerControl("br", 0.5, 0.5, "nwse-resize");
|
|
5126
5143
|
g.__hasCustomControls = true;
|
|
5144
|
+
g.set(controlStyle);
|
|
5145
|
+
g.setCoords();
|
|
5127
5146
|
}
|
|
5128
5147
|
async function createMaskedImageElement({
|
|
5129
5148
|
url,
|
|
@@ -5694,12 +5713,15 @@ function exitCropMode(g, commit = true) {
|
|
|
5694
5713
|
g.hasControls = true;
|
|
5695
5714
|
g.borderDashArray = void 0;
|
|
5696
5715
|
installCanvaMaskControls(g);
|
|
5697
|
-
g.borderColor = "
|
|
5716
|
+
g.borderColor = "hsl(217, 91%, 60%)";
|
|
5698
5717
|
g.borderDashArray = void 0;
|
|
5699
|
-
g.cornerColor = "
|
|
5700
|
-
g.cornerStrokeColor = "#
|
|
5701
|
-
g.cornerStyle = "
|
|
5718
|
+
g.cornerColor = "hsl(217, 91%, 60%)";
|
|
5719
|
+
g.cornerStrokeColor = "#ffffff";
|
|
5720
|
+
g.cornerStyle = "circle";
|
|
5702
5721
|
g.transparentCorners = false;
|
|
5722
|
+
g.cornerSize = 10;
|
|
5723
|
+
g.touchCornerSize = 20;
|
|
5724
|
+
g.borderScaleFactor = 2;
|
|
5703
5725
|
g[CROP_MODE_FLAG] = false;
|
|
5704
5726
|
g.__cropZoomLastPointer = void 0;
|
|
5705
5727
|
g.__lastPointerForCrop = void 0;
|
|
@@ -5708,6 +5730,16 @@ function exitCropMode(g, commit = true) {
|
|
|
5708
5730
|
}
|
|
5709
5731
|
canvas == null ? void 0 : canvas.requestRenderAll();
|
|
5710
5732
|
}
|
|
5733
|
+
function boundsToSnapPoints(bounds) {
|
|
5734
|
+
return {
|
|
5735
|
+
left: bounds.left,
|
|
5736
|
+
right: bounds.left + bounds.width,
|
|
5737
|
+
top: bounds.top,
|
|
5738
|
+
bottom: bounds.top + bounds.height,
|
|
5739
|
+
centerX: bounds.left + bounds.width / 2,
|
|
5740
|
+
centerY: bounds.top + bounds.height / 2
|
|
5741
|
+
};
|
|
5742
|
+
}
|
|
5711
5743
|
function getObjectSnapPoints(obj) {
|
|
5712
5744
|
try {
|
|
5713
5745
|
obj.setCoords();
|
|
@@ -5737,7 +5769,8 @@ function getObjectSnapPoints(obj) {
|
|
|
5737
5769
|
}
|
|
5738
5770
|
function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold) {
|
|
5739
5771
|
if (!snapToGuides) return { guides: [], snapDx: 0, snapDy: 0 };
|
|
5740
|
-
const threshold = snapThreshold ||
|
|
5772
|
+
const threshold = snapThreshold || 8;
|
|
5773
|
+
const centerThreshold = threshold * 1.75;
|
|
5741
5774
|
const newGuides = [];
|
|
5742
5775
|
const horizontalSnaps = [];
|
|
5743
5776
|
const verticalSnaps = [];
|
|
@@ -5757,12 +5790,24 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5757
5790
|
horizontalSnaps.push({ delta: targetPoint - objPoint, distance, guide });
|
|
5758
5791
|
}
|
|
5759
5792
|
};
|
|
5793
|
+
const addCanvasCenterVerticalSnap = (objPoint, targetPoint, guide) => {
|
|
5794
|
+
const distance = Math.abs(objPoint - targetPoint);
|
|
5795
|
+
if (distance < centerThreshold) {
|
|
5796
|
+
verticalSnaps.push({ delta: targetPoint - objPoint, distance: distance * 0.85, guide });
|
|
5797
|
+
}
|
|
5798
|
+
};
|
|
5799
|
+
const addCanvasCenterHorizontalSnap = (objPoint, targetPoint, guide) => {
|
|
5800
|
+
const distance = Math.abs(objPoint - targetPoint);
|
|
5801
|
+
if (distance < centerThreshold) {
|
|
5802
|
+
horizontalSnaps.push({ delta: targetPoint - objPoint, distance: distance * 0.85, guide });
|
|
5803
|
+
}
|
|
5804
|
+
};
|
|
5760
5805
|
addVerticalSnap(moving.left, 0, { type: "vertical", position: 0 });
|
|
5761
5806
|
addVerticalSnap(moving.right, canvasWidth, { type: "vertical", position: canvasWidth });
|
|
5762
5807
|
addHorizontalSnap(moving.top, 0, { type: "horizontal", position: 0 });
|
|
5763
5808
|
addHorizontalSnap(moving.bottom, canvasHeight, { type: "horizontal", position: canvasHeight });
|
|
5764
|
-
|
|
5765
|
-
|
|
5809
|
+
addCanvasCenterVerticalSnap(moving.centerX, canvasCenterX, { type: "vertical", position: canvasCenterX });
|
|
5810
|
+
addCanvasCenterHorizontalSnap(moving.centerY, canvasCenterY, { type: "horizontal", position: canvasCenterY });
|
|
5766
5811
|
const rawObjects = canvas.getObjects();
|
|
5767
5812
|
const allObjects = [];
|
|
5768
5813
|
for (const obj of rawObjects) {
|
|
@@ -5782,16 +5827,22 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5782
5827
|
}
|
|
5783
5828
|
for (const otherObj of allObjects) {
|
|
5784
5829
|
const other = getObjectSnapPoints(otherObj);
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5830
|
+
const tb = {
|
|
5831
|
+
left: other.left,
|
|
5832
|
+
top: other.top,
|
|
5833
|
+
width: other.right - other.left,
|
|
5834
|
+
height: other.bottom - other.top
|
|
5835
|
+
};
|
|
5836
|
+
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 });
|
|
5837
|
+
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 });
|
|
5838
|
+
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 });
|
|
5839
|
+
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 });
|
|
5840
|
+
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 });
|
|
5841
|
+
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 });
|
|
5842
|
+
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 });
|
|
5843
|
+
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 });
|
|
5844
|
+
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 });
|
|
5845
|
+
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 });
|
|
5795
5846
|
}
|
|
5796
5847
|
let snapDx = 0;
|
|
5797
5848
|
let snapDy = 0;
|
|
@@ -5799,19 +5850,129 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5799
5850
|
verticalSnaps.sort((a, b) => a.distance - b.distance);
|
|
5800
5851
|
const bestSnap = verticalSnaps[0];
|
|
5801
5852
|
snapDx = bestSnap.delta;
|
|
5802
|
-
newGuides.push({ ...bestSnap.guide,
|
|
5853
|
+
newGuides.push({ ...bestSnap.guide, kind: "alignment" });
|
|
5803
5854
|
}
|
|
5804
5855
|
if (horizontalSnaps.length > 0) {
|
|
5805
5856
|
horizontalSnaps.sort((a, b) => a.distance - b.distance);
|
|
5806
5857
|
const bestSnap = horizontalSnaps[0];
|
|
5807
5858
|
snapDy = bestSnap.delta;
|
|
5808
|
-
newGuides.push({ ...bestSnap.guide,
|
|
5859
|
+
newGuides.push({ ...bestSnap.guide, kind: "alignment" });
|
|
5860
|
+
}
|
|
5861
|
+
const projectedLeft = moving.left + snapDx;
|
|
5862
|
+
const projectedRight = moving.right + snapDx;
|
|
5863
|
+
moving.centerX + snapDx;
|
|
5864
|
+
const projectedTop = moving.top + snapDy;
|
|
5865
|
+
const projectedBottom = moving.bottom + snapDy;
|
|
5866
|
+
moving.centerY + snapDy;
|
|
5867
|
+
if (snapDx === 0) {
|
|
5868
|
+
let bestPair = null;
|
|
5869
|
+
for (const a of allObjects) {
|
|
5870
|
+
const A = getObjectSnapPoints(a);
|
|
5871
|
+
if (A.right > projectedLeft) continue;
|
|
5872
|
+
if (A.bottom < projectedTop || A.top > projectedBottom) continue;
|
|
5873
|
+
for (const b of allObjects) {
|
|
5874
|
+
if (b === a) continue;
|
|
5875
|
+
const B = getObjectSnapPoints(b);
|
|
5876
|
+
if (B.left < projectedRight) continue;
|
|
5877
|
+
if (B.bottom < projectedTop || B.top > projectedBottom) continue;
|
|
5878
|
+
const gapL = projectedLeft - A.right;
|
|
5879
|
+
const gapR = B.left - projectedRight;
|
|
5880
|
+
const diff = gapR - gapL;
|
|
5881
|
+
const absDiff = Math.abs(diff);
|
|
5882
|
+
if (absDiff < threshold && (!bestPair || absDiff < bestPair.absDiff)) {
|
|
5883
|
+
bestPair = { A, B, delta: diff / 2, absDiff };
|
|
5884
|
+
}
|
|
5885
|
+
}
|
|
5886
|
+
}
|
|
5887
|
+
if (bestPair) {
|
|
5888
|
+
snapDx = bestPair.delta;
|
|
5889
|
+
const newLeft = moving.left + snapDx;
|
|
5890
|
+
const newRight = moving.right + snapDx;
|
|
5891
|
+
const equalGap = Math.round(newLeft - bestPair.A.right);
|
|
5892
|
+
const bracketY = (Math.max(bestPair.A.top, projectedTop, bestPair.B.top) + Math.min(bestPair.A.bottom, projectedBottom, bestPair.B.bottom)) / 2;
|
|
5893
|
+
if (equalGap > 0) {
|
|
5894
|
+
const aTb = { left: bestPair.A.left, top: bestPair.A.top, width: bestPair.A.right - bestPair.A.left, height: bestPair.A.bottom - bestPair.A.top };
|
|
5895
|
+
const bTb = { left: bestPair.B.left, top: bestPair.B.top, width: bestPair.B.right - bestPair.B.left, height: bestPair.B.bottom - bestPair.B.top };
|
|
5896
|
+
newGuides.push({
|
|
5897
|
+
type: "horizontal",
|
|
5898
|
+
position: bracketY,
|
|
5899
|
+
kind: "gap",
|
|
5900
|
+
gap: equalGap,
|
|
5901
|
+
start: bestPair.A.right,
|
|
5902
|
+
end: newLeft,
|
|
5903
|
+
bracketAt: bracketY,
|
|
5904
|
+
targetBoundsList: [aTb, bTb]
|
|
5905
|
+
});
|
|
5906
|
+
newGuides.push({
|
|
5907
|
+
type: "horizontal",
|
|
5908
|
+
position: bracketY,
|
|
5909
|
+
kind: "gap",
|
|
5910
|
+
gap: equalGap,
|
|
5911
|
+
start: newRight,
|
|
5912
|
+
end: bestPair.B.left,
|
|
5913
|
+
bracketAt: bracketY,
|
|
5914
|
+
targetBoundsList: [aTb, bTb]
|
|
5915
|
+
});
|
|
5916
|
+
}
|
|
5917
|
+
}
|
|
5918
|
+
}
|
|
5919
|
+
if (snapDy === 0) {
|
|
5920
|
+
let bestPair = null;
|
|
5921
|
+
for (const a of allObjects) {
|
|
5922
|
+
const A = getObjectSnapPoints(a);
|
|
5923
|
+
if (A.bottom > projectedTop) continue;
|
|
5924
|
+
if (A.right < projectedLeft || A.left > projectedRight) continue;
|
|
5925
|
+
for (const b of allObjects) {
|
|
5926
|
+
if (b === a) continue;
|
|
5927
|
+
const B = getObjectSnapPoints(b);
|
|
5928
|
+
if (B.top < projectedBottom) continue;
|
|
5929
|
+
if (B.right < projectedLeft || B.left > projectedRight) continue;
|
|
5930
|
+
const gapT = projectedTop - A.bottom;
|
|
5931
|
+
const gapB = B.top - projectedBottom;
|
|
5932
|
+
const diff = gapB - gapT;
|
|
5933
|
+
const absDiff = Math.abs(diff);
|
|
5934
|
+
if (absDiff < threshold && (!bestPair || absDiff < bestPair.absDiff)) {
|
|
5935
|
+
bestPair = { A, B, delta: diff / 2, absDiff };
|
|
5936
|
+
}
|
|
5937
|
+
}
|
|
5938
|
+
}
|
|
5939
|
+
if (bestPair) {
|
|
5940
|
+
snapDy = bestPair.delta;
|
|
5941
|
+
const newTop = moving.top + snapDy;
|
|
5942
|
+
const newBottom = moving.bottom + snapDy;
|
|
5943
|
+
const equalGap = Math.round(newTop - bestPair.A.bottom);
|
|
5944
|
+
const bracketX = (Math.max(bestPair.A.left, projectedLeft, bestPair.B.left) + Math.min(bestPair.A.right, projectedRight, bestPair.B.right)) / 2;
|
|
5945
|
+
if (equalGap > 0) {
|
|
5946
|
+
const aTb = { left: bestPair.A.left, top: bestPair.A.top, width: bestPair.A.right - bestPair.A.left, height: bestPair.A.bottom - bestPair.A.top };
|
|
5947
|
+
const bTb = { left: bestPair.B.left, top: bestPair.B.top, width: bestPair.B.right - bestPair.B.left, height: bestPair.B.bottom - bestPair.B.top };
|
|
5948
|
+
newGuides.push({
|
|
5949
|
+
type: "vertical",
|
|
5950
|
+
position: bracketX,
|
|
5951
|
+
kind: "gap",
|
|
5952
|
+
gap: equalGap,
|
|
5953
|
+
start: bestPair.A.bottom,
|
|
5954
|
+
end: newTop,
|
|
5955
|
+
bracketAt: bracketX,
|
|
5956
|
+
targetBoundsList: [aTb, bTb]
|
|
5957
|
+
});
|
|
5958
|
+
newGuides.push({
|
|
5959
|
+
type: "vertical",
|
|
5960
|
+
position: bracketX,
|
|
5961
|
+
kind: "gap",
|
|
5962
|
+
gap: equalGap,
|
|
5963
|
+
start: newBottom,
|
|
5964
|
+
end: bestPair.B.top,
|
|
5965
|
+
bracketAt: bracketX,
|
|
5966
|
+
targetBoundsList: [aTb, bTb]
|
|
5967
|
+
});
|
|
5968
|
+
}
|
|
5969
|
+
}
|
|
5809
5970
|
}
|
|
5810
5971
|
return { guides: newGuides, snapDx, snapDy };
|
|
5811
5972
|
}
|
|
5812
|
-
function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold) {
|
|
5973
|
+
function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold, additionalBounds = []) {
|
|
5813
5974
|
if (!snapToGuides) return [];
|
|
5814
|
-
const threshold = snapThreshold
|
|
5975
|
+
const threshold = snapThreshold;
|
|
5815
5976
|
const newGuides = [];
|
|
5816
5977
|
const scaling = getObjectSnapPoints(scalingObj);
|
|
5817
5978
|
const scalingId = getObjectId(scalingObj);
|
|
@@ -5824,7 +5985,7 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5824
5985
|
const checkVerticalSnap = (edgePosition, targetPosition, guide) => {
|
|
5825
5986
|
const dist = Math.abs(edgePosition - targetPosition);
|
|
5826
5987
|
if (dist < threshold) {
|
|
5827
|
-
newGuides.push({ ...guide,
|
|
5988
|
+
newGuides.push({ ...guide, kind: "alignment" });
|
|
5828
5989
|
return true;
|
|
5829
5990
|
}
|
|
5830
5991
|
return false;
|
|
@@ -5832,7 +5993,7 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5832
5993
|
const checkHorizontalSnap = (edgePosition, targetPosition, guide) => {
|
|
5833
5994
|
const dist = Math.abs(edgePosition - targetPosition);
|
|
5834
5995
|
if (dist < threshold) {
|
|
5835
|
-
newGuides.push({ ...guide,
|
|
5996
|
+
newGuides.push({ ...guide, kind: "alignment" });
|
|
5836
5997
|
return true;
|
|
5837
5998
|
}
|
|
5838
5999
|
return false;
|
|
@@ -5854,12 +6015,39 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5854
6015
|
checkHorizontalSnap(scaling.bottom, canvasCenterY, { type: "horizontal", position: canvasCenterY });
|
|
5855
6016
|
}
|
|
5856
6017
|
const rawObjects = canvas.getObjects();
|
|
6018
|
+
const objectBounds = [];
|
|
5857
6019
|
for (const obj of rawObjects) {
|
|
5858
6020
|
if (obj === scalingObj) continue;
|
|
5859
6021
|
const objId = getObjectId(obj);
|
|
5860
6022
|
if (objId === "__background__") continue;
|
|
5861
6023
|
if (objId && objId === scalingId) continue;
|
|
5862
|
-
|
|
6024
|
+
if (scalingObj instanceof fabric.ActiveSelection && scalingObj.contains(obj)) continue;
|
|
6025
|
+
if (scalingObj instanceof fabric.Group && typeof scalingObj.getObjects === "function") {
|
|
6026
|
+
const inner = scalingObj.getObjects();
|
|
6027
|
+
if (inner.includes(obj)) continue;
|
|
6028
|
+
}
|
|
6029
|
+
objectBounds.push(getObjectSnapPoints(obj));
|
|
6030
|
+
}
|
|
6031
|
+
for (const bounds of additionalBounds) {
|
|
6032
|
+
objectBounds.push(boundsToSnapPoints(bounds));
|
|
6033
|
+
}
|
|
6034
|
+
let bestWidthMatch = null;
|
|
6035
|
+
let bestWidthDiff = threshold + 1;
|
|
6036
|
+
let bestHeightMatch = null;
|
|
6037
|
+
let bestHeightDiff = threshold + 1;
|
|
6038
|
+
for (const other of objectBounds) {
|
|
6039
|
+
const otherWidth = other.right - other.left;
|
|
6040
|
+
const otherHeight = other.bottom - other.top;
|
|
6041
|
+
const widthDiff = Math.abs(scaling.right - scaling.left - otherWidth);
|
|
6042
|
+
const heightDiff = Math.abs(scaling.bottom - scaling.top - otherHeight);
|
|
6043
|
+
if (resizingLeft !== resizingRight && widthDiff < bestWidthDiff) {
|
|
6044
|
+
bestWidthDiff = widthDiff;
|
|
6045
|
+
bestWidthMatch = other;
|
|
6046
|
+
}
|
|
6047
|
+
if (resizingTop !== resizingBottom && heightDiff < bestHeightDiff) {
|
|
6048
|
+
bestHeightDiff = heightDiff;
|
|
6049
|
+
bestHeightMatch = other;
|
|
6050
|
+
}
|
|
5863
6051
|
if (resizingLeft) {
|
|
5864
6052
|
checkVerticalSnap(scaling.left, other.left, {
|
|
5865
6053
|
type: "vertical",
|
|
@@ -5941,6 +6129,18 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5941
6129
|
});
|
|
5942
6130
|
}
|
|
5943
6131
|
}
|
|
6132
|
+
if (bestWidthMatch && bestWidthDiff < threshold) {
|
|
6133
|
+
newGuides.push(
|
|
6134
|
+
{ type: "horizontal", position: scaling.top, start: scaling.left, end: scaling.right, kind: "alignment" },
|
|
6135
|
+
{ type: "horizontal", position: bestWidthMatch.top, start: bestWidthMatch.left, end: bestWidthMatch.right, kind: "alignment" }
|
|
6136
|
+
);
|
|
6137
|
+
}
|
|
6138
|
+
if (bestHeightMatch && bestHeightDiff < threshold) {
|
|
6139
|
+
newGuides.push(
|
|
6140
|
+
{ type: "vertical", position: scaling.left, start: scaling.top, end: scaling.bottom, kind: "alignment" },
|
|
6141
|
+
{ type: "vertical", position: bestHeightMatch.left, start: bestHeightMatch.top, end: bestHeightMatch.bottom, kind: "alignment" }
|
|
6142
|
+
);
|
|
6143
|
+
}
|
|
5944
6144
|
const seen = /* @__PURE__ */ new Set();
|
|
5945
6145
|
return newGuides.filter((guide) => {
|
|
5946
6146
|
const key = `${guide.type}-${guide.position.toFixed(1)}`;
|
|
@@ -5949,6 +6149,349 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5949
6149
|
return true;
|
|
5950
6150
|
});
|
|
5951
6151
|
}
|
|
6152
|
+
const MIN_SNAP_BOX = 20;
|
|
6153
|
+
const SNAP_HYSTERESIS_PX = 6;
|
|
6154
|
+
function applyScaleSnapToBox(box, corner, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold, excludeObjectId, options) {
|
|
6155
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h;
|
|
6156
|
+
const hysteresis = (options == null ? void 0 : options.hysteresis) ?? SNAP_HYSTERESIS_PX;
|
|
6157
|
+
const activeSnapRef = options == null ? void 0 : options.activeSnapRef;
|
|
6158
|
+
const roundSnappedOnly = (options == null ? void 0 : options.roundSnappedOnly) ?? false;
|
|
6159
|
+
if (!snapToGuides || !canvas) {
|
|
6160
|
+
if (roundSnappedOnly) return { ...box };
|
|
6161
|
+
return {
|
|
6162
|
+
left: Math.round(box.left),
|
|
6163
|
+
top: Math.round(box.top),
|
|
6164
|
+
width: Math.round(box.width),
|
|
6165
|
+
height: Math.round(box.height)
|
|
6166
|
+
};
|
|
6167
|
+
}
|
|
6168
|
+
const threshold = snapThreshold || 5;
|
|
6169
|
+
const releaseDist = threshold + hysteresis;
|
|
6170
|
+
const matchDimensions = (options == null ? void 0 : options.matchDimensions) ?? true;
|
|
6171
|
+
const excludedIds = new Set((options == null ? void 0 : options.excludeObjectIds) ?? []);
|
|
6172
|
+
if (excludeObjectId) excludedIds.add(excludeObjectId);
|
|
6173
|
+
const right = box.left + box.width;
|
|
6174
|
+
const bottom = box.top + box.height;
|
|
6175
|
+
const canvasCenterX = canvasWidth / 2;
|
|
6176
|
+
const canvasCenterY = canvasHeight / 2;
|
|
6177
|
+
const resizingLeft = corner.includes("l");
|
|
6178
|
+
const resizingRight = corner.includes("r");
|
|
6179
|
+
const resizingTop = corner.includes("t");
|
|
6180
|
+
const resizingBottom = corner.includes("b");
|
|
6181
|
+
const verticalTargets = [0, canvasWidth, canvasCenterX];
|
|
6182
|
+
const horizontalTargets = [0, canvasHeight, canvasCenterY];
|
|
6183
|
+
const widthTargets = [];
|
|
6184
|
+
const heightTargets = [];
|
|
6185
|
+
if ((_a2 = options == null ? void 0 : options.verticalTargetsExtra) == null ? void 0 : _a2.length) verticalTargets.push(...options.verticalTargetsExtra);
|
|
6186
|
+
if ((_b2 = options == null ? void 0 : options.horizontalTargetsExtra) == null ? void 0 : _b2.length) horizontalTargets.push(...options.horizontalTargetsExtra);
|
|
6187
|
+
const rawObjects = canvas.getObjects();
|
|
6188
|
+
for (const obj of rawObjects) {
|
|
6189
|
+
const objId = getObjectId(obj);
|
|
6190
|
+
if (objId === "__background__") continue;
|
|
6191
|
+
if (objId && excludedIds.has(objId)) continue;
|
|
6192
|
+
const pts = getObjectSnapPoints(obj);
|
|
6193
|
+
verticalTargets.push(pts.left, pts.right, pts.centerX);
|
|
6194
|
+
horizontalTargets.push(pts.top, pts.bottom, pts.centerY);
|
|
6195
|
+
widthTargets.push(Math.max(1, pts.right - pts.left));
|
|
6196
|
+
heightTargets.push(Math.max(1, pts.bottom - pts.top));
|
|
6197
|
+
}
|
|
6198
|
+
for (const bounds of (options == null ? void 0 : options.additionalBounds) ?? []) {
|
|
6199
|
+
const pts = boundsToSnapPoints(bounds);
|
|
6200
|
+
verticalTargets.push(pts.left, pts.right, pts.centerX);
|
|
6201
|
+
horizontalTargets.push(pts.top, pts.bottom, pts.centerY);
|
|
6202
|
+
widthTargets.push(Math.max(1, bounds.width));
|
|
6203
|
+
heightTargets.push(Math.max(1, bounds.height));
|
|
6204
|
+
}
|
|
6205
|
+
const matchAsEdgeEnabled = (options == null ? void 0 : options.matchDimensions) ?? true;
|
|
6206
|
+
if (matchAsEdgeEnabled) {
|
|
6207
|
+
if (resizingLeft && !resizingRight) {
|
|
6208
|
+
for (const w of widthTargets) verticalTargets.push(right - w);
|
|
6209
|
+
} else if (resizingRight && !resizingLeft) {
|
|
6210
|
+
for (const w of widthTargets) verticalTargets.push(box.left + w);
|
|
6211
|
+
}
|
|
6212
|
+
if (resizingTop && !resizingBottom) {
|
|
6213
|
+
for (const h of heightTargets) horizontalTargets.push(bottom - h);
|
|
6214
|
+
} else if (resizingBottom && !resizingTop) {
|
|
6215
|
+
for (const h of heightTargets) horizontalTargets.push(box.top + h);
|
|
6216
|
+
}
|
|
6217
|
+
}
|
|
6218
|
+
const findBestSnap = (edgePos, targets) => {
|
|
6219
|
+
let best = edgePos;
|
|
6220
|
+
let bestDist = threshold + 1;
|
|
6221
|
+
for (const t of targets) {
|
|
6222
|
+
const d = Math.abs(edgePos - t);
|
|
6223
|
+
if (d < bestDist) {
|
|
6224
|
+
bestDist = d;
|
|
6225
|
+
best = t;
|
|
6226
|
+
}
|
|
6227
|
+
}
|
|
6228
|
+
return { value: best, dist: bestDist };
|
|
6229
|
+
};
|
|
6230
|
+
const findBestDimensionSnap = (size, targets) => {
|
|
6231
|
+
let best = size;
|
|
6232
|
+
let bestDist = threshold + 1;
|
|
6233
|
+
for (const t of targets) {
|
|
6234
|
+
const d = Math.abs(size - t);
|
|
6235
|
+
if (d < bestDist) {
|
|
6236
|
+
bestDist = d;
|
|
6237
|
+
best = t;
|
|
6238
|
+
}
|
|
6239
|
+
}
|
|
6240
|
+
return { value: best, dist: bestDist };
|
|
6241
|
+
};
|
|
6242
|
+
let left = box.left;
|
|
6243
|
+
let top = box.top;
|
|
6244
|
+
let width = box.width;
|
|
6245
|
+
let height = box.height;
|
|
6246
|
+
let snappedLeft = false;
|
|
6247
|
+
let snappedRight = false;
|
|
6248
|
+
let snappedTop = false;
|
|
6249
|
+
let snappedBottom = false;
|
|
6250
|
+
if (resizingLeft) {
|
|
6251
|
+
const stick = (_c = activeSnapRef == null ? void 0 : activeSnapRef.current) == null ? void 0 : _c.left;
|
|
6252
|
+
if (stick !== void 0) {
|
|
6253
|
+
const dist = Math.abs(box.left - stick);
|
|
6254
|
+
if (dist <= releaseDist) {
|
|
6255
|
+
left = stick;
|
|
6256
|
+
width = right - left;
|
|
6257
|
+
snappedLeft = true;
|
|
6258
|
+
} else if (dist > releaseDist) {
|
|
6259
|
+
if (activeSnapRef.current) delete activeSnapRef.current.left;
|
|
6260
|
+
const { value, dist: d } = findBestSnap(box.left, verticalTargets);
|
|
6261
|
+
if (d <= threshold) {
|
|
6262
|
+
if (!(activeSnapRef == null ? void 0 : activeSnapRef.current)) activeSnapRef.current = {};
|
|
6263
|
+
activeSnapRef.current.left = value;
|
|
6264
|
+
left = value;
|
|
6265
|
+
width = right - left;
|
|
6266
|
+
snappedLeft = true;
|
|
6267
|
+
} else {
|
|
6268
|
+
left = box.left;
|
|
6269
|
+
width = right - left;
|
|
6270
|
+
}
|
|
6271
|
+
} else {
|
|
6272
|
+
left = box.left;
|
|
6273
|
+
width = right - left;
|
|
6274
|
+
}
|
|
6275
|
+
} else {
|
|
6276
|
+
const { value, dist } = findBestSnap(box.left, verticalTargets);
|
|
6277
|
+
if (dist <= threshold) {
|
|
6278
|
+
if (activeSnapRef) {
|
|
6279
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6280
|
+
activeSnapRef.current.left = value;
|
|
6281
|
+
}
|
|
6282
|
+
left = value;
|
|
6283
|
+
width = right - left;
|
|
6284
|
+
snappedLeft = true;
|
|
6285
|
+
} else {
|
|
6286
|
+
left = box.left;
|
|
6287
|
+
width = right - left;
|
|
6288
|
+
}
|
|
6289
|
+
}
|
|
6290
|
+
}
|
|
6291
|
+
if (resizingRight) {
|
|
6292
|
+
const stick = (_d = activeSnapRef == null ? void 0 : activeSnapRef.current) == null ? void 0 : _d.right;
|
|
6293
|
+
if (stick !== void 0) {
|
|
6294
|
+
const dist = Math.abs(right - stick);
|
|
6295
|
+
if (dist <= releaseDist) {
|
|
6296
|
+
width = stick - left;
|
|
6297
|
+
snappedRight = true;
|
|
6298
|
+
} else if (dist > releaseDist) {
|
|
6299
|
+
if (activeSnapRef == null ? void 0 : activeSnapRef.current) delete activeSnapRef.current.right;
|
|
6300
|
+
const { value, dist: d } = findBestSnap(right, verticalTargets);
|
|
6301
|
+
if (d <= threshold) {
|
|
6302
|
+
if (!(activeSnapRef == null ? void 0 : activeSnapRef.current)) activeSnapRef.current = {};
|
|
6303
|
+
activeSnapRef.current.right = value;
|
|
6304
|
+
width = value - left;
|
|
6305
|
+
snappedRight = true;
|
|
6306
|
+
} else {
|
|
6307
|
+
width = box.width;
|
|
6308
|
+
}
|
|
6309
|
+
} else {
|
|
6310
|
+
width = box.width;
|
|
6311
|
+
}
|
|
6312
|
+
} else {
|
|
6313
|
+
const { value, dist } = findBestSnap(right, verticalTargets);
|
|
6314
|
+
if (dist <= threshold) {
|
|
6315
|
+
if (activeSnapRef) {
|
|
6316
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6317
|
+
activeSnapRef.current.right = value;
|
|
6318
|
+
}
|
|
6319
|
+
width = value - left;
|
|
6320
|
+
snappedRight = true;
|
|
6321
|
+
} else {
|
|
6322
|
+
width = box.width;
|
|
6323
|
+
}
|
|
6324
|
+
}
|
|
6325
|
+
}
|
|
6326
|
+
if (resizingTop) {
|
|
6327
|
+
const stick = (_e = activeSnapRef == null ? void 0 : activeSnapRef.current) == null ? void 0 : _e.top;
|
|
6328
|
+
if (stick !== void 0) {
|
|
6329
|
+
const dist = Math.abs(box.top - stick);
|
|
6330
|
+
if (dist <= releaseDist) {
|
|
6331
|
+
top = stick;
|
|
6332
|
+
height = bottom - top;
|
|
6333
|
+
snappedTop = true;
|
|
6334
|
+
} else if (dist > releaseDist) {
|
|
6335
|
+
if (activeSnapRef == null ? void 0 : activeSnapRef.current) delete activeSnapRef.current.top;
|
|
6336
|
+
const { value, dist: d } = findBestSnap(box.top, horizontalTargets);
|
|
6337
|
+
if (d <= threshold) {
|
|
6338
|
+
if (!(activeSnapRef == null ? void 0 : activeSnapRef.current)) activeSnapRef.current = {};
|
|
6339
|
+
activeSnapRef.current.top = value;
|
|
6340
|
+
top = value;
|
|
6341
|
+
height = bottom - top;
|
|
6342
|
+
snappedTop = true;
|
|
6343
|
+
} else {
|
|
6344
|
+
top = box.top;
|
|
6345
|
+
height = bottom - top;
|
|
6346
|
+
}
|
|
6347
|
+
} else {
|
|
6348
|
+
top = box.top;
|
|
6349
|
+
height = bottom - top;
|
|
6350
|
+
}
|
|
6351
|
+
} else {
|
|
6352
|
+
const { value, dist } = findBestSnap(box.top, horizontalTargets);
|
|
6353
|
+
if (dist <= threshold) {
|
|
6354
|
+
if (activeSnapRef) {
|
|
6355
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6356
|
+
activeSnapRef.current.top = value;
|
|
6357
|
+
}
|
|
6358
|
+
top = value;
|
|
6359
|
+
height = bottom - top;
|
|
6360
|
+
snappedTop = true;
|
|
6361
|
+
} else {
|
|
6362
|
+
top = box.top;
|
|
6363
|
+
height = bottom - top;
|
|
6364
|
+
}
|
|
6365
|
+
}
|
|
6366
|
+
}
|
|
6367
|
+
if (resizingBottom) {
|
|
6368
|
+
const stick = (_f = activeSnapRef == null ? void 0 : activeSnapRef.current) == null ? void 0 : _f.bottom;
|
|
6369
|
+
if (stick !== void 0) {
|
|
6370
|
+
const dist = Math.abs(bottom - stick);
|
|
6371
|
+
if (dist <= releaseDist) {
|
|
6372
|
+
height = stick - top;
|
|
6373
|
+
snappedBottom = true;
|
|
6374
|
+
} else if (dist > releaseDist) {
|
|
6375
|
+
if (activeSnapRef == null ? void 0 : activeSnapRef.current) delete activeSnapRef.current.bottom;
|
|
6376
|
+
const { value, dist: d } = findBestSnap(bottom, horizontalTargets);
|
|
6377
|
+
if (d <= threshold) {
|
|
6378
|
+
if (!(activeSnapRef == null ? void 0 : activeSnapRef.current)) activeSnapRef.current = {};
|
|
6379
|
+
activeSnapRef.current.bottom = value;
|
|
6380
|
+
height = value - top;
|
|
6381
|
+
snappedBottom = true;
|
|
6382
|
+
} else {
|
|
6383
|
+
height = box.height;
|
|
6384
|
+
}
|
|
6385
|
+
} else {
|
|
6386
|
+
height = box.height;
|
|
6387
|
+
}
|
|
6388
|
+
} else {
|
|
6389
|
+
const { value, dist } = findBestSnap(bottom, horizontalTargets);
|
|
6390
|
+
if (dist <= threshold) {
|
|
6391
|
+
if (activeSnapRef) {
|
|
6392
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6393
|
+
activeSnapRef.current.bottom = value;
|
|
6394
|
+
}
|
|
6395
|
+
height = value - top;
|
|
6396
|
+
snappedBottom = true;
|
|
6397
|
+
} else {
|
|
6398
|
+
height = box.height;
|
|
6399
|
+
}
|
|
6400
|
+
}
|
|
6401
|
+
}
|
|
6402
|
+
if (matchDimensions && resizingLeft !== resizingRight && !snappedLeft && !snappedRight && widthTargets.length > 0) {
|
|
6403
|
+
const stick = (_g = activeSnapRef == null ? void 0 : activeSnapRef.current) == null ? void 0 : _g.width;
|
|
6404
|
+
const applyWidth = (targetWidth) => {
|
|
6405
|
+
width = Math.max(MIN_SNAP_BOX, targetWidth);
|
|
6406
|
+
if (resizingLeft) {
|
|
6407
|
+
left = right - width;
|
|
6408
|
+
snappedLeft = true;
|
|
6409
|
+
} else {
|
|
6410
|
+
snappedRight = true;
|
|
6411
|
+
}
|
|
6412
|
+
};
|
|
6413
|
+
if (stick !== void 0) {
|
|
6414
|
+
const dist = Math.abs(box.width - stick);
|
|
6415
|
+
if (dist <= releaseDist) {
|
|
6416
|
+
applyWidth(stick);
|
|
6417
|
+
} else if (dist > releaseDist) {
|
|
6418
|
+
if (activeSnapRef == null ? void 0 : activeSnapRef.current) delete activeSnapRef.current.width;
|
|
6419
|
+
const { value, dist: d } = findBestDimensionSnap(box.width, widthTargets);
|
|
6420
|
+
if (d <= threshold) {
|
|
6421
|
+
if (activeSnapRef) {
|
|
6422
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6423
|
+
activeSnapRef.current.width = value;
|
|
6424
|
+
}
|
|
6425
|
+
applyWidth(value);
|
|
6426
|
+
}
|
|
6427
|
+
}
|
|
6428
|
+
} else {
|
|
6429
|
+
const { value, dist } = findBestDimensionSnap(box.width, widthTargets);
|
|
6430
|
+
if (dist <= threshold) {
|
|
6431
|
+
if (activeSnapRef) {
|
|
6432
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6433
|
+
activeSnapRef.current.width = value;
|
|
6434
|
+
}
|
|
6435
|
+
applyWidth(value);
|
|
6436
|
+
}
|
|
6437
|
+
}
|
|
6438
|
+
}
|
|
6439
|
+
if (matchDimensions && resizingTop !== resizingBottom && !snappedTop && !snappedBottom && heightTargets.length > 0) {
|
|
6440
|
+
const stick = (_h = activeSnapRef == null ? void 0 : activeSnapRef.current) == null ? void 0 : _h.height;
|
|
6441
|
+
const applyHeight = (targetHeight) => {
|
|
6442
|
+
height = Math.max(MIN_SNAP_BOX, targetHeight);
|
|
6443
|
+
if (resizingTop) {
|
|
6444
|
+
top = bottom - height;
|
|
6445
|
+
snappedTop = true;
|
|
6446
|
+
} else {
|
|
6447
|
+
snappedBottom = true;
|
|
6448
|
+
}
|
|
6449
|
+
};
|
|
6450
|
+
if (stick !== void 0) {
|
|
6451
|
+
const dist = Math.abs(box.height - stick);
|
|
6452
|
+
if (dist <= releaseDist) {
|
|
6453
|
+
applyHeight(stick);
|
|
6454
|
+
} else if (dist > releaseDist) {
|
|
6455
|
+
if (activeSnapRef == null ? void 0 : activeSnapRef.current) delete activeSnapRef.current.height;
|
|
6456
|
+
const { value, dist: d } = findBestDimensionSnap(box.height, heightTargets);
|
|
6457
|
+
if (d <= threshold) {
|
|
6458
|
+
if (activeSnapRef) {
|
|
6459
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6460
|
+
activeSnapRef.current.height = value;
|
|
6461
|
+
}
|
|
6462
|
+
applyHeight(value);
|
|
6463
|
+
}
|
|
6464
|
+
}
|
|
6465
|
+
} else {
|
|
6466
|
+
const { value, dist } = findBestDimensionSnap(box.height, heightTargets);
|
|
6467
|
+
if (dist <= threshold) {
|
|
6468
|
+
if (activeSnapRef) {
|
|
6469
|
+
if (!activeSnapRef.current) activeSnapRef.current = {};
|
|
6470
|
+
activeSnapRef.current.height = value;
|
|
6471
|
+
}
|
|
6472
|
+
applyHeight(value);
|
|
6473
|
+
}
|
|
6474
|
+
}
|
|
6475
|
+
}
|
|
6476
|
+
width = Math.max(MIN_SNAP_BOX, width);
|
|
6477
|
+
height = Math.max(MIN_SNAP_BOX, height);
|
|
6478
|
+
if (resizingLeft && !resizingRight) left = right - width;
|
|
6479
|
+
if (resizingTop && !resizingBottom) top = bottom - height;
|
|
6480
|
+
if (roundSnappedOnly) {
|
|
6481
|
+
return {
|
|
6482
|
+
left: snappedLeft ? Math.round(left) : left,
|
|
6483
|
+
top: snappedTop ? Math.round(top) : top,
|
|
6484
|
+
width: snappedLeft || snappedRight ? Math.round(width) : width,
|
|
6485
|
+
height: snappedTop || snappedBottom ? Math.round(height) : height
|
|
6486
|
+
};
|
|
6487
|
+
}
|
|
6488
|
+
return {
|
|
6489
|
+
left: Math.round(left),
|
|
6490
|
+
top: Math.round(top),
|
|
6491
|
+
width: Math.round(width),
|
|
6492
|
+
height: Math.round(height)
|
|
6493
|
+
};
|
|
6494
|
+
}
|
|
5952
6495
|
const clamp01$1 = (v) => Math.max(0, Math.min(1, Number.isFinite(v) ? v : 0));
|
|
5953
6496
|
function arcPath(w, sag, up) {
|
|
5954
6497
|
if (sag <= 0.5) return `M 0 0 L ${w} 0`;
|
|
@@ -6119,12 +6662,87 @@ if (Array.isArray(stateProps)) {
|
|
|
6119
6662
|
if (!stateProps.includes("minBoxHeight")) stateProps.push("minBoxHeight");
|
|
6120
6663
|
if (!stateProps.includes("verticalAlign")) stateProps.push("verticalAlign");
|
|
6121
6664
|
if (!stateProps.includes("textPath")) stateProps.push("textPath");
|
|
6665
|
+
if (!stateProps.includes("smartWrap")) stateProps.push("smartWrap");
|
|
6122
6666
|
}
|
|
6123
6667
|
const cacheProps = fabric.Textbox.prototype.cacheProperties;
|
|
6124
6668
|
if (Array.isArray(cacheProps)) {
|
|
6125
6669
|
if (!cacheProps.includes("minBoxHeight")) cacheProps.push("minBoxHeight");
|
|
6126
6670
|
if (!cacheProps.includes("verticalAlign")) cacheProps.push("verticalAlign");
|
|
6127
6671
|
if (!cacheProps.includes("textPath")) cacheProps.push("textPath");
|
|
6672
|
+
if (!cacheProps.includes("smartWrap")) cacheProps.push("smartWrap");
|
|
6673
|
+
}
|
|
6674
|
+
fabric.Textbox.prototype.smartWrap = true;
|
|
6675
|
+
if (TextboxProto._wrapLine && !TextboxProto.__pixldocsOrigWrapLine) {
|
|
6676
|
+
TextboxProto.__pixldocsOrigWrapLine = TextboxProto._wrapLine;
|
|
6677
|
+
TextboxProto._wrapLine = function(lineIndex, desiredWidth, ref, reservedSpace = 0) {
|
|
6678
|
+
var _a2;
|
|
6679
|
+
const orig = TextboxProto.__pixldocsOrigWrapLine;
|
|
6680
|
+
if (!this.smartWrap || this.splitByGrapheme) {
|
|
6681
|
+
return orig.call(this, lineIndex, desiredWidth, ref, reservedSpace);
|
|
6682
|
+
}
|
|
6683
|
+
try {
|
|
6684
|
+
const additionalSpace = TextboxProto._getWidthOfCharSpacing.call(this);
|
|
6685
|
+
const data = ((_a2 = ref == null ? void 0 : ref.wordsData) == null ? void 0 : _a2[lineIndex]) ?? [];
|
|
6686
|
+
const effective = Math.max(1, desiredWidth - reservedSpace);
|
|
6687
|
+
const infix = " ";
|
|
6688
|
+
const measureWord = TextboxProto._measureWord;
|
|
6689
|
+
const infixWidth = measureWord.call(this, [infix], lineIndex, 0);
|
|
6690
|
+
const graphemeLines = [];
|
|
6691
|
+
let line = [];
|
|
6692
|
+
let lineWidth = 0;
|
|
6693
|
+
let lineJustStarted = true;
|
|
6694
|
+
let largestWordWidth = 0;
|
|
6695
|
+
let offset = 0;
|
|
6696
|
+
const pushLine = () => {
|
|
6697
|
+
graphemeLines.push(line);
|
|
6698
|
+
line = [];
|
|
6699
|
+
lineWidth = 0;
|
|
6700
|
+
lineJustStarted = true;
|
|
6701
|
+
};
|
|
6702
|
+
for (let i = 0; i < data.length; i++) {
|
|
6703
|
+
const { word, width: wordWidth } = data[i];
|
|
6704
|
+
if (wordWidth <= effective) {
|
|
6705
|
+
if (wordWidth > largestWordWidth) largestWordWidth = wordWidth;
|
|
6706
|
+
const projected = lineJustStarted ? wordWidth : lineWidth + infixWidth + wordWidth - additionalSpace;
|
|
6707
|
+
if (!lineJustStarted && projected > effective) {
|
|
6708
|
+
pushLine();
|
|
6709
|
+
}
|
|
6710
|
+
if (!lineJustStarted) {
|
|
6711
|
+
line.push(infix);
|
|
6712
|
+
lineWidth += infixWidth;
|
|
6713
|
+
}
|
|
6714
|
+
line = line.concat(word);
|
|
6715
|
+
lineWidth += wordWidth;
|
|
6716
|
+
lineJustStarted = false;
|
|
6717
|
+
} else {
|
|
6718
|
+
if (!lineJustStarted) pushLine();
|
|
6719
|
+
for (const g of word) {
|
|
6720
|
+
const gw = measureWord.call(this, [g], lineIndex, offset);
|
|
6721
|
+
if (gw > largestWordWidth) largestWordWidth = gw;
|
|
6722
|
+
const projected = lineJustStarted ? gw : lineWidth + gw - additionalSpace;
|
|
6723
|
+
if (!lineJustStarted && projected > effective) {
|
|
6724
|
+
pushLine();
|
|
6725
|
+
}
|
|
6726
|
+
line.push(g);
|
|
6727
|
+
lineWidth += gw;
|
|
6728
|
+
lineJustStarted = false;
|
|
6729
|
+
offset++;
|
|
6730
|
+
}
|
|
6731
|
+
offset -= word.length;
|
|
6732
|
+
}
|
|
6733
|
+
offset += word.length + 1;
|
|
6734
|
+
}
|
|
6735
|
+
if (line.length) graphemeLines.push(line);
|
|
6736
|
+
const minNeeded = Math.max(0, Math.min(largestWordWidth, effective) - additionalSpace + reservedSpace);
|
|
6737
|
+
if (minNeeded > this.dynamicMinWidth) {
|
|
6738
|
+
this.dynamicMinWidth = minNeeded;
|
|
6739
|
+
}
|
|
6740
|
+
return graphemeLines;
|
|
6741
|
+
} catch (e) {
|
|
6742
|
+
console.warn("[smartWrap] fell back to default wrap:", e);
|
|
6743
|
+
return orig.call(this, lineIndex, desiredWidth, ref, reservedSpace);
|
|
6744
|
+
}
|
|
6745
|
+
};
|
|
6128
6746
|
}
|
|
6129
6747
|
const hasActiveTextPath = (obj) => {
|
|
6130
6748
|
const tp = obj.textPath;
|
|
@@ -6281,14 +6899,14 @@ function scaleLocalToScreen(target, p) {
|
|
|
6281
6899
|
return new fabric.Point(p.x * sx * zx, p.y * sy * zy);
|
|
6282
6900
|
}
|
|
6283
6901
|
function applyTextPathControls(textbox) {
|
|
6284
|
-
var _a2,
|
|
6902
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
6285
6903
|
const obj = textbox;
|
|
6286
6904
|
if (!hasActiveTextPath(obj)) {
|
|
6287
6905
|
obj.__pdTextPathHovered = false;
|
|
6288
6906
|
if (obj.__pdTextPathControls) {
|
|
6289
6907
|
try {
|
|
6290
6908
|
const cu2 = fabric.controlsUtils;
|
|
6291
|
-
const defaults = ((_a2 = cu2 == null ? void 0 : cu2.createTextboxDefaultControls) == null ? void 0 : _a2.call(cu2)) ?? ((
|
|
6909
|
+
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));
|
|
6292
6910
|
if (defaults) obj.controls = defaults;
|
|
6293
6911
|
} catch {
|
|
6294
6912
|
}
|
|
@@ -6552,7 +7170,7 @@ function applyTextPathControls(textbox) {
|
|
|
6552
7170
|
actionName: "tpPivot",
|
|
6553
7171
|
positionHandler: (_d2, finalMatrix, fabricObject) => scaleLocalToScreen(fabricObject, getPivotLocalCentered(fabricObject)).transform(finalMatrix),
|
|
6554
7172
|
actionHandler: (_e2, transform, x, y) => {
|
|
6555
|
-
var _a3,
|
|
7173
|
+
var _a3, _b3;
|
|
6556
7174
|
const target = transform.target;
|
|
6557
7175
|
const state = transform.__pdCirclePivotDrag || (transform.__pdCirclePivotDrag = {
|
|
6558
7176
|
startMatrix: target.calcTransformMatrix(),
|
|
@@ -6569,7 +7187,7 @@ function applyTextPathControls(textbox) {
|
|
|
6569
7187
|
y: (state.startOffset.y || 0) + dy
|
|
6570
7188
|
};
|
|
6571
7189
|
target.setCoords();
|
|
6572
|
-
(
|
|
7190
|
+
(_b3 = target.canvas) == null ? void 0 : _b3.requestRenderAll();
|
|
6573
7191
|
return true;
|
|
6574
7192
|
},
|
|
6575
7193
|
render: renderPivot
|
|
@@ -6620,13 +7238,13 @@ function applyTextPathControls(textbox) {
|
|
|
6620
7238
|
}
|
|
6621
7239
|
if (!obj.__pdCirclePivotDblWired) {
|
|
6622
7240
|
obj.on("mousedblclick", () => {
|
|
6623
|
-
var _a3,
|
|
7241
|
+
var _a3, _b3;
|
|
6624
7242
|
if (((_a3 = obj.textPath) == null ? void 0 : _a3.preset) !== "circle") return;
|
|
6625
7243
|
if (obj.__corner !== "tpPivot") return;
|
|
6626
7244
|
if (!obj.textPath.pivot) return;
|
|
6627
7245
|
obj.textPath.pivot = { x: 0, y: 0 };
|
|
6628
7246
|
obj.setCoords();
|
|
6629
|
-
(
|
|
7247
|
+
(_b3 = obj.canvas) == null ? void 0 : _b3.requestRenderAll();
|
|
6630
7248
|
});
|
|
6631
7249
|
obj.__pdCirclePivotDblWired = true;
|
|
6632
7250
|
}
|
|
@@ -6994,10 +7612,10 @@ function textPathBoundsContainScenePoint(obj, point) {
|
|
|
6994
7612
|
}
|
|
6995
7613
|
}
|
|
6996
7614
|
function drawTextPathBounds(ctx, obj, bounds, hostCanvas) {
|
|
6997
|
-
var _a2,
|
|
7615
|
+
var _a2, _b2, _c;
|
|
6998
7616
|
const host = hostCanvas || obj.canvas || ((_a2 = obj.group) == null ? void 0 : _a2.canvas);
|
|
6999
7617
|
if (!host) return;
|
|
7000
|
-
const retina = ((
|
|
7618
|
+
const retina = ((_b2 = host.getRetinaScaling) == null ? void 0 : _b2.call(host)) || ((_c = obj.getCanvasRetinaScaling) == null ? void 0 : _c.call(obj)) || 1;
|
|
7001
7619
|
const matrix = fabric.util.multiplyTransformMatrices(host.viewportTransform || [1, 0, 0, 1, 0, 0], obj.calcTransformMatrix());
|
|
7002
7620
|
const corners = [
|
|
7003
7621
|
new fabric.Point(bounds.minX, bounds.minY),
|
|
@@ -7019,8 +7637,8 @@ function drawTextPathBounds(ctx, obj, bounds, hostCanvas) {
|
|
|
7019
7637
|
}
|
|
7020
7638
|
if (typeof TextboxProto._renderControls === "function" && !TextboxProto.__pixldocsOrigRenderControls) {
|
|
7021
7639
|
let drawWarpGuides = function(ctx) {
|
|
7022
|
-
var _a2,
|
|
7023
|
-
const hostCanvas = this.canvas || ((_a2 = this.group) == null ? void 0 : _a2.canvas) || ((_c = (
|
|
7640
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
7641
|
+
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);
|
|
7024
7642
|
if (!hostCanvas) return;
|
|
7025
7643
|
const hoverBounds = getTextPathHitBounds(this);
|
|
7026
7644
|
const active = (_d = hostCanvas.getActiveObject) == null ? void 0 : _d.call(hostCanvas);
|
|
@@ -7443,12 +8061,12 @@ function buildRoundedRectPath2D(ctx, x, y, w, h, rTL, rTR, rBR, rBL) {
|
|
|
7443
8061
|
ctx.closePath();
|
|
7444
8062
|
}
|
|
7445
8063
|
function measureLineGlyphWidth(obj, lineIndex) {
|
|
7446
|
-
var _a2,
|
|
8064
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
7447
8065
|
try {
|
|
7448
8066
|
const rawLine = (_a2 = obj == null ? void 0 : obj._textLines) == null ? void 0 : _a2[lineIndex];
|
|
7449
8067
|
const lineText = Array.isArray(rawLine) ? rawLine.join("") : String(rawLine ?? "");
|
|
7450
8068
|
if (!lineText) return 0;
|
|
7451
|
-
const fontSize = Number(((
|
|
8069
|
+
const fontSize = Number(((_b2 = obj.getValueOfPropertyAt) == null ? void 0 : _b2.call(obj, lineIndex, 0, "fontSize")) ?? obj.fontSize ?? 0);
|
|
7452
8070
|
if (!fontSize) return 0;
|
|
7453
8071
|
const fontStyle = String(((_c = obj.getValueOfPropertyAt) == null ? void 0 : _c.call(obj, lineIndex, 0, "fontStyle")) ?? obj.fontStyle ?? "normal");
|
|
7454
8072
|
const fontWeight = String(((_d = obj.getValueOfPropertyAt) == null ? void 0 : _d.call(obj, lineIndex, 0, "fontWeight")) ?? obj.fontWeight ?? "400");
|
|
@@ -7717,7 +8335,7 @@ function applyTextBackground(obj, cfg) {
|
|
|
7717
8335
|
const originalToSVG = (_a2 = obj.toSVG) == null ? void 0 : _a2.bind(obj);
|
|
7718
8336
|
if (typeof originalToSVG === "function") {
|
|
7719
8337
|
obj.toSVG = function(reviver) {
|
|
7720
|
-
var _a3,
|
|
8338
|
+
var _a3, _b2;
|
|
7721
8339
|
let svg = originalToSVG(reviver);
|
|
7722
8340
|
const bg = this[PD_BG_KEY];
|
|
7723
8341
|
const shadow = this.shadow;
|
|
@@ -7766,7 +8384,7 @@ function applyTextBackground(obj, cfg) {
|
|
|
7766
8384
|
const bgOpacityAttr = bgOpacity < 1 ? ` fill-opacity="${bgOpacity}"` : "";
|
|
7767
8385
|
let bgGradDefs = "";
|
|
7768
8386
|
let bgFillAttr = escapeXmlAttr(bgFill);
|
|
7769
|
-
if (hasBg && (bg == null ? void 0 : bg.gradient) && ((
|
|
8387
|
+
if (hasBg && (bg == null ? void 0 : bg.gradient) && ((_b2 = bg.gradient.stops) == null ? void 0 : _b2.length) >= 2) {
|
|
7770
8388
|
const bounds = ribbonD ? computeRibbonBoundsFor(this, pT, pR, pB, pL) : unionBounds(rects);
|
|
7771
8389
|
const gid = `__pdBgGrad_${Math.random().toString(36).slice(2, 9)}`;
|
|
7772
8390
|
const def = buildSvgGradientDef(bg.gradient, gid, bounds.x, bounds.y, bounds.w, bounds.h);
|
|
@@ -8795,9 +9413,9 @@ function createShape(element) {
|
|
|
8795
9413
|
});
|
|
8796
9414
|
}
|
|
8797
9415
|
case "circle": {
|
|
8798
|
-
|
|
8799
|
-
|
|
8800
|
-
|
|
9416
|
+
return new fabric.Ellipse({
|
|
9417
|
+
rx: w / 2,
|
|
9418
|
+
ry: h / 2,
|
|
8801
9419
|
fill,
|
|
8802
9420
|
stroke,
|
|
8803
9421
|
strokeWidth,
|
|
@@ -8806,8 +9424,7 @@ function createShape(element) {
|
|
|
8806
9424
|
objectCaching: true,
|
|
8807
9425
|
strokeUniform: true,
|
|
8808
9426
|
strokeLineJoin: "round",
|
|
8809
|
-
strokeLineCap: "round"
|
|
8810
|
-
lockUniScaling: true
|
|
9427
|
+
strokeLineCap: "round"
|
|
8811
9428
|
});
|
|
8812
9429
|
}
|
|
8813
9430
|
case "triangle": {
|
|
@@ -8842,7 +9459,7 @@ function createShape(element) {
|
|
|
8842
9459
|
}
|
|
8843
9460
|
}
|
|
8844
9461
|
function createText(element) {
|
|
8845
|
-
var _a2,
|
|
9462
|
+
var _a2, _b2, _c, _d, _e;
|
|
8846
9463
|
const overflowPolicy = element.overflowPolicy || "grow-and-push";
|
|
8847
9464
|
let text = element.text || "Text";
|
|
8848
9465
|
let fontSize = element.fontSize || 16;
|
|
@@ -9043,7 +9660,7 @@ function createText(element) {
|
|
|
9043
9660
|
textbox.setCoords();
|
|
9044
9661
|
const widthAfterSet = textbox.width ?? 0;
|
|
9045
9662
|
try {
|
|
9046
|
-
(
|
|
9663
|
+
(_b2 = textbox.setControlsVisibility) == null ? void 0 : _b2.call(textbox, {
|
|
9047
9664
|
tl: true,
|
|
9048
9665
|
tr: true,
|
|
9049
9666
|
bl: true,
|
|
@@ -9842,34 +10459,595 @@ function bakeEdgeFade(source, fade) {
|
|
|
9842
10459
|
return canvas;
|
|
9843
10460
|
}
|
|
9844
10461
|
const SELECTION_PRIMARY = "hsl(217, 91%, 60%)";
|
|
10462
|
+
const SELECTION_BORDER_SCALE = 2;
|
|
10463
|
+
let ensureCanvaControlRenders = () => {
|
|
10464
|
+
};
|
|
9845
10465
|
try {
|
|
9846
10466
|
const InteractiveBase = fabric.InteractiveFabricObject ?? fabric.Object;
|
|
10467
|
+
if ((InteractiveBase == null ? void 0 : InteractiveBase.prototype) && !InteractiveBase.prototype.__pixldocsCenteredSelectionBorder) {
|
|
10468
|
+
InteractiveBase.prototype.__pixldocsCenteredSelectionBorder = true;
|
|
10469
|
+
InteractiveBase.prototype.strokeBorders = function(ctx, size) {
|
|
10470
|
+
const border = Number(this.borderScaleFactor ?? SELECTION_BORDER_SCALE) || SELECTION_BORDER_SCALE;
|
|
10471
|
+
const width = Math.max(0, ((size == null ? void 0 : size.x) ?? 0) - border);
|
|
10472
|
+
const height = Math.max(0, ((size == null ? void 0 : size.y) ?? 0) - border);
|
|
10473
|
+
ctx.strokeRect(-width / 2, -height / 2, width, height);
|
|
10474
|
+
};
|
|
10475
|
+
}
|
|
9847
10476
|
if (InteractiveBase == null ? void 0 : InteractiveBase.ownDefaults) {
|
|
9848
10477
|
Object.assign(InteractiveBase.ownDefaults, {
|
|
9849
10478
|
borderColor: SELECTION_PRIMARY,
|
|
9850
|
-
borderScaleFactor:
|
|
10479
|
+
borderScaleFactor: SELECTION_BORDER_SCALE,
|
|
9851
10480
|
cornerColor: SELECTION_PRIMARY,
|
|
9852
10481
|
cornerStrokeColor: "#ffffff",
|
|
9853
|
-
cornerStyle: "
|
|
10482
|
+
cornerStyle: "circle",
|
|
9854
10483
|
transparentCorners: false,
|
|
9855
|
-
cornerSize:
|
|
10484
|
+
cornerSize: 10,
|
|
9856
10485
|
borderOpacityWhenMoving: 0.9
|
|
9857
10486
|
});
|
|
9858
10487
|
} else if (InteractiveBase == null ? void 0 : InteractiveBase.prototype) {
|
|
9859
10488
|
Object.assign(InteractiveBase.prototype, {
|
|
9860
10489
|
borderColor: SELECTION_PRIMARY,
|
|
9861
|
-
borderScaleFactor:
|
|
10490
|
+
borderScaleFactor: SELECTION_BORDER_SCALE,
|
|
9862
10491
|
cornerColor: SELECTION_PRIMARY,
|
|
9863
10492
|
cornerStrokeColor: "#ffffff",
|
|
9864
|
-
cornerStyle: "
|
|
10493
|
+
cornerStyle: "circle",
|
|
9865
10494
|
transparentCorners: false,
|
|
9866
|
-
cornerSize:
|
|
10495
|
+
cornerSize: 10,
|
|
9867
10496
|
borderOpacityWhenMoving: 0.9
|
|
9868
10497
|
});
|
|
9869
10498
|
}
|
|
9870
10499
|
} catch (e) {
|
|
9871
10500
|
console.warn("[PageCanvas] Failed to apply global selection defaults:", e);
|
|
9872
10501
|
}
|
|
10502
|
+
try {
|
|
10503
|
+
const cu = fabric.controlsUtils;
|
|
10504
|
+
if (cu && typeof cu.createObjectDefaultControls === "function") {
|
|
10505
|
+
const PILL_LEN = 20;
|
|
10506
|
+
const PILL_THICK = 6;
|
|
10507
|
+
const PILL_RADIUS = 3;
|
|
10508
|
+
const CORNER_RADIUS = 6;
|
|
10509
|
+
const EDGE_HIT_PERP = 22;
|
|
10510
|
+
const EDGE_HIT_ALONG = 44;
|
|
10511
|
+
const HOVER_FILL = SELECTION_PRIMARY;
|
|
10512
|
+
const HOVER_STROKE = "#ffffff";
|
|
10513
|
+
const IDLE_FILL = "#ffffff";
|
|
10514
|
+
const IDLE_STROKE = "rgba(15, 23, 42, 0.18)";
|
|
10515
|
+
const isHovered = (fabricObject, controlKey) => fabricObject && fabricObject.__corner === controlKey;
|
|
10516
|
+
const getHoverProgress = (fabricObject, controlKey) => {
|
|
10517
|
+
const map = fabricObject == null ? void 0 : fabricObject.__handleHoverProgress;
|
|
10518
|
+
const p = map ? map[controlKey] : void 0;
|
|
10519
|
+
if (typeof p === "number") return Math.max(0, Math.min(1, p));
|
|
10520
|
+
return isHovered(fabricObject, controlKey) ? 1 : 0;
|
|
10521
|
+
};
|
|
10522
|
+
const HOVER_RGB = [59, 130, 246];
|
|
10523
|
+
const IDLE_RGB = [255, 255, 255];
|
|
10524
|
+
const lerpFill = (p) => {
|
|
10525
|
+
const r = Math.round(IDLE_RGB[0] + (HOVER_RGB[0] - IDLE_RGB[0]) * p);
|
|
10526
|
+
const g = Math.round(IDLE_RGB[1] + (HOVER_RGB[1] - IDLE_RGB[1]) * p);
|
|
10527
|
+
const b = Math.round(IDLE_RGB[2] + (HOVER_RGB[2] - IDLE_RGB[2]) * p);
|
|
10528
|
+
return `rgb(${r}, ${g}, ${b})`;
|
|
10529
|
+
};
|
|
10530
|
+
const getVisualScale = (_fabricObject) => {
|
|
10531
|
+
return 1;
|
|
10532
|
+
};
|
|
10533
|
+
const COLLAPSE_THRESHOLD_PX = 32;
|
|
10534
|
+
const shouldCollapseHandles = (fabricObject) => {
|
|
10535
|
+
var _a2, _b2, _c;
|
|
10536
|
+
try {
|
|
10537
|
+
const canvas = fabricObject == null ? void 0 : fabricObject.canvas;
|
|
10538
|
+
if (!canvas) return false;
|
|
10539
|
+
const zoom = ((_a2 = canvas.getZoom) == null ? void 0 : _a2.call(canvas)) ?? 1;
|
|
10540
|
+
const w = (((_b2 = fabricObject.getScaledWidth) == null ? void 0 : _b2.call(fabricObject)) ?? fabricObject.width ?? 0) * zoom;
|
|
10541
|
+
const h = (((_c = fabricObject.getScaledHeight) == null ? void 0 : _c.call(fabricObject)) ?? fabricObject.height ?? 0) * zoom;
|
|
10542
|
+
return Math.min(w, h) < COLLAPSE_THRESHOLD_PX;
|
|
10543
|
+
} catch {
|
|
10544
|
+
return false;
|
|
10545
|
+
}
|
|
10546
|
+
};
|
|
10547
|
+
const isVisibleControlWhenCollapsed = (controlKey) => controlKey === "tl" || controlKey === "mr" || controlKey === "mtr" || controlKey === "mvh";
|
|
10548
|
+
const wrapCollapseVisibility = (control, controlKey) => {
|
|
10549
|
+
if (!control || control.__pixldocsCollapseVisibilityWrapped) return;
|
|
10550
|
+
const originalGetVisibility = typeof control.getVisibility === "function" ? control.getVisibility.bind(control) : null;
|
|
10551
|
+
control.getVisibility = (fabricObject, key) => {
|
|
10552
|
+
const baseVisible = originalGetVisibility ? originalGetVisibility(fabricObject, key) : control.visible !== false;
|
|
10553
|
+
if (!baseVisible) return false;
|
|
10554
|
+
return !shouldCollapseHandles(fabricObject) || isVisibleControlWhenCollapsed(controlKey);
|
|
10555
|
+
};
|
|
10556
|
+
control.__pixldocsCollapseVisibilityWrapped = true;
|
|
10557
|
+
};
|
|
10558
|
+
const renderPill = (ctx, left, top, _styleOverride, fabricObject, orientation, controlKey) => {
|
|
10559
|
+
var _a2, _b2, _c;
|
|
10560
|
+
const action = (_b2 = (_a2 = fabricObject.canvas) == null ? void 0 : _a2._currentTransform) == null ? void 0 : _b2.action;
|
|
10561
|
+
if (action === "drag" && fabricObject.__pixldocsDragMoved) return;
|
|
10562
|
+
if (shouldCollapseHandles(fabricObject) && !isVisibleControlWhenCollapsed(controlKey)) return;
|
|
10563
|
+
const angle = ((_c = fabricObject.getTotalAngle) == null ? void 0 : _c.call(fabricObject)) ?? (fabricObject.angle ?? 0);
|
|
10564
|
+
const p = getHoverProgress(fabricObject, controlKey);
|
|
10565
|
+
const scale = getVisualScale(fabricObject);
|
|
10566
|
+
const pillLen = PILL_LEN * scale;
|
|
10567
|
+
const pillThick = PILL_THICK * scale;
|
|
10568
|
+
const w = orientation === "horizontal" ? pillLen : pillThick;
|
|
10569
|
+
const h = orientation === "horizontal" ? pillThick : pillLen;
|
|
10570
|
+
ctx.save();
|
|
10571
|
+
ctx.translate(left, top);
|
|
10572
|
+
ctx.rotate(angle * Math.PI / 180);
|
|
10573
|
+
ctx.beginPath();
|
|
10574
|
+
const x = -w / 2;
|
|
10575
|
+
const y = -h / 2;
|
|
10576
|
+
const r = Math.min(PILL_RADIUS * scale, Math.min(w, h) / 2);
|
|
10577
|
+
ctx.moveTo(x + r, y);
|
|
10578
|
+
ctx.lineTo(x + w - r, y);
|
|
10579
|
+
ctx.quadraticCurveTo(x + w, y, x + w, y + r);
|
|
10580
|
+
ctx.lineTo(x + w, y + h - r);
|
|
10581
|
+
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
|
|
10582
|
+
ctx.lineTo(x + r, y + h);
|
|
10583
|
+
ctx.quadraticCurveTo(x, y + h, x, y + h - r);
|
|
10584
|
+
ctx.lineTo(x, y + r);
|
|
10585
|
+
ctx.quadraticCurveTo(x, y, x + r, y);
|
|
10586
|
+
ctx.closePath();
|
|
10587
|
+
ctx.fillStyle = lerpFill(p);
|
|
10588
|
+
ctx.strokeStyle = `rgba(15, 23, 42, ${0.18 * (1 - p)})`;
|
|
10589
|
+
ctx.lineWidth = 0.75 * (1 - p);
|
|
10590
|
+
ctx.shadowColor = "rgba(15, 23, 42, 0.38)";
|
|
10591
|
+
ctx.shadowBlur = 8;
|
|
10592
|
+
ctx.shadowOffsetY = 2;
|
|
10593
|
+
ctx.fill();
|
|
10594
|
+
if (p < 1) ctx.stroke();
|
|
10595
|
+
ctx.restore();
|
|
10596
|
+
};
|
|
10597
|
+
const renderCornerDot = (ctx, left, top, _styleOverride, fabricObject, controlKey) => {
|
|
10598
|
+
var _a2, _b2;
|
|
10599
|
+
const action = (_b2 = (_a2 = fabricObject.canvas) == null ? void 0 : _a2._currentTransform) == null ? void 0 : _b2.action;
|
|
10600
|
+
if (action === "drag" && fabricObject.__pixldocsDragMoved) return;
|
|
10601
|
+
if (shouldCollapseHandles(fabricObject) && !isVisibleControlWhenCollapsed(controlKey)) return;
|
|
10602
|
+
const p = getHoverProgress(fabricObject, controlKey);
|
|
10603
|
+
const scale = getVisualScale(fabricObject);
|
|
10604
|
+
const r = CORNER_RADIUS * scale;
|
|
10605
|
+
ctx.save();
|
|
10606
|
+
ctx.beginPath();
|
|
10607
|
+
ctx.arc(left, top, r, 0, Math.PI * 2);
|
|
10608
|
+
ctx.closePath();
|
|
10609
|
+
ctx.fillStyle = lerpFill(p);
|
|
10610
|
+
ctx.strokeStyle = `rgba(15, 23, 42, ${0.18 * (1 - p)})`;
|
|
10611
|
+
ctx.lineWidth = 0.75 * (1 - p);
|
|
10612
|
+
ctx.shadowColor = "rgba(15, 23, 42, 0.38)";
|
|
10613
|
+
ctx.shadowBlur = 8;
|
|
10614
|
+
ctx.shadowOffsetY = 2;
|
|
10615
|
+
ctx.fill();
|
|
10616
|
+
if (p < 1) ctx.stroke();
|
|
10617
|
+
ctx.restore();
|
|
10618
|
+
};
|
|
10619
|
+
const installPillRenders = (controls) => {
|
|
10620
|
+
var _a2;
|
|
10621
|
+
const CUR_SIZE = 22;
|
|
10622
|
+
const HOT = Math.round(CUR_SIZE / 2);
|
|
10623
|
+
const makeCursor = (angleDeg) => {
|
|
10624
|
+
const svg = `<?xml version="1.0" encoding="UTF-8"?>
|
|
10625
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${CUR_SIZE}" height="${CUR_SIZE}" viewBox="0 0 22 22">
|
|
10626
|
+
<g transform="rotate(${angleDeg} 11 11)" fill="none" stroke="#000" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
|
|
10627
|
+
<path d="M2.5 11 L19.5 11" stroke="#fff" stroke-width="3.2"/>
|
|
10628
|
+
<path d="M5 8.5 L2.5 11 L5 13.5" stroke="#fff" stroke-width="3.2"/>
|
|
10629
|
+
<path d="M17 8.5 L19.5 11 L17 13.5" stroke="#fff" stroke-width="3.2"/>
|
|
10630
|
+
<path d="M2.5 11 L19.5 11"/>
|
|
10631
|
+
<path d="M5 8.5 L2.5 11 L5 13.5"/>
|
|
10632
|
+
<path d="M17 8.5 L19.5 11 L17 13.5"/>
|
|
10633
|
+
</g>
|
|
10634
|
+
</svg>`;
|
|
10635
|
+
const encoded = encodeURIComponent(svg).replace(/'/g, "%27").replace(/"/g, "%22");
|
|
10636
|
+
const fallback = angleDeg % 180 === 0 ? "ew-resize" : angleDeg % 180 === 90 ? "ns-resize" : angleDeg === 45 || angleDeg === 225 ? "nwse-resize" : "nesw-resize";
|
|
10637
|
+
return `url("data:image/svg+xml;utf8,${encoded}") ${HOT} ${HOT}, ${fallback}`;
|
|
10638
|
+
};
|
|
10639
|
+
const cursorFor = {
|
|
10640
|
+
ml: makeCursor(0),
|
|
10641
|
+
mr: makeCursor(0),
|
|
10642
|
+
mt: makeCursor(90),
|
|
10643
|
+
mb: makeCursor(90),
|
|
10644
|
+
tl: makeCursor(45),
|
|
10645
|
+
br: makeCursor(45),
|
|
10646
|
+
tr: makeCursor(135),
|
|
10647
|
+
bl: makeCursor(135)
|
|
10648
|
+
};
|
|
10649
|
+
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";
|
|
10650
|
+
const CUR_R_SIZE = 18;
|
|
10651
|
+
const HOT_R = Math.round(CUR_R_SIZE / 2);
|
|
10652
|
+
const makeRotateCursor = (angleDeg) => {
|
|
10653
|
+
const a = ((angleDeg + 215) % 360 + 360) % 360;
|
|
10654
|
+
const halo = `<path d="${ROTATE_ICON_PATH}" fill="#fff" stroke="#fff" stroke-width="40" stroke-linejoin="round"/>`;
|
|
10655
|
+
const fg = `<path d="${ROTATE_ICON_PATH}" fill="#0f172a" stroke="#0f172a" stroke-width="6" stroke-linejoin="round"/>`;
|
|
10656
|
+
const svg = `<?xml version="1.0" encoding="UTF-8"?>
|
|
10657
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${CUR_R_SIZE}" height="${CUR_R_SIZE}" viewBox="0 0 512 512">
|
|
10658
|
+
<g transform="rotate(${a} 256 256)">${halo}${fg}</g>
|
|
10659
|
+
</svg>`;
|
|
10660
|
+
const encoded = encodeURIComponent(svg).replace(/'/g, "%27").replace(/"/g, "%22");
|
|
10661
|
+
return `url("data:image/svg+xml;utf8,${encoded}") ${HOT_R} ${HOT_R}, crosshair`;
|
|
10662
|
+
};
|
|
10663
|
+
const rotateCursorCache = {};
|
|
10664
|
+
const getRotateCursor = (fabricObject) => {
|
|
10665
|
+
let objAngle = 0;
|
|
10666
|
+
try {
|
|
10667
|
+
objAngle = typeof (fabricObject == null ? void 0 : fabricObject.getTotalAngle) === "function" ? fabricObject.getTotalAngle() : (fabricObject == null ? void 0 : fabricObject.angle) ?? 0;
|
|
10668
|
+
} catch {
|
|
10669
|
+
objAngle = 0;
|
|
10670
|
+
}
|
|
10671
|
+
let a = (objAngle % 360 + 360) % 360;
|
|
10672
|
+
a = Math.round(a / 15) * 15;
|
|
10673
|
+
if (a === 360) a = 0;
|
|
10674
|
+
if (!rotateCursorCache[a]) rotateCursorCache[a] = makeRotateCursor(a);
|
|
10675
|
+
return rotateCursorCache[a];
|
|
10676
|
+
};
|
|
10677
|
+
const MOVE_PATHS_2D = [
|
|
10678
|
+
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"),
|
|
10679
|
+
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"),
|
|
10680
|
+
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"),
|
|
10681
|
+
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")
|
|
10682
|
+
];
|
|
10683
|
+
const ROTATE_PATHS_2D = [
|
|
10684
|
+
new Path2D("M22 12l-3 3-3-3"),
|
|
10685
|
+
new Path2D("M2 12l3-3 3 3"),
|
|
10686
|
+
new Path2D("M19.016 14v-1.95A7.05 7.05 0 0 0 8 6.22"),
|
|
10687
|
+
new Path2D("M16.016 17.845A7.05 7.05 0 0 1 5 12.015V10"),
|
|
10688
|
+
new Path2D("M5 10V9"),
|
|
10689
|
+
new Path2D("M19 15v-1")
|
|
10690
|
+
];
|
|
10691
|
+
const baseAngleFor = {
|
|
10692
|
+
ml: 0,
|
|
10693
|
+
mr: 0,
|
|
10694
|
+
mt: 90,
|
|
10695
|
+
mb: 90,
|
|
10696
|
+
tl: 45,
|
|
10697
|
+
br: 45,
|
|
10698
|
+
tr: 135,
|
|
10699
|
+
bl: 135
|
|
10700
|
+
};
|
|
10701
|
+
const cursorCache = {};
|
|
10702
|
+
const getRotatedCursor = (key, fabricObject) => {
|
|
10703
|
+
const base = baseAngleFor[key];
|
|
10704
|
+
if (base === void 0) return cursorFor[key];
|
|
10705
|
+
let objAngle = 0;
|
|
10706
|
+
try {
|
|
10707
|
+
objAngle = typeof (fabricObject == null ? void 0 : fabricObject.getTotalAngle) === "function" ? fabricObject.getTotalAngle() : (fabricObject == null ? void 0 : fabricObject.angle) ?? 0;
|
|
10708
|
+
} catch {
|
|
10709
|
+
objAngle = 0;
|
|
10710
|
+
}
|
|
10711
|
+
let a = ((base + objAngle) % 180 + 180) % 180;
|
|
10712
|
+
a = Math.round(a / 15) * 15;
|
|
10713
|
+
if (a === 180) a = 0;
|
|
10714
|
+
if (!cursorCache[a]) cursorCache[a] = makeCursor(a);
|
|
10715
|
+
return cursorCache[a];
|
|
10716
|
+
};
|
|
10717
|
+
const sides = [
|
|
10718
|
+
["ml", "vertical"],
|
|
10719
|
+
["mr", "vertical"],
|
|
10720
|
+
["mt", "horizontal"],
|
|
10721
|
+
["mb", "horizontal"]
|
|
10722
|
+
];
|
|
10723
|
+
for (const [key, orient] of sides) {
|
|
10724
|
+
const c = controls[key];
|
|
10725
|
+
if (!c) continue;
|
|
10726
|
+
c.sizeX = orient === "horizontal" ? EDGE_HIT_ALONG : EDGE_HIT_PERP;
|
|
10727
|
+
c.sizeY = orient === "horizontal" ? EDGE_HIT_PERP : EDGE_HIT_ALONG;
|
|
10728
|
+
c.touchSizeX = c.sizeX;
|
|
10729
|
+
c.touchSizeY = c.sizeY;
|
|
10730
|
+
wrapCollapseVisibility(c, key);
|
|
10731
|
+
c.cursorStyle = cursorFor[key];
|
|
10732
|
+
c.cursorStyleHandler = (_eventData, _control, fabricObject) => getRotatedCursor(key, fabricObject);
|
|
10733
|
+
c.render = (ctx, left, top, styleOverride, fabricObject) => renderPill(ctx, left, top, styleOverride, fabricObject, orient, key);
|
|
10734
|
+
}
|
|
10735
|
+
const corners = ["tl", "tr", "bl", "br"];
|
|
10736
|
+
for (const key of corners) {
|
|
10737
|
+
const c = controls[key];
|
|
10738
|
+
if (!c) continue;
|
|
10739
|
+
c.sizeX = 16;
|
|
10740
|
+
c.sizeY = 16;
|
|
10741
|
+
c.touchSizeX = 24;
|
|
10742
|
+
c.touchSizeY = 24;
|
|
10743
|
+
wrapCollapseVisibility(c, key);
|
|
10744
|
+
c.cursorStyle = cursorFor[key];
|
|
10745
|
+
c.cursorStyleHandler = (_eventData, _control, fabricObject) => getRotatedCursor(key, fabricObject);
|
|
10746
|
+
c.render = (ctx, left, top, styleOverride, fabricObject) => renderCornerDot(ctx, left, top, styleOverride, fabricObject, key);
|
|
10747
|
+
}
|
|
10748
|
+
const mtr = controls.mtr;
|
|
10749
|
+
if (mtr) {
|
|
10750
|
+
mtr.sizeX = 22;
|
|
10751
|
+
mtr.sizeY = 22;
|
|
10752
|
+
mtr.touchSizeX = 32;
|
|
10753
|
+
mtr.touchSizeY = 32;
|
|
10754
|
+
wrapCollapseVisibility(mtr, "mtr");
|
|
10755
|
+
mtr.offsetY = -28;
|
|
10756
|
+
mtr.withConnection = false;
|
|
10757
|
+
mtr.x = 0;
|
|
10758
|
+
mtr.y = -0.5;
|
|
10759
|
+
mtr.cursorStyle = getRotateCursor(null);
|
|
10760
|
+
mtr.cursorStyleHandler = (_e, _c, fabricObject) => {
|
|
10761
|
+
const cursor = getRotateCursor(fabricObject);
|
|
10762
|
+
try {
|
|
10763
|
+
const canvas = fabricObject == null ? void 0 : fabricObject.canvas;
|
|
10764
|
+
if (canvas) canvas.__pixldocsGetRotateCursor = getRotateCursor;
|
|
10765
|
+
const upper = canvas == null ? void 0 : canvas.upperCanvasEl;
|
|
10766
|
+
if (upper) upper.style.cursor = cursor;
|
|
10767
|
+
} catch {
|
|
10768
|
+
}
|
|
10769
|
+
return cursor;
|
|
10770
|
+
};
|
|
10771
|
+
mtr.render = (ctx, left, top, _styleOverride, fabricObject) => {
|
|
10772
|
+
var _a3, _b2;
|
|
10773
|
+
const action = (_b2 = (_a3 = fabricObject.canvas) == null ? void 0 : _a3._currentTransform) == null ? void 0 : _b2.action;
|
|
10774
|
+
if (action === "drag" && fabricObject.__pixldocsDragMoved) return;
|
|
10775
|
+
const scale = getVisualScale(fabricObject);
|
|
10776
|
+
const p = getHoverProgress(fabricObject, "mtr");
|
|
10777
|
+
const r = 11 * scale;
|
|
10778
|
+
ctx.save();
|
|
10779
|
+
ctx.beginPath();
|
|
10780
|
+
ctx.arc(left, top, r, 0, Math.PI * 2);
|
|
10781
|
+
ctx.closePath();
|
|
10782
|
+
ctx.fillStyle = lerpFill(p);
|
|
10783
|
+
ctx.strokeStyle = `rgba(15, 23, 42, ${0.18 * (1 - p)})`;
|
|
10784
|
+
ctx.lineWidth = 0.75 * (1 - p);
|
|
10785
|
+
ctx.shadowColor = "rgba(15, 23, 42, 0.4)";
|
|
10786
|
+
ctx.shadowBlur = 10;
|
|
10787
|
+
ctx.shadowOffsetY = 2;
|
|
10788
|
+
ctx.fill();
|
|
10789
|
+
if (p < 1) ctx.stroke();
|
|
10790
|
+
ctx.shadowColor = "transparent";
|
|
10791
|
+
ctx.shadowBlur = 0;
|
|
10792
|
+
ctx.shadowOffsetY = 0;
|
|
10793
|
+
const iconColor = p > 0.5 ? "#ffffff" : "rgba(15, 23, 42, 0.85)";
|
|
10794
|
+
ctx.strokeStyle = iconColor;
|
|
10795
|
+
ctx.fillStyle = iconColor;
|
|
10796
|
+
ctx.lineJoin = "miter";
|
|
10797
|
+
ctx.miterLimit = 4;
|
|
10798
|
+
{
|
|
10799
|
+
const target = r * 1.55;
|
|
10800
|
+
const s = target / 24;
|
|
10801
|
+
ctx.translate(left, top);
|
|
10802
|
+
ctx.scale(s, s);
|
|
10803
|
+
ctx.translate(-12, -12);
|
|
10804
|
+
ctx.strokeStyle = iconColor;
|
|
10805
|
+
ctx.lineWidth = 1 / s;
|
|
10806
|
+
ROTATE_PATHS_2D.forEach((p2d, index) => {
|
|
10807
|
+
ctx.lineCap = index >= 4 ? "round" : "square";
|
|
10808
|
+
ctx.stroke(p2d);
|
|
10809
|
+
});
|
|
10810
|
+
}
|
|
10811
|
+
ctx.restore();
|
|
10812
|
+
};
|
|
10813
|
+
}
|
|
10814
|
+
const moveActionHandler = (eventData, transform, x, y) => {
|
|
10815
|
+
const target = transform.target;
|
|
10816
|
+
if (!target) return false;
|
|
10817
|
+
if (!transform.__pixldocsMoveStart) {
|
|
10818
|
+
transform.__pixldocsMoveStart = {
|
|
10819
|
+
x,
|
|
10820
|
+
y,
|
|
10821
|
+
left: target.left ?? 0,
|
|
10822
|
+
top: target.top ?? 0
|
|
10823
|
+
};
|
|
10824
|
+
}
|
|
10825
|
+
const s = transform.__pixldocsMoveStart;
|
|
10826
|
+
target.set({ left: s.left + (x - s.x), top: s.top + (y - s.y) });
|
|
10827
|
+
target.setCoords();
|
|
10828
|
+
try {
|
|
10829
|
+
const canvas = target.canvas;
|
|
10830
|
+
if (canvas) {
|
|
10831
|
+
canvas.fire("object:moving", { target, e: eventData == null ? void 0 : eventData.e, transform, pointer: { x, y } });
|
|
10832
|
+
target.fire("moving", { e: eventData == null ? void 0 : eventData.e, transform, pointer: { x, y } });
|
|
10833
|
+
}
|
|
10834
|
+
} catch {
|
|
10835
|
+
}
|
|
10836
|
+
return true;
|
|
10837
|
+
};
|
|
10838
|
+
const renderMoveHandle = (ctx, left, top, _styleOverride, fabricObject) => {
|
|
10839
|
+
var _a3, _b2;
|
|
10840
|
+
if (!shouldCollapseHandles(fabricObject)) return;
|
|
10841
|
+
const action = (_b2 = (_a3 = fabricObject.canvas) == null ? void 0 : _a3._currentTransform) == null ? void 0 : _b2.action;
|
|
10842
|
+
if (action === "drag" && fabricObject.__pixldocsDragMoved) return;
|
|
10843
|
+
const scale = getVisualScale(fabricObject);
|
|
10844
|
+
const p = getHoverProgress(fabricObject, "mvh");
|
|
10845
|
+
const r = 11 * scale;
|
|
10846
|
+
ctx.save();
|
|
10847
|
+
ctx.beginPath();
|
|
10848
|
+
ctx.arc(left, top, r, 0, Math.PI * 2);
|
|
10849
|
+
ctx.closePath();
|
|
10850
|
+
ctx.fillStyle = lerpFill(p);
|
|
10851
|
+
ctx.strokeStyle = `rgba(15, 23, 42, ${0.18 * (1 - p)})`;
|
|
10852
|
+
ctx.lineWidth = 0.75 * (1 - p);
|
|
10853
|
+
ctx.shadowColor = "rgba(15, 23, 42, 0.4)";
|
|
10854
|
+
ctx.shadowBlur = 10;
|
|
10855
|
+
ctx.shadowOffsetY = 2;
|
|
10856
|
+
ctx.fill();
|
|
10857
|
+
if (p < 1) ctx.stroke();
|
|
10858
|
+
ctx.shadowColor = "transparent";
|
|
10859
|
+
ctx.shadowBlur = 0;
|
|
10860
|
+
ctx.shadowOffsetY = 0;
|
|
10861
|
+
const iconColor = p > 0.5 ? "#ffffff" : "rgba(15, 23, 42, 0.85)";
|
|
10862
|
+
ctx.fillStyle = iconColor;
|
|
10863
|
+
const target = r * 1.5;
|
|
10864
|
+
const s = target / 24;
|
|
10865
|
+
ctx.translate(left, top);
|
|
10866
|
+
ctx.scale(s, s);
|
|
10867
|
+
ctx.translate(-12, -12);
|
|
10868
|
+
for (const p2d of MOVE_PATHS_2D) ctx.fill(p2d);
|
|
10869
|
+
ctx.restore();
|
|
10870
|
+
};
|
|
10871
|
+
if (!controls.mvh) {
|
|
10872
|
+
const mvh = new fabric.Control({
|
|
10873
|
+
x: 0,
|
|
10874
|
+
y: 0.5,
|
|
10875
|
+
offsetY: 28,
|
|
10876
|
+
sizeX: 22,
|
|
10877
|
+
sizeY: 22,
|
|
10878
|
+
touchSizeX: 32,
|
|
10879
|
+
touchSizeY: 32,
|
|
10880
|
+
cursorStyle: "move",
|
|
10881
|
+
actionName: "drag",
|
|
10882
|
+
actionHandler: moveActionHandler,
|
|
10883
|
+
render: renderMoveHandle
|
|
10884
|
+
});
|
|
10885
|
+
mvh.withConnection = false;
|
|
10886
|
+
controls.mvh = mvh;
|
|
10887
|
+
} else {
|
|
10888
|
+
controls.mvh.render = renderMoveHandle;
|
|
10889
|
+
controls.mvh.actionHandler = moveActionHandler;
|
|
10890
|
+
controls.mvh.cursorStyle = "move";
|
|
10891
|
+
}
|
|
10892
|
+
wrapCollapseVisibility(controls.mvh, "mvh");
|
|
10893
|
+
const baseGetVisibility = (_a2 = controls.mvh.getVisibility) == null ? void 0 : _a2.bind(controls.mvh);
|
|
10894
|
+
if (baseGetVisibility && !controls.mvh.__pixldocsMvhVisibilityWrapped) {
|
|
10895
|
+
controls.mvh.getVisibility = (fabricObject, key) => {
|
|
10896
|
+
if (!shouldCollapseHandles(fabricObject)) return false;
|
|
10897
|
+
return baseGetVisibility(fabricObject, key);
|
|
10898
|
+
};
|
|
10899
|
+
controls.mvh.__pixldocsMvhVisibilityWrapped = true;
|
|
10900
|
+
}
|
|
10901
|
+
return controls;
|
|
10902
|
+
};
|
|
10903
|
+
ensureCanvaControlRenders = (obj) => {
|
|
10904
|
+
try {
|
|
10905
|
+
if (obj && obj.controls) installPillRenders(obj.controls);
|
|
10906
|
+
if (obj && Array.isArray(obj._objects)) {
|
|
10907
|
+
for (const child of obj._objects) {
|
|
10908
|
+
if (child && child.controls) installPillRenders(child.controls);
|
|
10909
|
+
}
|
|
10910
|
+
}
|
|
10911
|
+
} catch (e) {
|
|
10912
|
+
}
|
|
10913
|
+
};
|
|
10914
|
+
const origObj = cu.createObjectDefaultControls.bind(cu);
|
|
10915
|
+
cu.createObjectDefaultControls = () => installPillRenders(origObj());
|
|
10916
|
+
if (typeof cu.createTextboxDefaultControls === "function") {
|
|
10917
|
+
const origTb = cu.createTextboxDefaultControls.bind(cu);
|
|
10918
|
+
cu.createTextboxDefaultControls = () => installPillRenders(origTb());
|
|
10919
|
+
}
|
|
10920
|
+
const wrapClassCreateControls = (Klass) => {
|
|
10921
|
+
if (!Klass || typeof Klass.createControls !== "function") return;
|
|
10922
|
+
const orig = Klass.createControls.bind(Klass);
|
|
10923
|
+
Klass.createControls = () => {
|
|
10924
|
+
const res = orig();
|
|
10925
|
+
if (res && res.controls) installPillRenders(res.controls);
|
|
10926
|
+
return res;
|
|
10927
|
+
};
|
|
10928
|
+
};
|
|
10929
|
+
wrapClassCreateControls(fabric.InteractiveFabricObject);
|
|
10930
|
+
wrapClassCreateControls(fabric.FabricObject);
|
|
10931
|
+
wrapClassCreateControls(fabric.Textbox);
|
|
10932
|
+
wrapClassCreateControls(fabric.IText);
|
|
10933
|
+
const CanvasProto = (_b = fabric.Canvas) == null ? void 0 : _b.prototype;
|
|
10934
|
+
if (CanvasProto && typeof CanvasProto._setCursorFromEvent === "function") {
|
|
10935
|
+
const origSet = CanvasProto._setCursorFromEvent;
|
|
10936
|
+
CanvasProto._setCursorFromEvent = function(e, target) {
|
|
10937
|
+
const prev = target && target.__corner;
|
|
10938
|
+
const res = origSet.call(this, e, target);
|
|
10939
|
+
const next = target && target.__corner;
|
|
10940
|
+
if (prev !== next) {
|
|
10941
|
+
try {
|
|
10942
|
+
this.requestRenderAll();
|
|
10943
|
+
} catch {
|
|
10944
|
+
}
|
|
10945
|
+
}
|
|
10946
|
+
return res;
|
|
10947
|
+
};
|
|
10948
|
+
}
|
|
10949
|
+
}
|
|
10950
|
+
} catch (e) {
|
|
10951
|
+
console.warn("[PageCanvas] Failed to install Canva-style control handles:", e);
|
|
10952
|
+
}
|
|
10953
|
+
const scaleTextPathConfig = (textPath, sx, sy, uniform) => {
|
|
10954
|
+
if (!textPath || typeof textPath !== "object") return textPath;
|
|
10955
|
+
const next = JSON.parse(JSON.stringify(textPath));
|
|
10956
|
+
if (typeof next.radius === "number") next.radius *= uniform;
|
|
10957
|
+
if (next.bbox) {
|
|
10958
|
+
if (typeof next.bbox.width === "number") next.bbox.width *= sx;
|
|
10959
|
+
if (typeof next.bbox.height === "number") next.bbox.height *= sy;
|
|
10960
|
+
}
|
|
10961
|
+
if (next.endpoints) {
|
|
10962
|
+
if (typeof next.endpoints.leftY === "number") next.endpoints.leftY *= sy;
|
|
10963
|
+
if (typeof next.endpoints.rightY === "number") next.endpoints.rightY *= sy;
|
|
10964
|
+
if (typeof next.endpoints.centerY === "number") next.endpoints.centerY *= sy;
|
|
10965
|
+
}
|
|
10966
|
+
if (next.pivot) {
|
|
10967
|
+
if (typeof next.pivot.x === "number") next.pivot.x *= sx;
|
|
10968
|
+
if (typeof next.pivot.y === "number") next.pivot.y *= sy;
|
|
10969
|
+
}
|
|
10970
|
+
if (next.bezier) {
|
|
10971
|
+
["p0", "c0", "c1", "p1"].forEach((key) => {
|
|
10972
|
+
if (Array.isArray(next.bezier[key])) {
|
|
10973
|
+
next.bezier[key][0] *= sx;
|
|
10974
|
+
next.bezier[key][1] *= sy;
|
|
10975
|
+
}
|
|
10976
|
+
});
|
|
10977
|
+
}
|
|
10978
|
+
return next;
|
|
10979
|
+
};
|
|
10980
|
+
const scaleUpdateNumber = (updates, source, key, factor) => {
|
|
10981
|
+
const value = Number(source == null ? void 0 : source[key]);
|
|
10982
|
+
if (Number.isFinite(value)) updates[key] = value * factor;
|
|
10983
|
+
};
|
|
10984
|
+
const bakeTextboxScaleIntoTypography = (obj, sourceElement) => {
|
|
10985
|
+
const sx = Math.abs(obj.scaleX ?? 1) || 1;
|
|
10986
|
+
const sy = Math.abs(obj.scaleY ?? 1) || 1;
|
|
10987
|
+
if (Math.abs(sx - 1) < 1e-3 && Math.abs(sy - 1) < 1e-3) return null;
|
|
10988
|
+
const isUniform = Math.abs(sx - sy) < 0.01;
|
|
10989
|
+
const fontScale = isUniform ? (sx + sy) / 2 : Math.abs(sy - 1) > 1e-3 ? sy : 1;
|
|
10990
|
+
const effectScale = isUniform ? fontScale : Math.max(1e-3, Math.sqrt(sx * sy));
|
|
10991
|
+
const updates = {
|
|
10992
|
+
width: Math.max(20, (obj.width ?? (sourceElement == null ? void 0 : sourceElement.width) ?? 20) * sx),
|
|
10993
|
+
scaleX: 1,
|
|
10994
|
+
scaleY: 1
|
|
10995
|
+
};
|
|
10996
|
+
if (fontScale !== 1) {
|
|
10997
|
+
updates.fontSize = Math.max(1, Number(obj.fontSize || (sourceElement == null ? void 0 : sourceElement.fontSize) || 16) * fontScale);
|
|
10998
|
+
const minBoxHeight = Number(obj.minBoxHeight ?? (sourceElement == null ? void 0 : sourceElement.minBoxHeight));
|
|
10999
|
+
if (Number.isFinite(minBoxHeight) && minBoxHeight > 0) updates.minBoxHeight = minBoxHeight * sy;
|
|
11000
|
+
}
|
|
11001
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "strokeWidth", effectScale);
|
|
11002
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textShadowBlur", effectScale);
|
|
11003
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textShadowDistance", effectScale);
|
|
11004
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textShadowOffsetX", sx);
|
|
11005
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textShadowOffsetY", sy);
|
|
11006
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgPaddingTop", sy);
|
|
11007
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgPaddingBottom", sy);
|
|
11008
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgPaddingLeft", sx);
|
|
11009
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgPaddingRight", sx);
|
|
11010
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgPadding", effectScale);
|
|
11011
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgRxTL", effectScale);
|
|
11012
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgRxTR", effectScale);
|
|
11013
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgRxBR", effectScale);
|
|
11014
|
+
scaleUpdateNumber(updates, sourceElement ?? void 0, "textBgRxBL", effectScale);
|
|
11015
|
+
const textPath = obj.textPath ?? (sourceElement == null ? void 0 : sourceElement.textPath);
|
|
11016
|
+
if (textPath) updates.textPath = scaleTextPathConfig(textPath, sx, sy, effectScale);
|
|
11017
|
+
const center = obj.getCenterPoint();
|
|
11018
|
+
obj.set({
|
|
11019
|
+
width: updates.width,
|
|
11020
|
+
scaleX: 1,
|
|
11021
|
+
scaleY: 1,
|
|
11022
|
+
...updates.fontSize ? { fontSize: updates.fontSize } : {},
|
|
11023
|
+
...updates.strokeWidth !== void 0 ? { strokeWidth: updates.strokeWidth } : {}
|
|
11024
|
+
});
|
|
11025
|
+
if (updates.minBoxHeight !== void 0) obj.minBoxHeight = updates.minBoxHeight;
|
|
11026
|
+
if (updates.textPath) obj.textPath = updates.textPath;
|
|
11027
|
+
const shadow = obj.shadow;
|
|
11028
|
+
if (shadow) {
|
|
11029
|
+
shadow.blur = updates.textShadowBlur ?? shadow.blur;
|
|
11030
|
+
shadow.offsetX = updates.textShadowOffsetX ?? shadow.offsetX;
|
|
11031
|
+
shadow.offsetY = updates.textShadowOffsetY ?? shadow.offsetY;
|
|
11032
|
+
}
|
|
11033
|
+
if ((sourceElement == null ? void 0 : sourceElement.type) === "text") {
|
|
11034
|
+
const bakedElement = { ...sourceElement, ...updates };
|
|
11035
|
+
applyTextBackground(obj, extractTextBgConfig(bakedElement));
|
|
11036
|
+
applyTextShadow(obj, bakedElement);
|
|
11037
|
+
}
|
|
11038
|
+
try {
|
|
11039
|
+
obj.initDimensions();
|
|
11040
|
+
} catch {
|
|
11041
|
+
}
|
|
11042
|
+
obj.setPositionByOrigin(center, "center", "center");
|
|
11043
|
+
obj.setCoords();
|
|
11044
|
+
obj.dirty = true;
|
|
11045
|
+
obj.__pixldocsBakedTextScaleUpdates = {
|
|
11046
|
+
...obj.__pixldocsBakedTextScaleUpdates || {},
|
|
11047
|
+
...updates
|
|
11048
|
+
};
|
|
11049
|
+
return updates;
|
|
11050
|
+
};
|
|
9873
11051
|
function applyWarpAwareSelectionBorders(selection) {
|
|
9874
11052
|
if (selection.__pixldocsOrigASHasBorders !== void 0) {
|
|
9875
11053
|
selection.hasBorders = selection.__pixldocsOrigASHasBorders;
|
|
@@ -9937,8 +11115,11 @@ const PageCanvas = forwardRef(
|
|
|
9937
11115
|
const hasRunPostReadyReflowForPageRef = useRef(null);
|
|
9938
11116
|
const hasNotifiedReadyForPageRef = useRef(null);
|
|
9939
11117
|
const hasClearedCachesBeforeFirstSyncRef = useRef(false);
|
|
11118
|
+
const projectSettingsRef = useRef(projectSettings);
|
|
11119
|
+
projectSettingsRef.current = projectSettings;
|
|
9940
11120
|
const [guides, setGuides] = useState([]);
|
|
9941
11121
|
const [gridResizeLabel, setGridResizeLabel] = useState(null);
|
|
11122
|
+
const [hoverBounds, setHoverBounds] = useState(null);
|
|
9942
11123
|
const [rotationLabel, setRotationLabel] = useState(null);
|
|
9943
11124
|
const [sizeLabel, setSizeLabel] = useState(null);
|
|
9944
11125
|
const [ready, setReady] = useState(false);
|
|
@@ -10005,7 +11186,8 @@ const PageCanvas = forwardRef(
|
|
|
10005
11186
|
useRef(null);
|
|
10006
11187
|
useRef(null);
|
|
10007
11188
|
useRef(/* @__PURE__ */ new Map());
|
|
10008
|
-
useRef(null);
|
|
11189
|
+
const groupResizeActiveSnapRef = useRef(null);
|
|
11190
|
+
const objectResizeActiveSnapRef = useRef(null);
|
|
10009
11191
|
useRef(null);
|
|
10010
11192
|
useRef(null);
|
|
10011
11193
|
useRef(null);
|
|
@@ -10147,33 +11329,358 @@ const PageCanvas = forwardRef(
|
|
|
10147
11329
|
(movingObj) => {
|
|
10148
11330
|
const fabricCanvas = fabricRef.current;
|
|
10149
11331
|
if (!fabricCanvas) return { guides: [], snapDx: 0, snapDy: 0 };
|
|
11332
|
+
const ps = projectSettingsRef.current;
|
|
10150
11333
|
return calculateSnapGuides(
|
|
10151
11334
|
movingObj,
|
|
10152
11335
|
fabricCanvas,
|
|
10153
11336
|
canvasWidth,
|
|
10154
11337
|
canvasHeight,
|
|
10155
|
-
|
|
10156
|
-
|
|
11338
|
+
ps.snapToGuides,
|
|
11339
|
+
ps.snapThreshold
|
|
10157
11340
|
);
|
|
10158
11341
|
},
|
|
10159
|
-
[canvasWidth, canvasHeight
|
|
11342
|
+
[canvasWidth, canvasHeight]
|
|
10160
11343
|
);
|
|
11344
|
+
const getResizeExcludeIdsCallback = useCallback((obj) => {
|
|
11345
|
+
const ids = /* @__PURE__ */ new Set();
|
|
11346
|
+
const ownId = getObjectId(obj);
|
|
11347
|
+
if (ownId) ids.add(ownId);
|
|
11348
|
+
if (obj instanceof fabric.ActiveSelection) {
|
|
11349
|
+
obj.getObjects().forEach((member) => {
|
|
11350
|
+
const id = getObjectId(member);
|
|
11351
|
+
if (id) ids.add(id);
|
|
11352
|
+
});
|
|
11353
|
+
} else if (obj instanceof fabric.Group && typeof obj.getObjects === "function") {
|
|
11354
|
+
obj.getObjects().forEach((member) => {
|
|
11355
|
+
const id = getObjectId(member);
|
|
11356
|
+
if (id) ids.add(id);
|
|
11357
|
+
});
|
|
11358
|
+
}
|
|
11359
|
+
return ids;
|
|
11360
|
+
}, []);
|
|
11361
|
+
const getLogicalGroupSnapBoundsCallback = useCallback((excludeIds = []) => {
|
|
11362
|
+
const fabricCanvas = fabricRef.current;
|
|
11363
|
+
if (!fabricCanvas) return [];
|
|
11364
|
+
const excluded = new Set(excludeIds);
|
|
11365
|
+
const page = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
11366
|
+
const children = (page == null ? void 0 : page.children) ?? pageChildren ?? [];
|
|
11367
|
+
const objectBounds = /* @__PURE__ */ new Map();
|
|
11368
|
+
for (const object of fabricCanvas.getObjects()) {
|
|
11369
|
+
const id = getObjectId(object);
|
|
11370
|
+
if (!id || id === "__background__") continue;
|
|
11371
|
+
try {
|
|
11372
|
+
object.setCoords();
|
|
11373
|
+
} catch {
|
|
11374
|
+
}
|
|
11375
|
+
const bounds2 = object.getBoundingRect();
|
|
11376
|
+
objectBounds.set(id, { left: bounds2.left, top: bounds2.top, width: bounds2.width, height: bounds2.height });
|
|
11377
|
+
}
|
|
11378
|
+
const bounds = [];
|
|
11379
|
+
const visit = (nodes) => {
|
|
11380
|
+
for (const node of nodes) {
|
|
11381
|
+
if (!isGroup(node)) continue;
|
|
11382
|
+
const memberIds = getAllElementIds(node.children ?? []);
|
|
11383
|
+
if (memberIds.length === 0) continue;
|
|
11384
|
+
if (memberIds.some((id) => excluded.has(id)) || excluded.has(node.id)) {
|
|
11385
|
+
visit(node.children ?? []);
|
|
11386
|
+
continue;
|
|
11387
|
+
}
|
|
11388
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
11389
|
+
for (const memberId of memberIds) {
|
|
11390
|
+
const b = objectBounds.get(memberId);
|
|
11391
|
+
if (!b) continue;
|
|
11392
|
+
minX = Math.min(minX, b.left);
|
|
11393
|
+
minY = Math.min(minY, b.top);
|
|
11394
|
+
maxX = Math.max(maxX, b.left + b.width);
|
|
11395
|
+
maxY = Math.max(maxY, b.top + b.height);
|
|
11396
|
+
}
|
|
11397
|
+
if (Number.isFinite(minX) && Number.isFinite(minY) && maxX > minX && maxY > minY) {
|
|
11398
|
+
bounds.push({ left: minX, top: minY, width: maxX - minX, height: maxY - minY });
|
|
11399
|
+
}
|
|
11400
|
+
visit(node.children ?? []);
|
|
11401
|
+
}
|
|
11402
|
+
};
|
|
11403
|
+
visit(children);
|
|
11404
|
+
const seen = /* @__PURE__ */ new Set();
|
|
11405
|
+
return bounds.filter((b) => {
|
|
11406
|
+
const key = `${Math.round(b.left)}:${Math.round(b.top)}:${Math.round(b.width)}:${Math.round(b.height)}`;
|
|
11407
|
+
if (seen.has(key)) return false;
|
|
11408
|
+
seen.add(key);
|
|
11409
|
+
return true;
|
|
11410
|
+
});
|
|
11411
|
+
}, [pageId, pageChildren]);
|
|
10161
11412
|
const calculateScaleSnapGuidesCallback = useCallback(
|
|
10162
11413
|
(scalingObj, corner) => {
|
|
10163
11414
|
const fabricCanvas = fabricRef.current;
|
|
10164
11415
|
if (!fabricCanvas) return [];
|
|
11416
|
+
const ps = projectSettingsRef.current;
|
|
11417
|
+
const excludeIds = getResizeExcludeIdsCallback(scalingObj);
|
|
10165
11418
|
return calculateScaleSnapGuides(
|
|
10166
11419
|
scalingObj,
|
|
10167
11420
|
corner,
|
|
10168
|
-
fabricCanvas,
|
|
11421
|
+
fabricCanvas,
|
|
11422
|
+
canvasWidth,
|
|
11423
|
+
canvasHeight,
|
|
11424
|
+
ps.snapToGuides,
|
|
11425
|
+
ps.snapThreshold || 4,
|
|
11426
|
+
getLogicalGroupSnapBoundsCallback(excludeIds)
|
|
11427
|
+
);
|
|
11428
|
+
},
|
|
11429
|
+
[canvasWidth, canvasHeight, getLogicalGroupSnapBoundsCallback, getResizeExcludeIdsCallback]
|
|
11430
|
+
);
|
|
11431
|
+
const snapDuringScaleCallback = useCallback(
|
|
11432
|
+
(obj, corner) => {
|
|
11433
|
+
const fc = fabricRef.current;
|
|
11434
|
+
if (!fc || !obj || !corner) return;
|
|
11435
|
+
const ps = projectSettingsRef.current;
|
|
11436
|
+
if (!ps.snapToGuides) return;
|
|
11437
|
+
if (obj instanceof fabric.Textbox && (corner === "ml" || corner === "mr")) {
|
|
11438
|
+
const sourceEl = getObjectId(obj) ? elementsRef.current.find((el) => el.id === getObjectId(obj)) : void 0;
|
|
11439
|
+
bakeTextboxScaleIntoTypography(obj, sourceEl);
|
|
11440
|
+
}
|
|
11441
|
+
try {
|
|
11442
|
+
obj.setCoords();
|
|
11443
|
+
} catch {
|
|
11444
|
+
}
|
|
11445
|
+
const br = obj.getBoundingRect();
|
|
11446
|
+
const excludeIds = getResizeExcludeIdsCallback(obj);
|
|
11447
|
+
const snapThreshold = ps.snapThreshold || 4;
|
|
11448
|
+
const snapped = applyScaleSnapToBox(
|
|
11449
|
+
{ left: br.left, top: br.top, width: br.width, height: br.height },
|
|
11450
|
+
corner,
|
|
11451
|
+
fc,
|
|
10169
11452
|
canvasWidth,
|
|
10170
11453
|
canvasHeight,
|
|
10171
|
-
|
|
10172
|
-
|
|
11454
|
+
true,
|
|
11455
|
+
snapThreshold,
|
|
11456
|
+
getObjectId(obj),
|
|
11457
|
+
{
|
|
11458
|
+
hysteresis: 3,
|
|
11459
|
+
activeSnapRef: objectResizeActiveSnapRef,
|
|
11460
|
+
roundSnappedOnly: true,
|
|
11461
|
+
additionalBounds: getLogicalGroupSnapBoundsCallback(excludeIds),
|
|
11462
|
+
excludeObjectIds: excludeIds,
|
|
11463
|
+
matchDimensions: true
|
|
11464
|
+
}
|
|
10173
11465
|
);
|
|
11466
|
+
const maxSnapShift = Math.max(snapThreshold + 3, 10);
|
|
11467
|
+
const brRight = br.left + br.width;
|
|
11468
|
+
const brBottom = br.top + br.height;
|
|
11469
|
+
const snappedRight = snapped.left + snapped.width;
|
|
11470
|
+
const snappedBottom = snapped.top + snapped.height;
|
|
11471
|
+
const xJump = Math.max(Math.abs(snapped.left - br.left), Math.abs(snappedRight - brRight));
|
|
11472
|
+
const yJump = Math.max(Math.abs(snapped.top - br.top), Math.abs(snappedBottom - brBottom));
|
|
11473
|
+
if (xJump > maxSnapShift) {
|
|
11474
|
+
snapped.left = br.left;
|
|
11475
|
+
snapped.width = br.width;
|
|
11476
|
+
if (objectResizeActiveSnapRef.current) {
|
|
11477
|
+
delete objectResizeActiveSnapRef.current.left;
|
|
11478
|
+
delete objectResizeActiveSnapRef.current.right;
|
|
11479
|
+
delete objectResizeActiveSnapRef.current.width;
|
|
11480
|
+
}
|
|
11481
|
+
}
|
|
11482
|
+
if (yJump > maxSnapShift) {
|
|
11483
|
+
snapped.top = br.top;
|
|
11484
|
+
snapped.height = br.height;
|
|
11485
|
+
if (objectResizeActiveSnapRef.current) {
|
|
11486
|
+
delete objectResizeActiveSnapRef.current.top;
|
|
11487
|
+
delete objectResizeActiveSnapRef.current.bottom;
|
|
11488
|
+
delete objectResizeActiveSnapRef.current.height;
|
|
11489
|
+
}
|
|
11490
|
+
}
|
|
11491
|
+
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;
|
|
11492
|
+
if (obj instanceof fabric.Textbox && (corner === "ml" || corner === "mr")) {
|
|
11493
|
+
if (corner.includes("l") !== corner.includes("r")) {
|
|
11494
|
+
obj.set({ width: Math.max(20, snapped.width) });
|
|
11495
|
+
obj.initDimensions();
|
|
11496
|
+
obj.setCoords();
|
|
11497
|
+
const after2 = obj.getBoundingRect();
|
|
11498
|
+
obj.set({ left: (obj.left ?? 0) + (snapped.left - after2.left), top: (obj.top ?? 0) + (snapped.top - after2.top) });
|
|
11499
|
+
obj.setCoords();
|
|
11500
|
+
}
|
|
11501
|
+
return;
|
|
11502
|
+
}
|
|
11503
|
+
const baseW = obj.width ?? 1;
|
|
11504
|
+
const baseH = obj.height ?? 1;
|
|
11505
|
+
const signX = (obj.scaleX ?? 1) < 0 ? -1 : 1;
|
|
11506
|
+
const signY = (obj.scaleY ?? 1) < 0 ? -1 : 1;
|
|
11507
|
+
const newScaleX = snapped.width / Math.max(1, baseW) * signX;
|
|
11508
|
+
const newScaleY = snapped.height / Math.max(1, baseH) * signY;
|
|
11509
|
+
obj.set({ scaleX: newScaleX, scaleY: newScaleY });
|
|
11510
|
+
obj.setCoords();
|
|
11511
|
+
const after = obj.getBoundingRect();
|
|
11512
|
+
obj.set({ left: (obj.left ?? 0) + (snapped.left - after.left), top: (obj.top ?? 0) + (snapped.top - after.top) });
|
|
11513
|
+
obj.setCoords();
|
|
10174
11514
|
},
|
|
10175
|
-
[canvasWidth, canvasHeight,
|
|
11515
|
+
[canvasWidth, canvasHeight, getLogicalGroupSnapBoundsCallback, getResizeExcludeIdsCallback]
|
|
10176
11516
|
);
|
|
11517
|
+
const installImageResizeControlsWithSnap = useCallback((group) => {
|
|
11518
|
+
group.__resizeSnapHandler = (target, corner) => {
|
|
11519
|
+
const fc = fabricRef.current ?? target.canvas;
|
|
11520
|
+
if (!fc || !isActiveRef.current || !corner) return;
|
|
11521
|
+
fc.__isUserTransforming = true;
|
|
11522
|
+
didTransformRef.current = true;
|
|
11523
|
+
lastResizeScaleTargetRef.current = target;
|
|
11524
|
+
const targetId = getObjectId(target);
|
|
11525
|
+
if (targetId && targetId !== "__background__") {
|
|
11526
|
+
preserveSelectionAfterTransformIdRef.current = targetId;
|
|
11527
|
+
transformingIdsRef.current.add(targetId);
|
|
11528
|
+
}
|
|
11529
|
+
target.getObjects().forEach((member) => {
|
|
11530
|
+
const memberId = getObjectId(member);
|
|
11531
|
+
if (memberId) transformingIdsRef.current.add(memberId);
|
|
11532
|
+
});
|
|
11533
|
+
const gridGuidesForResize = [];
|
|
11534
|
+
try {
|
|
11535
|
+
target.setCoords();
|
|
11536
|
+
const br = target.getBoundingRect();
|
|
11537
|
+
const excludeIds = getResizeExcludeIdsCallback(target);
|
|
11538
|
+
const ps = projectSettingsRef.current;
|
|
11539
|
+
const snapThreshold = ps.snapThreshold || 4;
|
|
11540
|
+
const snapped = applyScaleSnapToBox(
|
|
11541
|
+
{ left: br.left, top: br.top, width: br.width, height: br.height },
|
|
11542
|
+
corner,
|
|
11543
|
+
fc,
|
|
11544
|
+
canvasWidth,
|
|
11545
|
+
canvasHeight,
|
|
11546
|
+
ps.snapToGuides,
|
|
11547
|
+
snapThreshold,
|
|
11548
|
+
targetId ?? void 0,
|
|
11549
|
+
{
|
|
11550
|
+
hysteresis: 3,
|
|
11551
|
+
activeSnapRef: objectResizeActiveSnapRef,
|
|
11552
|
+
roundSnappedOnly: true,
|
|
11553
|
+
additionalBounds: getLogicalGroupSnapBoundsCallback(excludeIds),
|
|
11554
|
+
excludeObjectIds: excludeIds,
|
|
11555
|
+
matchDimensions: true
|
|
11556
|
+
}
|
|
11557
|
+
);
|
|
11558
|
+
const maxSnapShift = Math.max(snapThreshold + 3, 10);
|
|
11559
|
+
const brRight = br.left + br.width;
|
|
11560
|
+
const brBottom = br.top + br.height;
|
|
11561
|
+
const snappedRight = snapped.left + snapped.width;
|
|
11562
|
+
const snappedBottom = snapped.top + snapped.height;
|
|
11563
|
+
const xJump = Math.max(Math.abs(snapped.left - br.left), Math.abs(snappedRight - brRight));
|
|
11564
|
+
const yJump = Math.max(Math.abs(snapped.top - br.top), Math.abs(snappedBottom - brBottom));
|
|
11565
|
+
if (xJump > maxSnapShift) {
|
|
11566
|
+
snapped.left = br.left;
|
|
11567
|
+
snapped.width = br.width;
|
|
11568
|
+
if (objectResizeActiveSnapRef.current) {
|
|
11569
|
+
delete objectResizeActiveSnapRef.current.left;
|
|
11570
|
+
delete objectResizeActiveSnapRef.current.right;
|
|
11571
|
+
delete objectResizeActiveSnapRef.current.width;
|
|
11572
|
+
}
|
|
11573
|
+
}
|
|
11574
|
+
if (yJump > maxSnapShift) {
|
|
11575
|
+
snapped.top = br.top;
|
|
11576
|
+
snapped.height = br.height;
|
|
11577
|
+
if (objectResizeActiveSnapRef.current) {
|
|
11578
|
+
delete objectResizeActiveSnapRef.current.top;
|
|
11579
|
+
delete objectResizeActiveSnapRef.current.bottom;
|
|
11580
|
+
delete objectResizeActiveSnapRef.current.height;
|
|
11581
|
+
}
|
|
11582
|
+
}
|
|
11583
|
+
const gridX = ps.gridSizeX ?? ps.gridSize ?? 0;
|
|
11584
|
+
const gridY = ps.gridSizeY ?? ps.gridSize ?? 0;
|
|
11585
|
+
if (ps.snapToGrid && gridX > 0 && gridY > 0) {
|
|
11586
|
+
const hasL = corner.includes("l");
|
|
11587
|
+
const hasR = corner.includes("r");
|
|
11588
|
+
const hasT = corner.includes("t");
|
|
11589
|
+
const hasB = corner.includes("b");
|
|
11590
|
+
const anchorRight = snapped.left + snapped.width;
|
|
11591
|
+
const anchorBottom = snapped.top + snapped.height;
|
|
11592
|
+
if (hasL) {
|
|
11593
|
+
const newLeft = Math.round(snapped.left / gridX) * gridX;
|
|
11594
|
+
const newWidth = Math.max(20, anchorRight - newLeft);
|
|
11595
|
+
snapped.left = anchorRight - newWidth;
|
|
11596
|
+
snapped.width = newWidth;
|
|
11597
|
+
gridGuidesForResize.push({ type: "vertical", position: snapped.left, kind: "grid" });
|
|
11598
|
+
} else if (hasR) {
|
|
11599
|
+
const newRight = Math.round(anchorRight / gridX) * gridX;
|
|
11600
|
+
snapped.width = Math.max(20, newRight - snapped.left);
|
|
11601
|
+
gridGuidesForResize.push({ type: "vertical", position: snapped.left + snapped.width, kind: "grid" });
|
|
11602
|
+
}
|
|
11603
|
+
if (hasT) {
|
|
11604
|
+
const newTop = Math.round(snapped.top / gridY) * gridY;
|
|
11605
|
+
const newHeight = Math.max(20, anchorBottom - newTop);
|
|
11606
|
+
snapped.top = anchorBottom - newHeight;
|
|
11607
|
+
snapped.height = newHeight;
|
|
11608
|
+
gridGuidesForResize.push({ type: "horizontal", position: snapped.top, kind: "grid" });
|
|
11609
|
+
} else if (hasB) {
|
|
11610
|
+
const newBottom = Math.round(anchorBottom / gridY) * gridY;
|
|
11611
|
+
snapped.height = Math.max(20, newBottom - snapped.top);
|
|
11612
|
+
gridGuidesForResize.push({ type: "horizontal", position: snapped.top + snapped.height, kind: "grid" });
|
|
11613
|
+
}
|
|
11614
|
+
}
|
|
11615
|
+
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;
|
|
11616
|
+
if (changed) {
|
|
11617
|
+
const ct = target.__cropData;
|
|
11618
|
+
if (ct) {
|
|
11619
|
+
const next = { ...snapped };
|
|
11620
|
+
const isCornerHandle = corner.includes("l") !== corner.includes("r") && corner.includes("t") !== corner.includes("b");
|
|
11621
|
+
const widthChanged = Math.abs(snapped.width - br.width) > 0.01;
|
|
11622
|
+
const heightChanged = Math.abs(snapped.height - br.height) > 0.01;
|
|
11623
|
+
if (isCornerHandle && br.width > 0 && br.height > 0 && widthChanged !== heightChanged) {
|
|
11624
|
+
const aspect = br.width / br.height;
|
|
11625
|
+
if (widthChanged) {
|
|
11626
|
+
next.height = Math.max(20, next.width / aspect);
|
|
11627
|
+
if (corner.includes("t")) next.top = br.top + br.height - next.height;
|
|
11628
|
+
} else {
|
|
11629
|
+
next.width = Math.max(20, next.height * aspect);
|
|
11630
|
+
if (corner.includes("l")) next.left = br.left + br.width - next.width;
|
|
11631
|
+
}
|
|
11632
|
+
} else if (isCornerHandle && br.width > 0 && br.height > 0) {
|
|
11633
|
+
const aspect = br.width / br.height;
|
|
11634
|
+
const nextAspect = next.width / Math.max(1, next.height);
|
|
11635
|
+
if (Math.abs(nextAspect - aspect) > 0.01) {
|
|
11636
|
+
const widthDelta = Math.abs(next.width - br.width);
|
|
11637
|
+
const heightDelta = Math.abs(next.height - br.height);
|
|
11638
|
+
if (widthDelta <= heightDelta) {
|
|
11639
|
+
next.height = Math.max(20, next.width / aspect);
|
|
11640
|
+
if (corner.includes("t")) next.top = br.top + br.height - next.height;
|
|
11641
|
+
} else {
|
|
11642
|
+
next.width = Math.max(20, next.height * aspect);
|
|
11643
|
+
if (corner.includes("l")) next.left = br.left + br.width - next.width;
|
|
11644
|
+
}
|
|
11645
|
+
}
|
|
11646
|
+
}
|
|
11647
|
+
ct.frameW = Math.max(20, next.width);
|
|
11648
|
+
ct.frameH = Math.max(20, next.height);
|
|
11649
|
+
target.set({
|
|
11650
|
+
left: next.left + ct.frameW / 2,
|
|
11651
|
+
top: next.top + ct.frameH / 2,
|
|
11652
|
+
width: ct.frameW,
|
|
11653
|
+
height: ct.frameH,
|
|
11654
|
+
scaleX: 1,
|
|
11655
|
+
scaleY: 1,
|
|
11656
|
+
originX: "center",
|
|
11657
|
+
originY: "center"
|
|
11658
|
+
});
|
|
11659
|
+
updateCoverLayout(target);
|
|
11660
|
+
}
|
|
11661
|
+
}
|
|
11662
|
+
} catch {
|
|
11663
|
+
snapDuringScaleCallback(target, corner);
|
|
11664
|
+
}
|
|
11665
|
+
try {
|
|
11666
|
+
target.setCoords();
|
|
11667
|
+
const br = target.getBoundingRect();
|
|
11668
|
+
setSizeLabel({
|
|
11669
|
+
width: Math.round(br.width),
|
|
11670
|
+
height: Math.round(br.height),
|
|
11671
|
+
x: br.left + br.width / 2,
|
|
11672
|
+
y: br.top + br.height + 18
|
|
11673
|
+
});
|
|
11674
|
+
} catch {
|
|
11675
|
+
}
|
|
11676
|
+
const smartGuides = calculateScaleSnapGuidesCallback(target, corner);
|
|
11677
|
+
setGuides(gridGuidesForResize.length ? [...smartGuides, ...gridGuidesForResize] : smartGuides);
|
|
11678
|
+
setHoverBounds(null);
|
|
11679
|
+
};
|
|
11680
|
+
installCanvaMaskControls(group);
|
|
11681
|
+
applyControlSizeForZoom(group.canvas ?? fabricRef.current, group);
|
|
11682
|
+
ensureCanvaControlRenders(group);
|
|
11683
|
+
}, [calculateScaleSnapGuidesCallback, canvasHeight, canvasWidth, getLogicalGroupSnapBoundsCallback, getResizeExcludeIdsCallback, snapDuringScaleCallback]);
|
|
10177
11684
|
const isTransforming = useCallback((canvas2) => {
|
|
10178
11685
|
if (!canvas2) return false;
|
|
10179
11686
|
return !!canvas2._currentTransform || !!canvas2.__isUserTransforming;
|
|
@@ -10299,6 +11806,8 @@ const PageCanvas = forwardRef(
|
|
|
10299
11806
|
// Transparent so underlay (page bg + group bgs) shows through
|
|
10300
11807
|
backgroundColor: "transparent"
|
|
10301
11808
|
});
|
|
11809
|
+
fabricCanvas.hoverCursor = "default";
|
|
11810
|
+
fabricCanvas.moveCursor = "move";
|
|
10302
11811
|
if (!allowSelection) {
|
|
10303
11812
|
fabricCanvas.selection = false;
|
|
10304
11813
|
fabricCanvas.on("selection:created", () => {
|
|
@@ -10320,6 +11829,61 @@ const PageCanvas = forwardRef(
|
|
|
10320
11829
|
fabricRef.current = fabricCanvas;
|
|
10321
11830
|
const storeRegistryKey = registerFabricCanvas(pageId, fabricCanvas);
|
|
10322
11831
|
fabricCanvas.__storeRegistryKey = storeRegistryKey;
|
|
11832
|
+
{
|
|
11833
|
+
const TWEEN_MS = 130;
|
|
11834
|
+
const active = /* @__PURE__ */ new Map();
|
|
11835
|
+
const ensureMap = (obj) => {
|
|
11836
|
+
if (!obj.__handleHoverProgress) obj.__handleHoverProgress = {};
|
|
11837
|
+
return obj.__handleHoverProgress;
|
|
11838
|
+
};
|
|
11839
|
+
const stateKey = (obj, key) => `${obj.__docuforgeId || ""}:${key}`;
|
|
11840
|
+
const step = (sk) => {
|
|
11841
|
+
const s = active.get(sk);
|
|
11842
|
+
if (!s) return;
|
|
11843
|
+
const t = Math.min(1, (performance.now() - s.start) / TWEEN_MS);
|
|
11844
|
+
const eased = 1 - Math.pow(1 - t, 3);
|
|
11845
|
+
const value = s.from + (s.to - s.from) * eased;
|
|
11846
|
+
const map = ensureMap(s.obj);
|
|
11847
|
+
map[s.key] = value;
|
|
11848
|
+
try {
|
|
11849
|
+
fabricCanvas.requestRenderAll();
|
|
11850
|
+
} catch {
|
|
11851
|
+
}
|
|
11852
|
+
if (t < 1) {
|
|
11853
|
+
s.raf = requestAnimationFrame(() => step(sk));
|
|
11854
|
+
} else {
|
|
11855
|
+
map[s.key] = s.to;
|
|
11856
|
+
active.delete(sk);
|
|
11857
|
+
}
|
|
11858
|
+
};
|
|
11859
|
+
const startTween = (obj, key, to) => {
|
|
11860
|
+
const sk = stateKey(obj, key);
|
|
11861
|
+
const map = ensureMap(obj);
|
|
11862
|
+
const from = map[key] ?? (to === 1 ? 0 : 1);
|
|
11863
|
+
if (from === to) return;
|
|
11864
|
+
const existing = active.get(sk);
|
|
11865
|
+
if (existing && existing.raf != null) cancelAnimationFrame(existing.raf);
|
|
11866
|
+
const s = { obj, key, start: performance.now(), from, to, raf: null };
|
|
11867
|
+
active.set(sk, s);
|
|
11868
|
+
s.raf = requestAnimationFrame(() => step(sk));
|
|
11869
|
+
};
|
|
11870
|
+
let prevTarget = null;
|
|
11871
|
+
let prevKey = null;
|
|
11872
|
+
fabricCanvas.on("mouse:move", (opt) => {
|
|
11873
|
+
const t = opt == null ? void 0 : opt.target;
|
|
11874
|
+
const key = t && t.__corner ? String(t.__corner) : null;
|
|
11875
|
+
if (t === prevTarget && key === prevKey) return;
|
|
11876
|
+
if (prevTarget && prevKey) startTween(prevTarget, prevKey, 0);
|
|
11877
|
+
if (t && key) startTween(t, key, 1);
|
|
11878
|
+
prevTarget = t;
|
|
11879
|
+
prevKey = key;
|
|
11880
|
+
});
|
|
11881
|
+
fabricCanvas.on("mouse:out", () => {
|
|
11882
|
+
if (prevTarget && prevKey) startTween(prevTarget, prevKey, 0);
|
|
11883
|
+
prevTarget = null;
|
|
11884
|
+
prevKey = null;
|
|
11885
|
+
});
|
|
11886
|
+
}
|
|
10323
11887
|
const initFonts = async () => {
|
|
10324
11888
|
try {
|
|
10325
11889
|
await preloadAllFonts();
|
|
@@ -10409,6 +11973,17 @@ const PageCanvas = forwardRef(
|
|
|
10409
11973
|
});
|
|
10410
11974
|
fabricCanvas.on("mouse:up", () => {
|
|
10411
11975
|
fabricCanvas.__isUserTransforming = false;
|
|
11976
|
+
objectResizeActiveSnapRef.current = null;
|
|
11977
|
+
groupResizeActiveSnapRef.current = null;
|
|
11978
|
+
try {
|
|
11979
|
+
for (const o of fabricCanvas.getObjects()) {
|
|
11980
|
+
if (o.__pixldocsDragMoved) o.__pixldocsDragMoved = false;
|
|
11981
|
+
}
|
|
11982
|
+
const active = fabricCanvas.getActiveObject();
|
|
11983
|
+
if (active == null ? void 0 : active.__pixldocsDragMoved) active.__pixldocsDragMoved = false;
|
|
11984
|
+
fabricCanvas.requestRenderAll();
|
|
11985
|
+
} catch {
|
|
11986
|
+
}
|
|
10412
11987
|
});
|
|
10413
11988
|
fabricCanvas.on("object:scaling", () => {
|
|
10414
11989
|
fabricCanvas.__isUserTransforming = true;
|
|
@@ -10455,7 +12030,7 @@ const PageCanvas = forwardRef(
|
|
|
10455
12030
|
didTransformRef.current = true;
|
|
10456
12031
|
});
|
|
10457
12032
|
const syncSelectionToStore = () => {
|
|
10458
|
-
var _a2,
|
|
12033
|
+
var _a2, _b2, _c, _d;
|
|
10459
12034
|
if (!isActiveRef.current || isRebuildingRef.current || isSyncingSelectionToFabricRef.current || !allowSelection) return;
|
|
10460
12035
|
const walkToTopmostGroup = (childId, children, activeEditingGroupId) => {
|
|
10461
12036
|
let topmost = null;
|
|
@@ -10494,7 +12069,7 @@ const PageCanvas = forwardRef(
|
|
|
10494
12069
|
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
10495
12070
|
const clickedId = ids[0];
|
|
10496
12071
|
const state = useEditorStore.getState();
|
|
10497
|
-
const currentPage2 = (
|
|
12072
|
+
const currentPage2 = (_b2 = state.canvas.pages) == null ? void 0 : _b2.find((p) => p.id === pageId);
|
|
10498
12073
|
const children = (currentPage2 == null ? void 0 : currentPage2.children) ?? [];
|
|
10499
12074
|
const parent = walkToTopmostGroup(clickedId, children, activeEditingGroupId);
|
|
10500
12075
|
const targetIsInCrop = !!(active instanceof fabric.Group && isCropGroupInCropMode(active) || (active == null ? void 0 : active.group) instanceof fabric.Group && isCropGroupInCropMode(active.group));
|
|
@@ -10641,8 +12216,10 @@ const PageCanvas = forwardRef(
|
|
|
10641
12216
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10642
12217
|
if (activeObj instanceof fabric.ActiveSelection) applyWarpAwareSelectionBorders(activeObj);
|
|
10643
12218
|
if (activeObj) applyControlSizeForZoom(fabricCanvas, activeObj);
|
|
12219
|
+
if (activeObj) ensureCanvaControlRenders(activeObj);
|
|
10644
12220
|
if (activeObj && !(activeObj instanceof fabric.ActiveSelection) && (((_a2 = activeObj._ct) == null ? void 0 : _a2.isCropGroup) || activeObj.__cropGroup)) {
|
|
10645
|
-
|
|
12221
|
+
installImageResizeControlsWithSnap(activeObj);
|
|
12222
|
+
ensureCanvaControlRenders(activeObj);
|
|
10646
12223
|
}
|
|
10647
12224
|
});
|
|
10648
12225
|
fabricCanvas.on("selection:updated", () => {
|
|
@@ -10654,12 +12231,14 @@ const PageCanvas = forwardRef(
|
|
|
10654
12231
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10655
12232
|
if (activeObj instanceof fabric.ActiveSelection) applyWarpAwareSelectionBorders(activeObj);
|
|
10656
12233
|
if (activeObj) applyControlSizeForZoom(fabricCanvas, activeObj);
|
|
12234
|
+
if (activeObj) ensureCanvaControlRenders(activeObj);
|
|
10657
12235
|
if (activeObj && !(activeObj instanceof fabric.ActiveSelection) && (((_a2 = activeObj._ct) == null ? void 0 : _a2.isCropGroup) || activeObj.__cropGroup)) {
|
|
10658
|
-
|
|
12236
|
+
installImageResizeControlsWithSnap(activeObj);
|
|
12237
|
+
ensureCanvaControlRenders(activeObj);
|
|
10659
12238
|
}
|
|
10660
12239
|
});
|
|
10661
12240
|
fabricCanvas.on("mouse:dblclick", (opt) => {
|
|
10662
|
-
var _a2,
|
|
12241
|
+
var _a2, _b2;
|
|
10663
12242
|
const target = opt == null ? void 0 : opt.target;
|
|
10664
12243
|
if (!target) return;
|
|
10665
12244
|
if (target.isEditing) return;
|
|
@@ -10683,7 +12262,7 @@ const PageCanvas = forwardRef(
|
|
|
10683
12262
|
const childId = getObjectId(hitChild);
|
|
10684
12263
|
if (!childId) return;
|
|
10685
12264
|
const stateNow = useEditorStore.getState();
|
|
10686
|
-
const pageNow = (
|
|
12265
|
+
const pageNow = (_b2 = stateNow.canvas.pages) == null ? void 0 : _b2.find((p) => p.id === pageId);
|
|
10687
12266
|
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
10688
12267
|
const chain = [];
|
|
10689
12268
|
{
|
|
@@ -10810,7 +12389,7 @@ const PageCanvas = forwardRef(
|
|
|
10810
12389
|
transformingIdsRef.current.clear();
|
|
10811
12390
|
};
|
|
10812
12391
|
const prepareGroupSelectionTransformStart = (target) => {
|
|
10813
|
-
var _a2,
|
|
12392
|
+
var _a2, _b2;
|
|
10814
12393
|
const active = target instanceof fabric.ActiveSelection ? target : fabricCanvas.getActiveObject();
|
|
10815
12394
|
if (!(active instanceof fabric.ActiveSelection)) return;
|
|
10816
12395
|
if (!activeSelectionMoveStartRef.current || activeSelectionMoveStartRef.current.selection !== active) {
|
|
@@ -10824,7 +12403,7 @@ const PageCanvas = forwardRef(
|
|
|
10824
12403
|
const groupId = active.__pixldocsGroupSelection;
|
|
10825
12404
|
if (!groupId) return;
|
|
10826
12405
|
if (((_a2 = groupSelectionTransformStartRef.current) == null ? void 0 : _a2.groupId) === groupId && groupSelectionTransformStartRef.current.selection === active) return;
|
|
10827
|
-
const pageChildren2 = ((
|
|
12406
|
+
const pageChildren2 = ((_b2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
|
|
10828
12407
|
const groupNode = findNodeById(pageChildren2, groupId);
|
|
10829
12408
|
if (!groupNode) return;
|
|
10830
12409
|
const groupAbs = getAbsoluteBounds(groupNode, pageChildren2);
|
|
@@ -10908,7 +12487,7 @@ const PageCanvas = forwardRef(
|
|
|
10908
12487
|
};
|
|
10909
12488
|
let pendingShiftMultiSelect = null;
|
|
10910
12489
|
const applyShiftMultiSelect = (target, event, baselineActive = fabricCanvas.getActiveObject(), baselineObjects = fabricCanvas.getActiveObjects()) => {
|
|
10911
|
-
var _a2,
|
|
12490
|
+
var _a2, _b2, _c;
|
|
10912
12491
|
if (!target || !target.selectable) return false;
|
|
10913
12492
|
const active = baselineActive;
|
|
10914
12493
|
if (!active || ((_a2 = active.getActiveControl) == null ? void 0 : _a2.call(active))) return false;
|
|
@@ -10942,7 +12521,7 @@ const PageCanvas = forwardRef(
|
|
|
10942
12521
|
isSyncingSelectionToFabricRef.current = false;
|
|
10943
12522
|
});
|
|
10944
12523
|
}
|
|
10945
|
-
(
|
|
12524
|
+
(_b2 = event == null ? void 0 : event.preventDefault) == null ? void 0 : _b2.call(event);
|
|
10946
12525
|
(_c = event == null ? void 0 : event.stopPropagation) == null ? void 0 : _c.call(event);
|
|
10947
12526
|
return true;
|
|
10948
12527
|
};
|
|
@@ -10993,9 +12572,9 @@ const PageCanvas = forwardRef(
|
|
|
10993
12572
|
return !!(((_a2 = o == null ? void 0 : o._ct) == null ? void 0 : _a2.isCropGroup) || (o == null ? void 0 : o.__cropGroup));
|
|
10994
12573
|
};
|
|
10995
12574
|
const promoteToCropGroup = (opt) => {
|
|
10996
|
-
var _a2,
|
|
12575
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
10997
12576
|
const t = opt.target;
|
|
10998
|
-
if (((_a2 = opt.e) == null ? void 0 : _a2.type) !== "mousedown" && ((
|
|
12577
|
+
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") {
|
|
10999
12578
|
if (t && isCropGroup2(t)) {
|
|
11000
12579
|
fabricCanvas._hoveredTarget = t;
|
|
11001
12580
|
} else if ((t == null ? void 0 : t.group) && isCropGroup2(t.group)) {
|
|
@@ -11011,6 +12590,8 @@ const PageCanvas = forwardRef(
|
|
|
11011
12590
|
const objects = fabricCanvas.getObjects();
|
|
11012
12591
|
for (const obj of objects) {
|
|
11013
12592
|
if (isCropGroup2(obj) && obj.containsPoint(pointer)) {
|
|
12593
|
+
installImageResizeControlsWithSnap(obj);
|
|
12594
|
+
ensureCanvaControlRenders(obj);
|
|
11014
12595
|
fabricCanvas.setActiveObject(obj);
|
|
11015
12596
|
opt.target = obj;
|
|
11016
12597
|
fabricCanvas._hoveredTarget = obj;
|
|
@@ -11021,12 +12602,16 @@ const PageCanvas = forwardRef(
|
|
|
11021
12602
|
}
|
|
11022
12603
|
const g = t.group;
|
|
11023
12604
|
if (g && isCropGroup2(g)) {
|
|
12605
|
+
installImageResizeControlsWithSnap(g);
|
|
12606
|
+
ensureCanvaControlRenders(g);
|
|
11024
12607
|
fabricCanvas.setActiveObject(g);
|
|
11025
12608
|
opt.target = g;
|
|
11026
12609
|
fabricCanvas._hoveredTarget = g;
|
|
11027
12610
|
return;
|
|
11028
12611
|
}
|
|
11029
12612
|
if (isCropGroup2(t)) {
|
|
12613
|
+
installImageResizeControlsWithSnap(t);
|
|
12614
|
+
ensureCanvaControlRenders(t);
|
|
11030
12615
|
fabricCanvas.setActiveObject(t);
|
|
11031
12616
|
t.set({
|
|
11032
12617
|
selectable: true,
|
|
@@ -11079,7 +12664,7 @@ const PageCanvas = forwardRef(
|
|
|
11079
12664
|
});
|
|
11080
12665
|
}
|
|
11081
12666
|
fabricCanvas.on("mouse:down", (opt) => {
|
|
11082
|
-
var _a2,
|
|
12667
|
+
var _a2, _b2;
|
|
11083
12668
|
if (pendingShiftMultiSelect) {
|
|
11084
12669
|
const pending = pendingShiftMultiSelect;
|
|
11085
12670
|
pendingShiftMultiSelect = null;
|
|
@@ -11087,17 +12672,19 @@ const PageCanvas = forwardRef(
|
|
|
11087
12672
|
return;
|
|
11088
12673
|
}
|
|
11089
12674
|
const target = opt.target;
|
|
11090
|
-
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) && (((
|
|
12675
|
+
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;
|
|
11091
12676
|
if (cropGroup) {
|
|
11092
12677
|
lockEdits();
|
|
11093
12678
|
didTransformRef.current = false;
|
|
12679
|
+
installImageResizeControlsWithSnap(cropGroup);
|
|
12680
|
+
ensureCanvaControlRenders(cropGroup);
|
|
11094
12681
|
fabricCanvas.setActiveObject(cropGroup);
|
|
11095
12682
|
cropGroup.setCoords();
|
|
11096
12683
|
fabricCanvas.requestRenderAll();
|
|
11097
12684
|
}
|
|
11098
12685
|
});
|
|
11099
12686
|
const groupFabricUnionBBox = (g) => {
|
|
11100
|
-
var _a2,
|
|
12687
|
+
var _a2, _b2;
|
|
11101
12688
|
const memberIds = new Set(getAllElementIds(g.children ?? []));
|
|
11102
12689
|
if (memberIds.size === 0) return null;
|
|
11103
12690
|
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
@@ -11105,7 +12692,7 @@ const PageCanvas = forwardRef(
|
|
|
11105
12692
|
for (const o of fabricCanvas.getObjects()) {
|
|
11106
12693
|
const oid = getObjectId(o);
|
|
11107
12694
|
if (!oid || !memberIds.has(oid)) continue;
|
|
11108
|
-
const br = ((_a2 = o.getBoundingRect) == null ? void 0 : _a2.call(o, true, true)) ?? ((
|
|
12695
|
+
const br = ((_a2 = o.getBoundingRect) == null ? void 0 : _a2.call(o, true, true)) ?? ((_b2 = o.getBoundingRect) == null ? void 0 : _b2.call(o));
|
|
11109
12696
|
if (!br) continue;
|
|
11110
12697
|
minX = Math.min(minX, br.left);
|
|
11111
12698
|
minY = Math.min(minY, br.top);
|
|
@@ -11131,13 +12718,13 @@ const PageCanvas = forwardRef(
|
|
|
11131
12718
|
return pick;
|
|
11132
12719
|
};
|
|
11133
12720
|
fabricCanvas.on("mouse:down:before", (opt) => {
|
|
11134
|
-
var _a2,
|
|
12721
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
|
|
11135
12722
|
if (editLockRef.current) {
|
|
11136
12723
|
const active = fabricCanvas.getActiveObject();
|
|
11137
12724
|
if (active && (((_a2 = active._ct) == null ? void 0 : _a2.isCropGroup) || active.__cropGroup)) {
|
|
11138
12725
|
opt.target = active;
|
|
11139
12726
|
if (opt.e) {
|
|
11140
|
-
(_c = (
|
|
12727
|
+
(_c = (_b2 = opt.e).preventDefault) == null ? void 0 : _c.call(_b2);
|
|
11141
12728
|
(_e = (_d = opt.e).stopPropagation) == null ? void 0 : _e.call(_d);
|
|
11142
12729
|
}
|
|
11143
12730
|
}
|
|
@@ -11152,6 +12739,10 @@ const PageCanvas = forwardRef(
|
|
|
11152
12739
|
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
11153
12740
|
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
11154
12741
|
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
12742
|
+
if (target instanceof fabric.Textbox && target.__corner && (target.__corner === "ml" || target.__corner === "mr")) {
|
|
12743
|
+
const sourceEl = targetId ? elementsRef.current.find((el) => el.id === targetId) : void 0;
|
|
12744
|
+
bakeTextboxScaleIntoTypography(target, sourceEl);
|
|
12745
|
+
}
|
|
11155
12746
|
if (isMultiSelectModifier(opt.e)) {
|
|
11156
12747
|
const manualTarget = target && !(target instanceof fabric.ActiveSelection) && targetId && targetId !== "__background__" ? target : pickSelectableObjectAtPointer(opt.e);
|
|
11157
12748
|
if (manualTarget) {
|
|
@@ -11178,11 +12769,39 @@ const PageCanvas = forwardRef(
|
|
|
11178
12769
|
return topmost;
|
|
11179
12770
|
};
|
|
11180
12771
|
if (target && targetId && targetId !== "__background__") {
|
|
11181
|
-
|
|
11182
|
-
|
|
12772
|
+
let effectiveTarget = target;
|
|
12773
|
+
let effectiveTargetId = targetId;
|
|
12774
|
+
const activeNowEarly = fabricCanvas.getActiveObject();
|
|
12775
|
+
const asGroupId = target instanceof fabric.ActiveSelection ? target.__pixldocsGroupSelection : void 0;
|
|
12776
|
+
if (target instanceof fabric.ActiveSelection && asGroupId && target === activeNowEarly) {
|
|
12777
|
+
try {
|
|
12778
|
+
const pointer = fabricCanvas.getViewportPoint(opt.e);
|
|
12779
|
+
const members = target.getObjects();
|
|
12780
|
+
for (let i = members.length - 1; i >= 0; i--) {
|
|
12781
|
+
const m = members[i];
|
|
12782
|
+
if (m.visible === false) continue;
|
|
12783
|
+
if (typeof m.containsPoint === "function" && m.containsPoint(pointer)) {
|
|
12784
|
+
const mid = getObjectId(m);
|
|
12785
|
+
if (mid) {
|
|
12786
|
+
effectiveTarget = m;
|
|
12787
|
+
effectiveTargetId = mid;
|
|
12788
|
+
}
|
|
12789
|
+
break;
|
|
12790
|
+
}
|
|
12791
|
+
}
|
|
12792
|
+
} catch {
|
|
12793
|
+
}
|
|
12794
|
+
}
|
|
12795
|
+
const parent = findTopmostPromotableGroup(effectiveTargetId);
|
|
12796
|
+
const targetIsInCrop = !!(effectiveTarget instanceof fabric.Group && isCropGroupInCropMode(effectiveTarget) || (effectiveTarget == null ? void 0 : effectiveTarget.group) instanceof fabric.Group && isCropGroupInCropMode(effectiveTarget.group));
|
|
11183
12797
|
const activeNow = fabricCanvas.getActiveObject();
|
|
11184
12798
|
const alreadyThisGroup = activeNow instanceof fabric.ActiveSelection && activeNow.__pixldocsGroupSelection === (parent == null ? void 0 : parent.id);
|
|
11185
12799
|
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));
|
|
12800
|
+
const isDeepSelectKey = !!((_i = opt.e) == null ? void 0 : _i.altKey);
|
|
12801
|
+
if (isDeepSelectKey) {
|
|
12802
|
+
pendingGroupPromotionRef.current = null;
|
|
12803
|
+
return;
|
|
12804
|
+
}
|
|
11186
12805
|
if (parent && !parent.backgroundColor && !targetIsInCrop && activeEditingGroupId !== parent.id && !alreadyThisGroup && !isMultiSelectKey) {
|
|
11187
12806
|
const memberIds = new Set(getAllElementIds(parent.children ?? []));
|
|
11188
12807
|
const memberObjs = fabricCanvas.getObjects().filter((o) => {
|
|
@@ -11206,10 +12825,33 @@ const PageCanvas = forwardRef(
|
|
|
11206
12825
|
opt.target = only;
|
|
11207
12826
|
pendingGroupPromotionRef.current = { groupId: parent.id, selection: only };
|
|
11208
12827
|
}
|
|
12828
|
+
} else if (parent && !parent.backgroundColor && !targetIsInCrop && alreadyThisGroup && !isMultiSelectKey && effectiveTarget !== activeNow) {
|
|
12829
|
+
try {
|
|
12830
|
+
skipSelectionClearOnDiscardRef.current = true;
|
|
12831
|
+
preserveEditingScopeOnSelectionClearRef.current = true;
|
|
12832
|
+
restoreSuppressedGroupBorders();
|
|
12833
|
+
fabricCanvas.discardActiveObject();
|
|
12834
|
+
} finally {
|
|
12835
|
+
skipSelectionClearOnDiscardRef.current = false;
|
|
12836
|
+
preserveEditingScopeOnSelectionClearRef.current = false;
|
|
12837
|
+
}
|
|
12838
|
+
fabricCanvas.__activeEditingGroupId = parent.id;
|
|
12839
|
+
delete effectiveTarget.__pixldocsGroupSelection;
|
|
12840
|
+
delete effectiveTarget.__pixldocsLogicalGroupIds;
|
|
12841
|
+
try {
|
|
12842
|
+
(_j = effectiveTarget.set) == null ? void 0 : _j.call(effectiveTarget, { selectable: true, evented: true, hasBorders: true, hasControls: true });
|
|
12843
|
+
} catch {
|
|
12844
|
+
}
|
|
12845
|
+
fabricCanvas.setActiveObject(effectiveTarget);
|
|
12846
|
+
effectiveTarget.setCoords();
|
|
12847
|
+
fabricCanvas._target = effectiveTarget;
|
|
12848
|
+
opt.target = effectiveTarget;
|
|
12849
|
+
pendingGroupPromotionRef.current = null;
|
|
11209
12850
|
}
|
|
11210
12851
|
} else if (!target || targetId === "__background__") {
|
|
11211
|
-
const isMultiSelectKey = !!(((
|
|
12852
|
+
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));
|
|
11212
12853
|
if (isMultiSelectKey) return;
|
|
12854
|
+
if ((_n = opt.e) == null ? void 0 : _n.altKey) return;
|
|
11213
12855
|
try {
|
|
11214
12856
|
const pointer = fabricCanvas.getPointer(opt.e);
|
|
11215
12857
|
const px = pointer.x;
|
|
@@ -11280,6 +12922,43 @@ const PageCanvas = forwardRef(
|
|
|
11280
12922
|
if (editLockRef.current) return;
|
|
11281
12923
|
const t = opt.target;
|
|
11282
12924
|
const tid = t ? getObjectId(t) : null;
|
|
12925
|
+
try {
|
|
12926
|
+
const activeIds = new Set(selectedIdsRef.current);
|
|
12927
|
+
const pointer = fabricCanvas.getPointer(opt.e);
|
|
12928
|
+
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
12929
|
+
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
12930
|
+
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
12931
|
+
const groupPick = pickGroupAtPointer(pointer.x, pointer.y, childrenNow, activeEditingGroupId);
|
|
12932
|
+
if (groupPick && !activeIds.has(groupPick.group.id)) {
|
|
12933
|
+
const b = groupFabricUnionBBox(groupPick.group);
|
|
12934
|
+
if (b) {
|
|
12935
|
+
setHoverBounds({
|
|
12936
|
+
left: b.left,
|
|
12937
|
+
top: b.top,
|
|
12938
|
+
width: b.right - b.left,
|
|
12939
|
+
height: b.bottom - b.top,
|
|
12940
|
+
angle: 0
|
|
12941
|
+
});
|
|
12942
|
+
return;
|
|
12943
|
+
}
|
|
12944
|
+
}
|
|
12945
|
+
const isHoveringSelected = !!(tid && activeIds.has(tid));
|
|
12946
|
+
if (t && tid && tid !== "__background__" && !isHoveringSelected) {
|
|
12947
|
+
t.setCoords();
|
|
12948
|
+
const br = t.getBoundingRect();
|
|
12949
|
+
setHoverBounds({
|
|
12950
|
+
left: br.left,
|
|
12951
|
+
top: br.top,
|
|
12952
|
+
width: br.width,
|
|
12953
|
+
height: br.height,
|
|
12954
|
+
angle: 0
|
|
12955
|
+
});
|
|
12956
|
+
} else {
|
|
12957
|
+
setHoverBounds(null);
|
|
12958
|
+
}
|
|
12959
|
+
} catch {
|
|
12960
|
+
setHoverBounds(null);
|
|
12961
|
+
}
|
|
11283
12962
|
if (t && tid && tid !== "__background__") return;
|
|
11284
12963
|
try {
|
|
11285
12964
|
const pointer = fabricCanvas.getPointer(opt.e);
|
|
@@ -11287,11 +12966,19 @@ const PageCanvas = forwardRef(
|
|
|
11287
12966
|
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
11288
12967
|
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
11289
12968
|
const pick = pickGroupAtPointer(pointer.x, pointer.y, childrenNow, activeEditingGroupId);
|
|
11290
|
-
fabricCanvas.defaultCursor =
|
|
12969
|
+
fabricCanvas.defaultCursor = "default";
|
|
11291
12970
|
} catch {
|
|
11292
12971
|
fabricCanvas.defaultCursor = "default";
|
|
11293
12972
|
}
|
|
11294
12973
|
});
|
|
12974
|
+
fabricCanvas.on("mouse:out", () => {
|
|
12975
|
+
setHoverBounds(null);
|
|
12976
|
+
});
|
|
12977
|
+
fabricCanvas.on("mouse:down", () => {
|
|
12978
|
+
setHoverBounds(null);
|
|
12979
|
+
});
|
|
12980
|
+
fabricCanvas.on("selection:created", () => setHoverBounds(null));
|
|
12981
|
+
fabricCanvas.on("selection:updated", () => setHoverBounds(null));
|
|
11295
12982
|
fabricCanvas.on("mouse:down", (ev) => {
|
|
11296
12983
|
if (fabricCanvas._currentTransform) {
|
|
11297
12984
|
lockEdits();
|
|
@@ -11307,6 +12994,8 @@ const PageCanvas = forwardRef(
|
|
|
11307
12994
|
setGuides([]);
|
|
11308
12995
|
setRotationLabel(null);
|
|
11309
12996
|
setSizeLabel(null);
|
|
12997
|
+
objectResizeActiveSnapRef.current = null;
|
|
12998
|
+
groupResizeActiveSnapRef.current = null;
|
|
11310
12999
|
dragStarted = false;
|
|
11311
13000
|
const pendingPromotion = pendingGroupPromotionRef.current;
|
|
11312
13001
|
pendingGroupPromotionRef.current = null;
|
|
@@ -11461,7 +13150,9 @@ const PageCanvas = forwardRef(
|
|
|
11461
13150
|
const intrH = obj.height ?? 1;
|
|
11462
13151
|
let newW = Math.max(1, intrW * Math.abs(sx));
|
|
11463
13152
|
let newH = Math.max(1, intrH * Math.abs(sy));
|
|
11464
|
-
if (obj instanceof fabric.
|
|
13153
|
+
if (obj instanceof fabric.Ellipse) {
|
|
13154
|
+
obj.set({ rx: newW / 2, ry: newH / 2 });
|
|
13155
|
+
} else if (obj instanceof fabric.Circle) {
|
|
11465
13156
|
const diameter = Math.max(1, Math.min(newW, newH));
|
|
11466
13157
|
newW = diameter;
|
|
11467
13158
|
newH = diameter;
|
|
@@ -11578,8 +13269,128 @@ const PageCanvas = forwardRef(
|
|
|
11578
13269
|
}
|
|
11579
13270
|
const transform = e.transform;
|
|
11580
13271
|
const corner = (transform == null ? void 0 : transform.corner) || "";
|
|
13272
|
+
if (obj instanceof fabric.ActiveSelection && (corner === "ml" || corner === "mr" || corner === "mt" || corner === "mb")) {
|
|
13273
|
+
const isXSide = corner === "ml" || corner === "mr";
|
|
13274
|
+
const sAxis = isXSide ? Math.abs(obj.scaleX ?? 1) : Math.abs(obj.scaleY ?? 1);
|
|
13275
|
+
if (sAxis > 1e-3) {
|
|
13276
|
+
for (const child of obj.getObjects()) {
|
|
13277
|
+
if (!(child instanceof fabric.Textbox)) continue;
|
|
13278
|
+
if (isXSide) {
|
|
13279
|
+
if (child.__asLiveOrigW == null) {
|
|
13280
|
+
child.__asLiveOrigW = (child.width ?? 0) * (child.scaleX ?? 1);
|
|
13281
|
+
}
|
|
13282
|
+
const origW = child.__asLiveOrigW;
|
|
13283
|
+
const newW = Math.max(20, origW * sAxis);
|
|
13284
|
+
if (Math.abs((child.width ?? 0) - newW) > 0.5) {
|
|
13285
|
+
child.set({ width: newW, scaleX: 1 / sAxis });
|
|
13286
|
+
try {
|
|
13287
|
+
child.initDimensions();
|
|
13288
|
+
} catch {
|
|
13289
|
+
}
|
|
13290
|
+
child.dirty = true;
|
|
13291
|
+
}
|
|
13292
|
+
} else {
|
|
13293
|
+
if (child.__asLiveOrigH == null) {
|
|
13294
|
+
child.__asLiveOrigH = (child.height ?? 0) * (child.scaleY ?? 1);
|
|
13295
|
+
}
|
|
13296
|
+
const origH = child.__asLiveOrigH;
|
|
13297
|
+
const newH = Math.max(20, origH * sAxis);
|
|
13298
|
+
child.minBoxHeight = newH;
|
|
13299
|
+
child.set({ scaleY: 1 / sAxis });
|
|
13300
|
+
try {
|
|
13301
|
+
child.initDimensions();
|
|
13302
|
+
} catch {
|
|
13303
|
+
}
|
|
13304
|
+
child.dirty = true;
|
|
13305
|
+
}
|
|
13306
|
+
}
|
|
13307
|
+
}
|
|
13308
|
+
}
|
|
13309
|
+
snapDuringScaleCallback(obj, corner);
|
|
11581
13310
|
const scaleGuides = calculateScaleSnapGuidesCallback(obj, corner);
|
|
11582
|
-
|
|
13311
|
+
const gridGuidesForScale = [];
|
|
13312
|
+
try {
|
|
13313
|
+
const psGrid = projectSettingsRef.current;
|
|
13314
|
+
const canApplyGridSnap = psGrid.snapToGrid && corner && !obj.__cropGroup && !obj.__resizeSnapHandler;
|
|
13315
|
+
if (canApplyGridSnap) {
|
|
13316
|
+
const gridX = psGrid.gridSizeX ?? psGrid.gridSize ?? 0;
|
|
13317
|
+
const gridY = psGrid.gridSizeY ?? psGrid.gridSize ?? 0;
|
|
13318
|
+
if (gridX > 0 && gridY > 0) {
|
|
13319
|
+
obj.setCoords();
|
|
13320
|
+
const br = obj.getBoundingRect();
|
|
13321
|
+
if (br.width > 1 && br.height > 1) {
|
|
13322
|
+
const hasL = corner.includes("l");
|
|
13323
|
+
const hasR = corner.includes("r");
|
|
13324
|
+
const hasT = corner.includes("t");
|
|
13325
|
+
const hasB = corner.includes("b");
|
|
13326
|
+
const anchorRight = br.left + br.width;
|
|
13327
|
+
const anchorBottom = br.top + br.height;
|
|
13328
|
+
let newLeft = br.left;
|
|
13329
|
+
let newTop = br.top;
|
|
13330
|
+
let newWidth = br.width;
|
|
13331
|
+
let newHeight = br.height;
|
|
13332
|
+
const xAlreadySnapped = scaleGuides.some((g) => g.type === "vertical");
|
|
13333
|
+
const yAlreadySnapped = scaleGuides.some((g) => g.type === "horizontal");
|
|
13334
|
+
if (!xAlreadySnapped) {
|
|
13335
|
+
if (hasL) {
|
|
13336
|
+
const nL = Math.round(br.left / gridX) * gridX;
|
|
13337
|
+
newWidth = Math.max(20, anchorRight - nL);
|
|
13338
|
+
newLeft = anchorRight - newWidth;
|
|
13339
|
+
} else if (hasR) {
|
|
13340
|
+
const nR = Math.round(anchorRight / gridX) * gridX;
|
|
13341
|
+
newWidth = Math.max(20, nR - br.left);
|
|
13342
|
+
}
|
|
13343
|
+
}
|
|
13344
|
+
if (!yAlreadySnapped) {
|
|
13345
|
+
if (hasT) {
|
|
13346
|
+
const nT = Math.round(br.top / gridY) * gridY;
|
|
13347
|
+
newHeight = Math.max(20, anchorBottom - nT);
|
|
13348
|
+
newTop = anchorBottom - newHeight;
|
|
13349
|
+
} else if (hasB) {
|
|
13350
|
+
const nB = Math.round(anchorBottom / gridY) * gridY;
|
|
13351
|
+
newHeight = Math.max(20, nB - br.top);
|
|
13352
|
+
}
|
|
13353
|
+
}
|
|
13354
|
+
const widthChanged = Math.abs(newWidth - br.width) > 0.5;
|
|
13355
|
+
const heightChanged = Math.abs(newHeight - br.height) > 0.5;
|
|
13356
|
+
if (widthChanged || heightChanged) {
|
|
13357
|
+
const isTextWidth = obj instanceof fabric.Textbox && widthChanged && !heightChanged;
|
|
13358
|
+
if (isTextWidth) {
|
|
13359
|
+
obj.set({ width: Math.max(20, newWidth) });
|
|
13360
|
+
try {
|
|
13361
|
+
obj.initDimensions();
|
|
13362
|
+
} catch {
|
|
13363
|
+
}
|
|
13364
|
+
} else {
|
|
13365
|
+
const ratioX = widthChanged ? newWidth / br.width : 1;
|
|
13366
|
+
const ratioY = heightChanged ? newHeight / br.height : 1;
|
|
13367
|
+
const curSx = obj.scaleX ?? 1;
|
|
13368
|
+
const curSy = obj.scaleY ?? 1;
|
|
13369
|
+
obj.set({ scaleX: curSx * ratioX, scaleY: curSy * ratioY });
|
|
13370
|
+
}
|
|
13371
|
+
obj.setCoords();
|
|
13372
|
+
const after = obj.getBoundingRect();
|
|
13373
|
+
const dx = newLeft - after.left;
|
|
13374
|
+
const dy = newTop - after.top;
|
|
13375
|
+
if (Math.abs(dx) > 0.01 || Math.abs(dy) > 0.01) {
|
|
13376
|
+
obj.set({ left: (obj.left ?? 0) + dx, top: (obj.top ?? 0) + dy });
|
|
13377
|
+
obj.setCoords();
|
|
13378
|
+
}
|
|
13379
|
+
if (!xAlreadySnapped) {
|
|
13380
|
+
if (hasL) gridGuidesForScale.push({ type: "vertical", position: newLeft, kind: "grid" });
|
|
13381
|
+
else if (hasR) gridGuidesForScale.push({ type: "vertical", position: newLeft + newWidth, kind: "grid" });
|
|
13382
|
+
}
|
|
13383
|
+
if (!yAlreadySnapped) {
|
|
13384
|
+
if (hasT) gridGuidesForScale.push({ type: "horizontal", position: newTop, kind: "grid" });
|
|
13385
|
+
else if (hasB) gridGuidesForScale.push({ type: "horizontal", position: newTop + newHeight, kind: "grid" });
|
|
13386
|
+
}
|
|
13387
|
+
}
|
|
13388
|
+
}
|
|
13389
|
+
}
|
|
13390
|
+
}
|
|
13391
|
+
} catch {
|
|
13392
|
+
}
|
|
13393
|
+
setGuides(gridGuidesForScale.length ? [...scaleGuides, ...gridGuidesForScale] : scaleGuides);
|
|
11583
13394
|
});
|
|
11584
13395
|
fabricCanvas.on("object:resizing", (e) => {
|
|
11585
13396
|
if (!isActiveRef.current) return;
|
|
@@ -11605,13 +13416,70 @@ const PageCanvas = forwardRef(
|
|
|
11605
13416
|
}
|
|
11606
13417
|
const transform = e.transform;
|
|
11607
13418
|
const corner = (transform == null ? void 0 : transform.corner) || "";
|
|
13419
|
+
if (obj instanceof fabric.Textbox && (corner === "ml" || corner === "mr")) {
|
|
13420
|
+
const objId = getObjectId(obj);
|
|
13421
|
+
const sourceEl = objId ? elementsRef.current.find((el) => el.id === objId) : void 0;
|
|
13422
|
+
bakeTextboxScaleIntoTypography(obj, sourceEl);
|
|
13423
|
+
}
|
|
13424
|
+
snapDuringScaleCallback(obj, corner);
|
|
11608
13425
|
const scaleGuides = calculateScaleSnapGuidesCallback(obj, corner);
|
|
11609
|
-
|
|
13426
|
+
const gridGuidesForTextResize = [];
|
|
13427
|
+
try {
|
|
13428
|
+
const psGrid = projectSettingsRef.current;
|
|
13429
|
+
if (psGrid.snapToGrid && corner && obj instanceof fabric.Textbox && (corner === "ml" || corner === "mr")) {
|
|
13430
|
+
const gridX = psGrid.gridSizeX ?? psGrid.gridSize ?? 0;
|
|
13431
|
+
if (gridX > 0) {
|
|
13432
|
+
obj.setCoords();
|
|
13433
|
+
const br = obj.getBoundingRect();
|
|
13434
|
+
const xAlreadySnapped = scaleGuides.some((g) => g.type === "vertical");
|
|
13435
|
+
if (!xAlreadySnapped && br.width > 1) {
|
|
13436
|
+
const anchorRight = br.left + br.width;
|
|
13437
|
+
let newLeft = br.left;
|
|
13438
|
+
let newWidth = br.width;
|
|
13439
|
+
if (corner === "ml") {
|
|
13440
|
+
const nL = Math.round(br.left / gridX) * gridX;
|
|
13441
|
+
newWidth = Math.max(20, anchorRight - nL);
|
|
13442
|
+
newLeft = anchorRight - newWidth;
|
|
13443
|
+
} else {
|
|
13444
|
+
const nR = Math.round(anchorRight / gridX) * gridX;
|
|
13445
|
+
newWidth = Math.max(20, nR - br.left);
|
|
13446
|
+
}
|
|
13447
|
+
if (Math.abs(newWidth - br.width) > 0.5) {
|
|
13448
|
+
obj.set({ width: Math.max(20, newWidth) });
|
|
13449
|
+
try {
|
|
13450
|
+
obj.initDimensions();
|
|
13451
|
+
} catch {
|
|
13452
|
+
}
|
|
13453
|
+
obj.setCoords();
|
|
13454
|
+
const after = obj.getBoundingRect();
|
|
13455
|
+
const dx = newLeft - after.left;
|
|
13456
|
+
if (Math.abs(dx) > 0.01) {
|
|
13457
|
+
obj.set({ left: (obj.left ?? 0) + dx });
|
|
13458
|
+
obj.setCoords();
|
|
13459
|
+
}
|
|
13460
|
+
gridGuidesForTextResize.push({
|
|
13461
|
+
type: "vertical",
|
|
13462
|
+
position: corner === "ml" ? newLeft : newLeft + newWidth,
|
|
13463
|
+
kind: "grid"
|
|
13464
|
+
});
|
|
13465
|
+
}
|
|
13466
|
+
}
|
|
13467
|
+
}
|
|
13468
|
+
}
|
|
13469
|
+
} catch {
|
|
13470
|
+
}
|
|
13471
|
+
setGuides(gridGuidesForTextResize.length ? [...scaleGuides, ...gridGuidesForTextResize] : scaleGuides);
|
|
11610
13472
|
});
|
|
11611
13473
|
fabricCanvas.on("object:rotating", (e) => {
|
|
11612
13474
|
markSimpleTransform(e);
|
|
11613
13475
|
didTransformRef.current = true;
|
|
11614
13476
|
const tr = e.target;
|
|
13477
|
+
try {
|
|
13478
|
+
const getCursor = fabricCanvas.__pixldocsGetRotateCursor;
|
|
13479
|
+
const upper = fabricCanvas.upperCanvasEl;
|
|
13480
|
+
if (typeof getCursor === "function" && upper && tr) upper.style.cursor = getCursor(tr);
|
|
13481
|
+
} catch {
|
|
13482
|
+
}
|
|
11615
13483
|
const rotateTargetId = tr ? getObjectId(tr) : null;
|
|
11616
13484
|
if (rotateTargetId && rotateTargetId !== "__background__") {
|
|
11617
13485
|
preserveSelectionAfterTransformIdRef.current = rotateTargetId;
|
|
@@ -11638,6 +13506,7 @@ const PageCanvas = forwardRef(
|
|
|
11638
13506
|
prepareGroupSelectionTransformStart(e.target);
|
|
11639
13507
|
markTransforming(e.target);
|
|
11640
13508
|
didTransformRef.current = true;
|
|
13509
|
+
if (e.target) e.target.__pixldocsDragMoved = true;
|
|
11641
13510
|
const moveTargetId = e.target ? getObjectId(e.target) : null;
|
|
11642
13511
|
if (moveTargetId && moveTargetId !== "__background__") {
|
|
11643
13512
|
preserveSelectionAfterTransformIdRef.current = moveTargetId;
|
|
@@ -11654,19 +13523,57 @@ const PageCanvas = forwardRef(
|
|
|
11654
13523
|
if (!obj) return;
|
|
11655
13524
|
const snapTarget = fabricCanvas.getActiveObject() ?? obj;
|
|
11656
13525
|
const { guides: newGuides, snapDx, snapDy } = calculateSnapGuidesCallback(snapTarget);
|
|
11657
|
-
|
|
11658
|
-
|
|
11659
|
-
|
|
13526
|
+
let finalDx = snapDx;
|
|
13527
|
+
let finalDy = snapDy;
|
|
13528
|
+
let mergedGuides = newGuides;
|
|
13529
|
+
const psLive = projectSettingsRef.current;
|
|
13530
|
+
const gridX = psLive.gridSizeX ?? psLive.gridSize ?? 0;
|
|
13531
|
+
const gridY = psLive.gridSizeY ?? psLive.gridSize ?? 0;
|
|
13532
|
+
if (psLive.snapToGrid && gridX > 0 && gridY > 0) {
|
|
13533
|
+
try {
|
|
13534
|
+
snapTarget.setCoords();
|
|
13535
|
+
} catch {
|
|
13536
|
+
}
|
|
13537
|
+
const br = snapTarget.getBoundingRect();
|
|
13538
|
+
const gridGuides = [];
|
|
13539
|
+
if (finalDx === 0) {
|
|
13540
|
+
const newLeft = Math.round(br.left / gridX) * gridX;
|
|
13541
|
+
finalDx = newLeft - br.left;
|
|
13542
|
+
gridGuides.push({ type: "vertical", position: newLeft, kind: "grid" });
|
|
13543
|
+
}
|
|
13544
|
+
if (finalDy === 0) {
|
|
13545
|
+
const newTop = Math.round(br.top / gridY) * gridY;
|
|
13546
|
+
finalDy = newTop - br.top;
|
|
13547
|
+
gridGuides.push({ type: "horizontal", position: newTop, kind: "grid" });
|
|
13548
|
+
}
|
|
13549
|
+
if (gridGuides.length) mergedGuides = [...newGuides, ...gridGuides];
|
|
13550
|
+
}
|
|
13551
|
+
setGuides(mergedGuides);
|
|
13552
|
+
setHoverBounds(null);
|
|
13553
|
+
if (finalDx !== 0 || finalDy !== 0) {
|
|
13554
|
+
snapTarget.set({ left: (snapTarget.left ?? 0) + finalDx, top: (snapTarget.top ?? 0) + finalDy });
|
|
11660
13555
|
}
|
|
11661
13556
|
});
|
|
11662
13557
|
let cropGroupSaveTimer = null;
|
|
11663
13558
|
fabricCanvas.on("object:modified", (e) => {
|
|
11664
|
-
var _a2,
|
|
13559
|
+
var _a2, _b2, _c, _d, _e, _f, _g;
|
|
11665
13560
|
try {
|
|
11666
13561
|
dragStarted = false;
|
|
11667
13562
|
setGuides([]);
|
|
11668
13563
|
setGroupOverlayLiveBoundsRef.current(null);
|
|
13564
|
+
objectResizeActiveSnapRef.current = null;
|
|
13565
|
+
groupResizeActiveSnapRef.current = null;
|
|
11669
13566
|
onDragEnd == null ? void 0 : onDragEnd();
|
|
13567
|
+
try {
|
|
13568
|
+
const t = e.target;
|
|
13569
|
+
if (t instanceof fabric.ActiveSelection) {
|
|
13570
|
+
for (const child of t.getObjects()) {
|
|
13571
|
+
delete child.__asLiveOrigW;
|
|
13572
|
+
delete child.__asLiveOrigH;
|
|
13573
|
+
}
|
|
13574
|
+
}
|
|
13575
|
+
} catch {
|
|
13576
|
+
}
|
|
11670
13577
|
lockEdits();
|
|
11671
13578
|
const modifiedTarget = e.target;
|
|
11672
13579
|
const modifiedTargetId = modifiedTarget ? getObjectId(modifiedTarget) : null;
|
|
@@ -11775,7 +13682,7 @@ const PageCanvas = forwardRef(
|
|
|
11775
13682
|
useEditorStore.getState().reflowStackGroupInPage(pageId, groupId);
|
|
11776
13683
|
}
|
|
11777
13684
|
const stateAfter = useEditorStore.getState();
|
|
11778
|
-
const pageAfter = ((
|
|
13685
|
+
const pageAfter = ((_b2 = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
|
|
11779
13686
|
const groupNodeAfter = findNodeById(pageAfter, groupId);
|
|
11780
13687
|
if (groupNodeAfter) {
|
|
11781
13688
|
const abs = getAbsoluteBounds(groupNodeAfter, pageAfter);
|
|
@@ -11802,11 +13709,11 @@ const PageCanvas = forwardRef(
|
|
|
11802
13709
|
clearTimeout(cropGroupSaveTimer);
|
|
11803
13710
|
}
|
|
11804
13711
|
cropGroupSaveTimer = setTimeout(() => {
|
|
11805
|
-
var _a3,
|
|
13712
|
+
var _a3, _b3, _c2;
|
|
11806
13713
|
const { updateElement: updateElement2 } = useEditorStore.getState();
|
|
11807
13714
|
const img = ct._img;
|
|
11808
13715
|
const zoom3 = ((_a3 = img == null ? void 0 : img._ct) == null ? void 0 : _a3.zoom) ?? 1;
|
|
11809
|
-
const panX = ((
|
|
13716
|
+
const panX = ((_b3 = img == null ? void 0 : img._ct) == null ? void 0 : _b3.panX) ?? 0.5;
|
|
11810
13717
|
const panY = ((_c2 = img == null ? void 0 : img._ct) == null ? void 0 : _c2.panY) ?? 0.5;
|
|
11811
13718
|
const stateCrop = useEditorStore.getState();
|
|
11812
13719
|
const pageCrop = stateCrop.canvas.pages.find((p) => p.id === pageId);
|
|
@@ -11825,6 +13732,8 @@ const PageCanvas = forwardRef(
|
|
|
11825
13732
|
cropZoom: zoom3
|
|
11826
13733
|
}, { recordHistory: false });
|
|
11827
13734
|
active.__isInternalCropUpdate = false;
|
|
13735
|
+
installImageResizeControlsWithSnap(active);
|
|
13736
|
+
ensureCanvaControlRenders(active);
|
|
11828
13737
|
fabricCanvas.setActiveObject(active);
|
|
11829
13738
|
setTimeout(() => justModifiedIdsRef.current.delete(objId), 150);
|
|
11830
13739
|
}, 0);
|
|
@@ -12078,6 +13987,10 @@ const PageCanvas = forwardRef(
|
|
|
12078
13987
|
for (const obj of activeObjects) {
|
|
12079
13988
|
const objId = getObjectId(obj);
|
|
12080
13989
|
if (!objId || objId === "__background__") continue;
|
|
13990
|
+
const sourceElement = elementsRef.current.find((el) => el.id === objId);
|
|
13991
|
+
if (obj instanceof fabric.Textbox && !isActiveSelection) {
|
|
13992
|
+
bakeTextboxScaleIntoTypography(obj, sourceElement);
|
|
13993
|
+
}
|
|
12081
13994
|
let intrinsicWidth;
|
|
12082
13995
|
let intrinsicHeight;
|
|
12083
13996
|
if (obj instanceof fabric.Circle) {
|
|
@@ -12144,7 +14057,6 @@ const PageCanvas = forwardRef(
|
|
|
12144
14057
|
absoluteLeft = (absoluteLeft ?? 0) - w / 2;
|
|
12145
14058
|
absoluteTop = (absoluteTop ?? 0) - h / 2;
|
|
12146
14059
|
}
|
|
12147
|
-
const sourceElement = elementsRef.current.find((el) => el.id === objId);
|
|
12148
14060
|
const preserveCornerGeometry = (sourceElement == null ? void 0 : sourceElement.type) === "shape" && (sourceElement.shapeType === "circle" || sourceElement.shapeType === "rounded-rect" || sourceElement.shapeType === "triangle");
|
|
12149
14061
|
let finalWidth = intrinsicWidth;
|
|
12150
14062
|
let finalHeight = intrinsicHeight;
|
|
@@ -12230,17 +14142,35 @@ const PageCanvas = forwardRef(
|
|
|
12230
14142
|
finalHeight = 0;
|
|
12231
14143
|
finalScaleX = 1;
|
|
12232
14144
|
finalScaleY = 1;
|
|
14145
|
+
} else if (obj instanceof fabric.Textbox && isActiveSelection && (Math.abs((decomposed.scaleX ?? 1) - 1) > 1e-3 || Math.abs((decomposed.scaleY ?? 1) - 1) > 1e-3)) {
|
|
14146
|
+
const sx = Math.abs(decomposed.scaleX || 1);
|
|
14147
|
+
const sy = Math.abs(decomposed.scaleY || 1);
|
|
14148
|
+
const bakedWidth = Math.max(20, intrinsicWidth * sx);
|
|
14149
|
+
const bakedHeight = Math.max(1, intrinsicHeight * sy);
|
|
14150
|
+
finalWidth = bakedWidth;
|
|
14151
|
+
finalHeight = bakedHeight;
|
|
14152
|
+
finalScaleX = 1;
|
|
14153
|
+
finalScaleY = 1;
|
|
14154
|
+
try {
|
|
14155
|
+
obj.set({ width: bakedWidth, scaleX: 1, scaleY: 1 });
|
|
14156
|
+
obj.initDimensions();
|
|
14157
|
+
obj.setCoords();
|
|
14158
|
+
} catch {
|
|
14159
|
+
}
|
|
14160
|
+
finalAbsoluteMatrix = fabric.util.composeMatrix({
|
|
14161
|
+
translateX: decomposed.translateX,
|
|
14162
|
+
translateY: decomposed.translateY,
|
|
14163
|
+
angle: decomposed.angle ?? 0,
|
|
14164
|
+
scaleX: 1,
|
|
14165
|
+
scaleY: 1,
|
|
14166
|
+
skewX: 0,
|
|
14167
|
+
skewY: 0
|
|
14168
|
+
});
|
|
12233
14169
|
} else if (preserveCornerGeometry) {
|
|
12234
14170
|
const scaledW = Math.max(1, intrinsicWidth * Math.abs(decomposed.scaleX || 1));
|
|
12235
14171
|
const scaledH = Math.max(1, intrinsicHeight * Math.abs(decomposed.scaleY || 1));
|
|
12236
|
-
|
|
12237
|
-
|
|
12238
|
-
finalWidth = diameter;
|
|
12239
|
-
finalHeight = diameter;
|
|
12240
|
-
} else {
|
|
12241
|
-
finalWidth = scaledW;
|
|
12242
|
-
finalHeight = scaledH;
|
|
12243
|
-
}
|
|
14172
|
+
finalWidth = scaledW;
|
|
14173
|
+
finalHeight = scaledH;
|
|
12244
14174
|
finalScaleX = 1;
|
|
12245
14175
|
finalScaleY = 1;
|
|
12246
14176
|
obj.set({ scaleX: 1, scaleY: 1 });
|
|
@@ -12279,6 +14209,11 @@ const PageCanvas = forwardRef(
|
|
|
12279
14209
|
transformMatrix: finalAbsoluteMatrix
|
|
12280
14210
|
};
|
|
12281
14211
|
if (obj instanceof fabric.Textbox) {
|
|
14212
|
+
const bakedTextScaleUpdates = obj.__pixldocsBakedTextScaleUpdates;
|
|
14213
|
+
if (bakedTextScaleUpdates && typeof bakedTextScaleUpdates === "object") {
|
|
14214
|
+
Object.assign(elementUpdate, bakedTextScaleUpdates);
|
|
14215
|
+
delete obj.__pixldocsBakedTextScaleUpdates;
|
|
14216
|
+
}
|
|
12282
14217
|
const baked = obj.minBoxHeight;
|
|
12283
14218
|
if (typeof baked === "number" && baked > 0) {
|
|
12284
14219
|
elementUpdate.minBoxHeight = baked;
|
|
@@ -12387,7 +14322,7 @@ const PageCanvas = forwardRef(
|
|
|
12387
14322
|
}
|
|
12388
14323
|
});
|
|
12389
14324
|
fabricCanvas.on("mouse:dblclick", (e) => {
|
|
12390
|
-
var _a2,
|
|
14325
|
+
var _a2, _b2;
|
|
12391
14326
|
if (!isActiveRef.current || !allowEditing) return;
|
|
12392
14327
|
let target = e.target;
|
|
12393
14328
|
if (!target) {
|
|
@@ -12397,7 +14332,7 @@ const PageCanvas = forwardRef(
|
|
|
12397
14332
|
if (target && target instanceof fabric.Group && target.__cropGroup) {
|
|
12398
14333
|
const ct = target.__cropData;
|
|
12399
14334
|
const innerImg = ct == null ? void 0 : ct._img;
|
|
12400
|
-
const innerSrc = ((_a2 = innerImg == null ? void 0 : innerImg.getSrc) == null ? void 0 : _a2.call(innerImg)) || ((
|
|
14335
|
+
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) || "";
|
|
12401
14336
|
const isPlaceholder = !innerSrc || innerSrc === EMPTY_IMAGE_PLACEHOLDER_DATA_URL;
|
|
12402
14337
|
if (innerImg && !isPlaceholder && !isCropGroupInCropMode(target)) {
|
|
12403
14338
|
enterCropMode(target);
|
|
@@ -12576,13 +14511,13 @@ const PageCanvas = forwardRef(
|
|
|
12576
14511
|
visibilityUpdateInProgressRef.current = false;
|
|
12577
14512
|
}
|
|
12578
14513
|
doSyncRef.current = () => {
|
|
12579
|
-
var _a2,
|
|
14514
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
12580
14515
|
const shouldSkipUpdates2 = syncLockedRef.current || editLockRef.current;
|
|
12581
14516
|
const state = useEditorStore.getState();
|
|
12582
14517
|
const elementsToSync = elements;
|
|
12583
14518
|
elementsRef.current = elementsToSync;
|
|
12584
14519
|
const pageTree = isPreviewMode && (pageChildren == null ? void 0 : pageChildren.length) ? pageChildren ?? [] : ((_a2 = state.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
|
|
12585
|
-
const selectedIdsFromStore = new Set(((
|
|
14520
|
+
const selectedIdsFromStore = new Set(((_b2 = state.canvas) == null ? void 0 : _b2.selectedIds) ?? []);
|
|
12586
14521
|
isRebuildingRef.current = true;
|
|
12587
14522
|
const allElementIds = new Set(elementsToSync.map((el) => el.id));
|
|
12588
14523
|
const sectionGroups = pageTree.filter(
|
|
@@ -12609,7 +14544,8 @@ const PageCanvas = forwardRef(
|
|
|
12609
14544
|
const activeObj = fc.getActiveObject();
|
|
12610
14545
|
const activeObjId = activeObj ? getObjectId(activeObj) : null;
|
|
12611
14546
|
const isTextBeingEdited = activeObjId && editingTextIdRef.current === activeObjId;
|
|
12612
|
-
|
|
14547
|
+
const isMultiSelect = activeObj instanceof fabric.ActiveSelection;
|
|
14548
|
+
if (activeObj && isMultiSelect && !(((_c = activeObj._ct) == null ? void 0 : _c.isCropGroup) || activeObj.__cropGroup) && !isTextBeingEdited) {
|
|
12613
14549
|
fc.discardActiveObject();
|
|
12614
14550
|
}
|
|
12615
14551
|
}
|
|
@@ -12929,7 +14865,7 @@ const PageCanvas = forwardRef(
|
|
|
12929
14865
|
updateCoverLayout(existingObj);
|
|
12930
14866
|
applyEdgeFadeFrameClipPath(existingObj, element, ct.frameW, ct.frameH, ct.shape || "rect", ct.rx || 0);
|
|
12931
14867
|
if (allowEditing) {
|
|
12932
|
-
|
|
14868
|
+
installImageResizeControlsWithSnap(existingObj);
|
|
12933
14869
|
} else {
|
|
12934
14870
|
existingObj.set({
|
|
12935
14871
|
hasControls: false,
|
|
@@ -13011,7 +14947,7 @@ const PageCanvas = forwardRef(
|
|
|
13011
14947
|
hoverCursor: isDynamicField && isPreviewMode ? "pointer" : void 0
|
|
13012
14948
|
});
|
|
13013
14949
|
if (allowEditing) {
|
|
13014
|
-
|
|
14950
|
+
installImageResizeControlsWithSnap(existingObj);
|
|
13015
14951
|
}
|
|
13016
14952
|
existingObj.setCoords();
|
|
13017
14953
|
fc.requestRenderAll();
|
|
@@ -13737,7 +15673,7 @@ const PageCanvas = forwardRef(
|
|
|
13737
15673
|
return unsub;
|
|
13738
15674
|
}, []);
|
|
13739
15675
|
const updateFabricObject = (obj, element, skipPositionUpdate = false) => {
|
|
13740
|
-
var _a2,
|
|
15676
|
+
var _a2, _b2, _c;
|
|
13741
15677
|
const fc = fabricRef.current;
|
|
13742
15678
|
if (fc && isTransforming(fc)) {
|
|
13743
15679
|
return;
|
|
@@ -13805,11 +15741,12 @@ const PageCanvas = forwardRef(
|
|
|
13805
15741
|
// Disable rotation for crop groups (simplifies resize math)
|
|
13806
15742
|
hasRotatingPoint: false,
|
|
13807
15743
|
// Hide rotation handle
|
|
13808
|
-
//
|
|
13809
|
-
|
|
13810
|
-
|
|
15744
|
+
// Handles are drawn in screen-space — keep them constant on-screen.
|
|
15745
|
+
// Match the global Canva-style defaults (circular dots, pill sides).
|
|
15746
|
+
cornerSize: 10,
|
|
15747
|
+
borderScaleFactor: SELECTION_BORDER_SCALE,
|
|
13811
15748
|
transparentCorners: false,
|
|
13812
|
-
cornerStyle: "
|
|
15749
|
+
cornerStyle: "circle",
|
|
13813
15750
|
cornerColor: SELECTION_PRIMARY,
|
|
13814
15751
|
cornerStrokeColor: "#ffffff",
|
|
13815
15752
|
borderColor: SELECTION_PRIMARY,
|
|
@@ -13919,7 +15856,8 @@ const PageCanvas = forwardRef(
|
|
|
13919
15856
|
obj.clipPath.dirty = true;
|
|
13920
15857
|
obj.clipPath.setCoords();
|
|
13921
15858
|
}
|
|
13922
|
-
|
|
15859
|
+
installImageResizeControlsWithSnap(obj);
|
|
15860
|
+
ensureCanvaControlRenders(obj);
|
|
13923
15861
|
obj.set({
|
|
13924
15862
|
selectable: true,
|
|
13925
15863
|
evented: true,
|
|
@@ -14014,7 +15952,7 @@ const PageCanvas = forwardRef(
|
|
|
14014
15952
|
obj.setCoords();
|
|
14015
15953
|
}
|
|
14016
15954
|
if (!isLine) {
|
|
14017
|
-
const angleTextPathActive = isTextbox && ((
|
|
15955
|
+
const angleTextPathActive = isTextbox && ((_b2 = element.textPath) == null ? void 0 : _b2.preset) === "rise";
|
|
14018
15956
|
const appliedSkewY = angleTextPathActive ? 0 : element.skewY ?? 0;
|
|
14019
15957
|
let posIfNotSkipped = skipPositionUpdate ? {} : { left: fabricPos.left, top: fabricPos.top };
|
|
14020
15958
|
if (!skipPositionUpdate && (obj instanceof fabric.FabricImage && obj.originX === "center" || obj instanceof fabric.Group && obj.__cropGroup)) {
|
|
@@ -14091,7 +16029,17 @@ const PageCanvas = forwardRef(
|
|
|
14091
16029
|
objectCaching: true
|
|
14092
16030
|
});
|
|
14093
16031
|
} else if (obj instanceof fabric.Ellipse) {
|
|
14094
|
-
obj.set({
|
|
16032
|
+
obj.set({
|
|
16033
|
+
rx: cornerSafeW / 2,
|
|
16034
|
+
ry: cornerSafeH / 2,
|
|
16035
|
+
fill: element.fill || "transparent",
|
|
16036
|
+
stroke: element.stroke || "transparent",
|
|
16037
|
+
strokeWidth: element.strokeWidth || 0,
|
|
16038
|
+
strokeUniform: true,
|
|
16039
|
+
strokeLineJoin: "round",
|
|
16040
|
+
strokeLineCap: "round",
|
|
16041
|
+
objectCaching: true
|
|
16042
|
+
});
|
|
14095
16043
|
} else if (obj instanceof fabric.Textbox) {
|
|
14096
16044
|
const overflowPolicy = element.overflowPolicy || "grow-and-push";
|
|
14097
16045
|
let text = element.text || "Text";
|
|
@@ -14285,6 +16233,16 @@ const PageCanvas = forwardRef(
|
|
|
14285
16233
|
strokeUniform: true,
|
|
14286
16234
|
objectCaching: true
|
|
14287
16235
|
});
|
|
16236
|
+
} else if (obj instanceof fabric.Ellipse) {
|
|
16237
|
+
obj.set({
|
|
16238
|
+
rx: cornerSafeW / 2,
|
|
16239
|
+
ry: cornerSafeH / 2,
|
|
16240
|
+
fill: element.fill || "transparent",
|
|
16241
|
+
stroke: element.stroke || "transparent",
|
|
16242
|
+
strokeWidth: element.strokeWidth || 0,
|
|
16243
|
+
strokeUniform: true,
|
|
16244
|
+
objectCaching: true
|
|
16245
|
+
});
|
|
14288
16246
|
} else if (obj instanceof fabric.Rect && element.shapeType === "rounded-rect") {
|
|
14289
16247
|
const toRadius = (value, fallback) => Number.isFinite(value) ? Math.max(0, Number(value)) : fallback;
|
|
14290
16248
|
const baseRx = Math.max(0, Number(element.rx ?? 0));
|
|
@@ -14544,7 +16502,7 @@ const PageCanvas = forwardRef(
|
|
|
14544
16502
|
return Math.max(min, Math.min(max, v));
|
|
14545
16503
|
};
|
|
14546
16504
|
const applyEdgeFadeFrameClipPath = (group, element, frameW, frameH, shape, rxRatio) => {
|
|
14547
|
-
var _a2,
|
|
16505
|
+
var _a2, _b2, _c;
|
|
14548
16506
|
const fadeElement = element;
|
|
14549
16507
|
const fadeGroup = group;
|
|
14550
16508
|
const inputKey = edgeFadeKey(fadeElement);
|
|
@@ -14665,7 +16623,7 @@ const PageCanvas = forwardRef(
|
|
|
14665
16623
|
delete fadeGroup.__edgeFadeRenderConfig;
|
|
14666
16624
|
delete fadeGroup.__edgeFadeKey;
|
|
14667
16625
|
delete fadeGroup.__edgeFadeInputKey;
|
|
14668
|
-
if ((
|
|
16626
|
+
if ((_b2 = group.clipPath) == null ? void 0 : _b2.__edgeFadeMask) {
|
|
14669
16627
|
group.clipPath = void 0;
|
|
14670
16628
|
updateCoverLayout(group);
|
|
14671
16629
|
}
|
|
@@ -14682,7 +16640,7 @@ const PageCanvas = forwardRef(
|
|
|
14682
16640
|
(_c = group.canvas) == null ? void 0 : _c.requestRenderAll();
|
|
14683
16641
|
};
|
|
14684
16642
|
const loadImageAsync2 = async (element, placeholder, fc) => {
|
|
14685
|
-
var _a2,
|
|
16643
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
14686
16644
|
const imageUrl = element.src || element.imageUrl;
|
|
14687
16645
|
if (!imageUrl) return;
|
|
14688
16646
|
const elementId = element.id;
|
|
@@ -14713,7 +16671,7 @@ const PageCanvas = forwardRef(
|
|
|
14713
16671
|
await normalizeSvgImageDimensions(img, imageUrl, element.sourceFormat);
|
|
14714
16672
|
if (!isLatestRequest()) return;
|
|
14715
16673
|
const imageFitForFade = element.imageFit || ((_a2 = element.style) == null ? void 0 : _a2.imageFit) || "cover";
|
|
14716
|
-
const clipShapeForFade = element.clipShape ?? ((
|
|
16674
|
+
const clipShapeForFade = element.clipShape ?? ((_b2 = element.style) == null ? void 0 : _b2.imageFrameShape) ?? (isPreviewMode ? "rectangle" : "none");
|
|
14717
16675
|
const willUseCropGroupForFade = imageFitForFade !== "fill" || clipShapeForFade && clipShapeForFade !== "none";
|
|
14718
16676
|
try {
|
|
14719
16677
|
if (hasEdgeFade(element) && !willUseCropGroupForFade) {
|
|
@@ -14931,7 +16889,7 @@ const PageCanvas = forwardRef(
|
|
|
14931
16889
|
evented: canBeEvented && !isHidden
|
|
14932
16890
|
});
|
|
14933
16891
|
} else {
|
|
14934
|
-
|
|
16892
|
+
installImageResizeControlsWithSnap(cropGroup);
|
|
14935
16893
|
}
|
|
14936
16894
|
const cropImg = (_o = cropGroup.__cropData) == null ? void 0 : _o._img;
|
|
14937
16895
|
if (cropImg) {
|
|
@@ -15142,65 +17100,191 @@ const PageCanvas = forwardRef(
|
|
|
15142
17100
|
),
|
|
15143
17101
|
sectionsOverlay,
|
|
15144
17102
|
groupBoundsOverlay,
|
|
15145
|
-
guides.length
|
|
17103
|
+
hoverBounds && !guides.length && !(selectedIdsRef.current && selectedIdsRef.current.length) && /* @__PURE__ */ jsx(
|
|
15146
17104
|
"svg",
|
|
15147
17105
|
{
|
|
15148
17106
|
className: "absolute inset-0 pointer-events-none",
|
|
15149
17107
|
style: { width: scaledWidth, height: scaledHeight },
|
|
15150
17108
|
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
15151
|
-
children:
|
|
15152
|
-
|
|
15153
|
-
|
|
15154
|
-
|
|
15155
|
-
|
|
15156
|
-
|
|
15157
|
-
|
|
15158
|
-
|
|
15159
|
-
|
|
15160
|
-
|
|
15161
|
-
|
|
15162
|
-
|
|
15163
|
-
|
|
15164
|
-
|
|
15165
|
-
|
|
15166
|
-
|
|
15167
|
-
|
|
15168
|
-
|
|
15169
|
-
|
|
15170
|
-
|
|
15171
|
-
|
|
15172
|
-
|
|
15173
|
-
|
|
15174
|
-
|
|
15175
|
-
|
|
15176
|
-
|
|
15177
|
-
|
|
15178
|
-
|
|
15179
|
-
|
|
15180
|
-
|
|
15181
|
-
|
|
15182
|
-
|
|
15183
|
-
|
|
15184
|
-
|
|
15185
|
-
|
|
15186
|
-
|
|
15187
|
-
|
|
15188
|
-
|
|
15189
|
-
|
|
15190
|
-
|
|
15191
|
-
|
|
15192
|
-
|
|
15193
|
-
|
|
15194
|
-
|
|
15195
|
-
|
|
15196
|
-
|
|
15197
|
-
|
|
15198
|
-
|
|
15199
|
-
|
|
15200
|
-
|
|
17109
|
+
children: /* @__PURE__ */ jsx(
|
|
17110
|
+
"rect",
|
|
17111
|
+
{
|
|
17112
|
+
x: hoverBounds.left,
|
|
17113
|
+
y: hoverBounds.top,
|
|
17114
|
+
width: hoverBounds.width,
|
|
17115
|
+
height: hoverBounds.height,
|
|
17116
|
+
fill: "none",
|
|
17117
|
+
stroke: SELECTION_PRIMARY,
|
|
17118
|
+
strokeWidth: 2,
|
|
17119
|
+
vectorEffect: "non-scaling-stroke",
|
|
17120
|
+
strokeDasharray: "0",
|
|
17121
|
+
opacity: 1
|
|
17122
|
+
}
|
|
17123
|
+
)
|
|
17124
|
+
}
|
|
17125
|
+
),
|
|
17126
|
+
canvas.projectSettings.showGrid && (() => {
|
|
17127
|
+
const ps = canvas.projectSettings;
|
|
17128
|
+
const gx = Math.max(1, ps.gridSizeX ?? ps.gridSize ?? 0);
|
|
17129
|
+
const gy = Math.max(1, ps.gridSizeY ?? ps.gridSize ?? 0);
|
|
17130
|
+
if (gx <= 0 || gy <= 0) return null;
|
|
17131
|
+
return /* @__PURE__ */ jsxs(
|
|
17132
|
+
"svg",
|
|
17133
|
+
{
|
|
17134
|
+
className: "absolute inset-0 pointer-events-none",
|
|
17135
|
+
style: { width: scaledWidth, height: scaledHeight },
|
|
17136
|
+
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
17137
|
+
children: [
|
|
17138
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
17139
|
+
"pattern",
|
|
17140
|
+
{
|
|
17141
|
+
id: `pixldocs-grid-${pageId}`,
|
|
17142
|
+
width: gx,
|
|
17143
|
+
height: gy,
|
|
17144
|
+
patternUnits: "userSpaceOnUse",
|
|
17145
|
+
children: /* @__PURE__ */ jsx(
|
|
17146
|
+
"path",
|
|
17147
|
+
{
|
|
17148
|
+
d: `M ${gx} 0 L 0 0 0 ${gy}`,
|
|
17149
|
+
fill: "none",
|
|
17150
|
+
stroke: ps.gridColor || "#0f172a",
|
|
17151
|
+
strokeWidth: 0.5,
|
|
17152
|
+
opacity: 0.22
|
|
17153
|
+
}
|
|
17154
|
+
)
|
|
17155
|
+
}
|
|
17156
|
+
) }),
|
|
17157
|
+
/* @__PURE__ */ jsx("rect", { width: canvasWidth, height: canvasHeight, fill: `url(#pixldocs-grid-${pageId})` })
|
|
17158
|
+
]
|
|
17159
|
+
}
|
|
17160
|
+
);
|
|
17161
|
+
})(),
|
|
17162
|
+
guides.length > 0 && /* @__PURE__ */ jsxs(
|
|
17163
|
+
"svg",
|
|
17164
|
+
{
|
|
17165
|
+
className: "absolute inset-0 pointer-events-none",
|
|
17166
|
+
style: { width: scaledWidth, height: scaledHeight },
|
|
17167
|
+
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
17168
|
+
children: [
|
|
17169
|
+
(() => {
|
|
17170
|
+
const seenBoxes = /* @__PURE__ */ new Set();
|
|
17171
|
+
const boxes = [];
|
|
17172
|
+
for (const g of guides) {
|
|
17173
|
+
const list = g.targetBoundsList ?? (g.targetBounds ? [g.targetBounds] : []);
|
|
17174
|
+
for (const b of list) {
|
|
17175
|
+
const key = `${b.left.toFixed(1)}-${b.top.toFixed(1)}-${b.width.toFixed(1)}-${b.height.toFixed(1)}`;
|
|
17176
|
+
if (seenBoxes.has(key)) continue;
|
|
17177
|
+
seenBoxes.add(key);
|
|
17178
|
+
boxes.push(b);
|
|
17179
|
+
}
|
|
15201
17180
|
}
|
|
15202
|
-
|
|
15203
|
-
|
|
17181
|
+
return boxes.map((b, i) => /* @__PURE__ */ jsx(
|
|
17182
|
+
"rect",
|
|
17183
|
+
{
|
|
17184
|
+
x: b.left,
|
|
17185
|
+
y: b.top,
|
|
17186
|
+
width: b.width,
|
|
17187
|
+
height: b.height,
|
|
17188
|
+
fill: "none",
|
|
17189
|
+
stroke: "#f43f5e",
|
|
17190
|
+
strokeWidth: 1.5,
|
|
17191
|
+
strokeDasharray: "4,3",
|
|
17192
|
+
opacity: 0.9,
|
|
17193
|
+
vectorEffect: "non-scaling-stroke"
|
|
17194
|
+
},
|
|
17195
|
+
`tb-${i}`
|
|
17196
|
+
));
|
|
17197
|
+
})(),
|
|
17198
|
+
(() => {
|
|
17199
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17200
|
+
return guides.filter((guide) => {
|
|
17201
|
+
if (guide.kind === "gap") return true;
|
|
17202
|
+
const key = `${guide.type}-${guide.position.toFixed(1)}`;
|
|
17203
|
+
if (seen.has(key)) return false;
|
|
17204
|
+
seen.add(key);
|
|
17205
|
+
return true;
|
|
17206
|
+
}).map((guide, i) => {
|
|
17207
|
+
if (guide.kind === "gap" && guide.gap != null && guide.start != null && guide.end != null) {
|
|
17208
|
+
const gapColor = "#ec4899";
|
|
17209
|
+
const label = `${guide.gap}`;
|
|
17210
|
+
const labelW2 = Math.max(22, label.length * 7 + 8);
|
|
17211
|
+
if (guide.type === "horizontal") {
|
|
17212
|
+
const y = guide.bracketAt ?? guide.position;
|
|
17213
|
+
const x1 = guide.start;
|
|
17214
|
+
const x2 = guide.end;
|
|
17215
|
+
const mid = (x1 + x2) / 2;
|
|
17216
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
17217
|
+
/* @__PURE__ */ jsx("line", { x1, y1: y, x2, y2: y, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17218
|
+
/* @__PURE__ */ jsx("line", { x1, y1: y - 4, x2: x1, y2: y + 4, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17219
|
+
/* @__PURE__ */ jsx("line", { x1: x2, y1: y - 4, x2, y2: y + 4, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17220
|
+
/* @__PURE__ */ jsxs("g", { transform: `translate(${mid}, ${y - 12})`, children: [
|
|
17221
|
+
/* @__PURE__ */ jsx("rect", { x: -labelW2 / 2, y: -9, width: labelW2, height: 16, rx: 4, fill: gapColor }),
|
|
17222
|
+
/* @__PURE__ */ jsx("text", { x: 0, y: 3, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 600, children: label })
|
|
17223
|
+
] })
|
|
17224
|
+
] }, i);
|
|
17225
|
+
} else {
|
|
17226
|
+
const x = guide.bracketAt ?? guide.position;
|
|
17227
|
+
const y1 = guide.start;
|
|
17228
|
+
const y2 = guide.end;
|
|
17229
|
+
const mid = (y1 + y2) / 2;
|
|
17230
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
17231
|
+
/* @__PURE__ */ jsx("line", { x1: x, y1, x2: x, y2, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17232
|
+
/* @__PURE__ */ jsx("line", { x1: x - 4, y1, x2: x + 4, y2: y1, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17233
|
+
/* @__PURE__ */ jsx("line", { x1: x - 4, y1: y2, x2: x + 4, y2, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17234
|
+
/* @__PURE__ */ jsxs("g", { transform: `translate(${x + 12}, ${mid})`, children: [
|
|
17235
|
+
/* @__PURE__ */ jsx("rect", { x: -labelW2 / 2, y: -9, width: labelW2, height: 16, rx: 4, fill: gapColor }),
|
|
17236
|
+
/* @__PURE__ */ jsx("text", { x: 0, y: 3, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 600, children: label })
|
|
17237
|
+
] })
|
|
17238
|
+
] }, i);
|
|
17239
|
+
}
|
|
17240
|
+
}
|
|
17241
|
+
const isElementRelative = guide.start !== void 0 && guide.end !== void 0;
|
|
17242
|
+
const isActive2 = guide.active === true;
|
|
17243
|
+
const isGrid = guide.kind === "grid";
|
|
17244
|
+
const strokeColor = isGrid ? "#f59e0b" : isActive2 ? "#22c55e" : isElementRelative ? "#f43f5e" : "#ec4899";
|
|
17245
|
+
const strokeWidth = isGrid ? 1.75 : 1.75;
|
|
17246
|
+
const strokeDasharray = isGrid ? "2,3" : isActive2 ? "none" : isElementRelative ? "3,3" : "4,4";
|
|
17247
|
+
const showDistance = typeof guide.distance === "number";
|
|
17248
|
+
const labelText = showDistance ? String(Math.round(guide.distance)) : "";
|
|
17249
|
+
const labelW = Math.max(24, labelText.length * 7);
|
|
17250
|
+
if (guide.type === "vertical") {
|
|
17251
|
+
const padding = isElementRelative || isActive2 ? 20 : 0;
|
|
17252
|
+
const y1 = guide.start != null && guide.end != null ? Math.max(0, guide.start - padding) : 0;
|
|
17253
|
+
const y2 = guide.start != null && guide.end != null ? Math.min(canvasHeight, guide.end + padding) : canvasHeight;
|
|
17254
|
+
const labelY = guide.start != null && guide.end != null ? (guide.start + guide.end) / 2 : canvasHeight / 2;
|
|
17255
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
17256
|
+
/* @__PURE__ */ jsx("line", { x1: guide.position, y1, x2: guide.position, y2, stroke: strokeColor, strokeWidth, strokeDasharray, vectorEffect: "non-scaling-stroke" }),
|
|
17257
|
+
isActive2 && /* @__PURE__ */ jsx("circle", { cx: guide.position, cy: y2, r: 4, fill: "#22c55e", opacity: 0.9 }),
|
|
17258
|
+
isElementRelative && !isActive2 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
17259
|
+
/* @__PURE__ */ jsx("circle", { cx: guide.position, cy: y1, r: 2, fill: "#f43f5e" }),
|
|
17260
|
+
/* @__PURE__ */ jsx("circle", { cx: guide.position, cy: y2, r: 2, fill: "#f43f5e" })
|
|
17261
|
+
] }),
|
|
17262
|
+
showDistance && /* @__PURE__ */ jsxs("g", { transform: `translate(${guide.position + 6}, ${labelY})`, children: [
|
|
17263
|
+
/* @__PURE__ */ jsx("rect", { x: -2, y: -9, width: labelW, height: 16, rx: 4, fill: "rgba(0,0,0,0.75)" }),
|
|
17264
|
+
/* @__PURE__ */ jsx("text", { x: labelW / 2 - 2, y: 4, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 500, children: labelText })
|
|
17265
|
+
] })
|
|
17266
|
+
] }, i);
|
|
17267
|
+
} else {
|
|
17268
|
+
const padding = isElementRelative || isActive2 ? 20 : 0;
|
|
17269
|
+
const x1 = guide.start != null && guide.end != null ? Math.max(0, guide.start - padding) : 0;
|
|
17270
|
+
const x2 = guide.start != null && guide.end != null ? Math.min(canvasWidth, guide.end + padding) : canvasWidth;
|
|
17271
|
+
const labelX = guide.start != null && guide.end != null ? (guide.start + guide.end) / 2 : canvasWidth / 2;
|
|
17272
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
17273
|
+
/* @__PURE__ */ jsx("line", { x1, y1: guide.position, x2, y2: guide.position, stroke: strokeColor, strokeWidth, strokeDasharray, vectorEffect: "non-scaling-stroke" }),
|
|
17274
|
+
isActive2 && /* @__PURE__ */ jsx("circle", { cx: x2, cy: guide.position, r: 4, fill: "#22c55e", opacity: 0.9 }),
|
|
17275
|
+
isElementRelative && !isActive2 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
17276
|
+
/* @__PURE__ */ jsx("circle", { cx: x1, cy: guide.position, r: 2, fill: "#f43f5e" }),
|
|
17277
|
+
/* @__PURE__ */ jsx("circle", { cx: x2, cy: guide.position, r: 2, fill: "#f43f5e" })
|
|
17278
|
+
] }),
|
|
17279
|
+
showDistance && /* @__PURE__ */ jsxs("g", { transform: `translate(${labelX}, ${guide.position - 10})`, children: [
|
|
17280
|
+
/* @__PURE__ */ jsx("rect", { x: -2, y: -9, width: labelW, height: 16, rx: 4, fill: "rgba(0,0,0,0.75)" }),
|
|
17281
|
+
/* @__PURE__ */ jsx("text", { x: labelW / 2 - 2, y: 4, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 500, children: labelText })
|
|
17282
|
+
] })
|
|
17283
|
+
] }, i);
|
|
17284
|
+
}
|
|
17285
|
+
});
|
|
17286
|
+
})()
|
|
17287
|
+
]
|
|
15204
17288
|
}
|
|
15205
17289
|
),
|
|
15206
17290
|
gridResizeLabel && /* @__PURE__ */ jsx(
|
|
@@ -15336,13 +17420,13 @@ function PreviewCanvas({
|
|
|
15336
17420
|
onDynamicFieldClick,
|
|
15337
17421
|
onReady
|
|
15338
17422
|
}) {
|
|
15339
|
-
var _a2,
|
|
17423
|
+
var _a2, _b2, _c, _d, _e;
|
|
15340
17424
|
const canvasRef = useRef(null);
|
|
15341
17425
|
const containerRef = useRef(null);
|
|
15342
17426
|
const [containerWidth, setContainerWidth] = useState(0);
|
|
15343
17427
|
const [hoveredFieldId, setHoveredFieldId] = useState(null);
|
|
15344
17428
|
const page = (_a2 = config == null ? void 0 : config.pages) == null ? void 0 : _a2[pageIndex];
|
|
15345
|
-
const canvasWidth = ((
|
|
17429
|
+
const canvasWidth = ((_b2 = config == null ? void 0 : config.canvas) == null ? void 0 : _b2.width) || 612;
|
|
15346
17430
|
const canvasHeight = ((_c = config == null ? void 0 : config.canvas) == null ? void 0 : _c.height) || 792;
|
|
15347
17431
|
const elementToFieldMap = useMemo(
|
|
15348
17432
|
() => buildElementToFieldMap(config == null ? void 0 : config.dynamicFields),
|
|
@@ -15392,14 +17476,14 @@ function PreviewCanvas({
|
|
|
15392
17476
|
}
|
|
15393
17477
|
}, [elements]);
|
|
15394
17478
|
const pageSettings = useMemo(() => {
|
|
15395
|
-
var _a3,
|
|
17479
|
+
var _a3, _b3;
|
|
15396
17480
|
return {
|
|
15397
17481
|
backgroundColor: ((_a3 = page == null ? void 0 : page.settings) == null ? void 0 : _a3.backgroundColor) || "#ffffff",
|
|
15398
|
-
backgroundGradient: (
|
|
17482
|
+
backgroundGradient: (_b3 = page == null ? void 0 : page.settings) == null ? void 0 : _b3.backgroundGradient
|
|
15399
17483
|
};
|
|
15400
17484
|
}, [(_d = page == null ? void 0 : page.settings) == null ? void 0 : _d.backgroundColor, (_e = page == null ? void 0 : page.settings) == null ? void 0 : _e.backgroundGradient]);
|
|
15401
17485
|
const projectSettings = useMemo(() => {
|
|
15402
|
-
var _a3,
|
|
17486
|
+
var _a3, _b3, _c2;
|
|
15403
17487
|
const vars = ((_a3 = config.themeConfig) == null ? void 0 : _a3.variables) || {};
|
|
15404
17488
|
return {
|
|
15405
17489
|
showGrid: false,
|
|
@@ -15407,7 +17491,7 @@ function PreviewCanvas({
|
|
|
15407
17491
|
gridSize: 10,
|
|
15408
17492
|
snapToGuides: false,
|
|
15409
17493
|
snapThreshold: 5,
|
|
15410
|
-
primaryColor: (
|
|
17494
|
+
primaryColor: (_b3 = vars.primary) == null ? void 0 : _b3.value,
|
|
15411
17495
|
secondaryColor: (_c2 = vars.secondary) == null ? void 0 : _c2.value
|
|
15412
17496
|
};
|
|
15413
17497
|
}, [config.themeConfig]);
|
|
@@ -15559,7 +17643,7 @@ const PreviewCanvas$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
|
|
|
15559
17643
|
PreviewCanvas
|
|
15560
17644
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
15561
17645
|
function applyThemeToConfig(config, themeOverrides) {
|
|
15562
|
-
var _a2,
|
|
17646
|
+
var _a2, _b2, _c;
|
|
15563
17647
|
if (!themeOverrides || Object.keys(themeOverrides).length === 0) return config;
|
|
15564
17648
|
const cloned = JSON.parse(JSON.stringify(config));
|
|
15565
17649
|
if ((_a2 = cloned.themeConfig) == null ? void 0 : _a2.variables) {
|
|
@@ -15570,7 +17654,7 @@ function applyThemeToConfig(config, themeOverrides) {
|
|
|
15570
17654
|
}
|
|
15571
17655
|
}
|
|
15572
17656
|
const varMap = /* @__PURE__ */ new Map();
|
|
15573
|
-
if ((
|
|
17657
|
+
if ((_b2 = cloned.themeConfig) == null ? void 0 : _b2.variables) {
|
|
15574
17658
|
for (const [key, def] of Object.entries(cloned.themeConfig.variables)) {
|
|
15575
17659
|
varMap.set(key, themeOverrides[key] ?? def.value);
|
|
15576
17660
|
}
|
|
@@ -15607,7 +17691,7 @@ function mapFormDefFieldType(t) {
|
|
|
15607
17691
|
function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
15608
17692
|
const sections = [];
|
|
15609
17693
|
function convert(defs, parentId) {
|
|
15610
|
-
var _a2,
|
|
17694
|
+
var _a2, _b2;
|
|
15611
17695
|
for (const def of defs) {
|
|
15612
17696
|
const isRepeatable = def.repeatable === true || def.type === "repeatable";
|
|
15613
17697
|
const defFields = def.fields ?? def.entryFields ?? [];
|
|
@@ -15659,7 +17743,7 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
15659
17743
|
placeholder: f.placeholder
|
|
15660
17744
|
}))
|
|
15661
17745
|
});
|
|
15662
|
-
if ((
|
|
17746
|
+
if ((_b2 = def.children) == null ? void 0 : _b2.length) {
|
|
15663
17747
|
convert(def.children, def.id);
|
|
15664
17748
|
}
|
|
15665
17749
|
}
|
|
@@ -16288,7 +18372,7 @@ function findAllRepeatableElementsBySourceId(pages, baseNodeId, oneBasedIndex, s
|
|
|
16288
18372
|
return out;
|
|
16289
18373
|
}
|
|
16290
18374
|
function findNestedRepeatableElementBySourceId(pages, parentBaseNodeId, parentPi, childBaseNodeId, childCi, sourceElementId) {
|
|
16291
|
-
var _a2,
|
|
18375
|
+
var _a2, _b2;
|
|
16292
18376
|
const parentGroups = collectGroupsByBaseId(pages, parentBaseNodeId);
|
|
16293
18377
|
const parentGroup = parentGroups[parentPi - 1];
|
|
16294
18378
|
if (!parentGroup || !isGroup(parentGroup) || !((_a2 = parentGroup.children) == null ? void 0 : _a2.length)) return void 0;
|
|
@@ -16303,7 +18387,7 @@ function findNestedRepeatableElementBySourceId(pages, parentBaseNodeId, parentPi
|
|
|
16303
18387
|
}
|
|
16304
18388
|
collectChild(parentGroup.children);
|
|
16305
18389
|
const childGroup = childGroups[childCi - 1];
|
|
16306
|
-
if (!childGroup || !isGroup(childGroup) || !((
|
|
18390
|
+
if (!childGroup || !isGroup(childGroup) || !((_b2 = childGroup.children) == null ? void 0 : _b2.length)) return void 0;
|
|
16307
18391
|
return findElementBySourceIdInSubtree(childGroup.children, sourceElementId) ?? (childGroup.__sourceId === sourceElementId ? childGroup.id : void 0);
|
|
16308
18392
|
}
|
|
16309
18393
|
function repeatableLabelKey(label) {
|
|
@@ -16353,7 +18437,7 @@ function getRepeatableFromConfig(pages) {
|
|
|
16353
18437
|
var _a2;
|
|
16354
18438
|
const result = [];
|
|
16355
18439
|
function walk(children) {
|
|
16356
|
-
var _a3,
|
|
18440
|
+
var _a3, _b2;
|
|
16357
18441
|
if (!children) return;
|
|
16358
18442
|
for (const node of children) {
|
|
16359
18443
|
if (isGroup(node) && isVerticalStackLayoutMode(node.layoutMode) && ((_a3 = node.children) == null ? void 0 : _a3.length)) {
|
|
@@ -16362,7 +18446,7 @@ function getRepeatableFromConfig(pages) {
|
|
|
16362
18446
|
if (rep == null ? void 0 : rep.label) result.push({ nodeId: child.id, label: rep.label });
|
|
16363
18447
|
}
|
|
16364
18448
|
}
|
|
16365
|
-
if (isGroup(node) && ((
|
|
18449
|
+
if (isGroup(node) && ((_b2 = node.children) == null ? void 0 : _b2.length)) walk(node.children);
|
|
16366
18450
|
}
|
|
16367
18451
|
}
|
|
16368
18452
|
for (const page of pages) if ((_a2 = page.children) == null ? void 0 : _a2.length) walk(page.children);
|
|
@@ -16378,7 +18462,7 @@ function findRepeatableByNodeIds(pages, nodeIds) {
|
|
|
16378
18462
|
return !!((_a3 = n.repeatableSection) == null ? void 0 : _a3.label);
|
|
16379
18463
|
};
|
|
16380
18464
|
function walk(children, parentRepeatableBaseId, parentInfo, parentRepeatableEntryIndex) {
|
|
16381
|
-
var _a3,
|
|
18465
|
+
var _a3, _b2;
|
|
16382
18466
|
if (!Array.isArray(children)) return;
|
|
16383
18467
|
for (let i = 0; i < children.length; i++) {
|
|
16384
18468
|
const node = children[i];
|
|
@@ -16421,7 +18505,7 @@ function findRepeatableByNodeIds(pages, nodeIds) {
|
|
|
16421
18505
|
if (isGroup(child) && Array.isArray(child.children)) walk(child.children, effectiveChildBase, void 0, childEntryIndex);
|
|
16422
18506
|
j += count;
|
|
16423
18507
|
}
|
|
16424
|
-
} else if (isGroup(node) && ((
|
|
18508
|
+
} else if (isGroup(node) && ((_b2 = node.children) == null ? void 0 : _b2.length)) {
|
|
16425
18509
|
const nodeBase = baseId(node.id);
|
|
16426
18510
|
const selfMatch = schemaBaseIds.has(node.id) || schemaBaseIds.has(nodeBase) || node.__baseNodeId != null && schemaBaseIds.has(node.__baseNodeId);
|
|
16427
18511
|
const isSelfRepeatable = selfMatch && hasRepeatableSection(node);
|
|
@@ -16510,7 +18594,7 @@ function getNestedRepeatableEntryCount(parentId, parentIndex, childId, formValue
|
|
|
16510
18594
|
return Math.max(1, maxIndex);
|
|
16511
18595
|
}
|
|
16512
18596
|
function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsFromSchema, repeatableEntryCounts, repeatableNestedEntryCounts, displayFormatMap, repeatablePagesFromSchema) {
|
|
16513
|
-
var _a2,
|
|
18597
|
+
var _a2, _b2, _c;
|
|
16514
18598
|
const cloned = JSON.parse(JSON.stringify(config));
|
|
16515
18599
|
if (!cloned.pages) return cloned;
|
|
16516
18600
|
const dynamicFields = cloned.dynamicFields;
|
|
@@ -16691,7 +18775,7 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
|
|
|
16691
18775
|
const { node, baseNodeId, startIndex, count } = block;
|
|
16692
18776
|
const occIdx = block.__occurrenceIndex ?? 1;
|
|
16693
18777
|
const N = computeN(baseNodeId, node.id);
|
|
16694
|
-
const entryFilter = ((
|
|
18778
|
+
const entryFilter = ((_b2 = node.repeatableSection) == null ? void 0 : _b2.entryFilter) ?? entryFilterFromList(baseNodeId);
|
|
16695
18779
|
let entryIndices;
|
|
16696
18780
|
if (entryFilter && entryFilter.mode === "range" && entryFilter.range) {
|
|
16697
18781
|
const parsed = parseEntryRange(entryFilter.range, N, entryMetaFromList(baseNodeId));
|
|
@@ -17148,7 +19232,7 @@ function findAllFlowStacks(pageChildren) {
|
|
|
17148
19232
|
return result;
|
|
17149
19233
|
}
|
|
17150
19234
|
function findNestedFlowStack(entry) {
|
|
17151
|
-
var _a2,
|
|
19235
|
+
var _a2, _b2;
|
|
17152
19236
|
const queue = [...entry.children ?? []];
|
|
17153
19237
|
while (queue.length > 0) {
|
|
17154
19238
|
const node = queue.shift();
|
|
@@ -17156,7 +19240,7 @@ function findNestedFlowStack(entry) {
|
|
|
17156
19240
|
const g = node;
|
|
17157
19241
|
const hasRepeatableChildren = ((_a2 = g.children) == null ? void 0 : _a2.length) && (g.children.some(hasBaseNodeId) || g.children.some((c) => isGroup(c)));
|
|
17158
19242
|
if (isVerticalStackLayoutMode(g.layoutMode) && hasRepeatableChildren) return g;
|
|
17159
|
-
if ((
|
|
19243
|
+
if ((_b2 = g.children) == null ? void 0 : _b2.length) queue.push(...g.children);
|
|
17160
19244
|
}
|
|
17161
19245
|
return null;
|
|
17162
19246
|
}
|
|
@@ -17287,9 +19371,9 @@ function splitNestedForOverflow(flowStack, stayChildren, overflowChildren, overf
|
|
|
17287
19371
|
return { stayChildren: newStay, overflowChildren: newOverflow };
|
|
17288
19372
|
}
|
|
17289
19373
|
function paginateSinglePage(sourcePage, pageOffsetIndex) {
|
|
17290
|
-
var _a2,
|
|
19374
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
17291
19375
|
const contentTop = (_a2 = sourcePage.settings) == null ? void 0 : _a2.contentTop;
|
|
17292
|
-
const contentBottom = (
|
|
19376
|
+
const contentBottom = (_b2 = sourcePage.settings) == null ? void 0 : _b2.contentBottom;
|
|
17293
19377
|
if (contentTop == null || contentBottom == null || contentBottom <= contentTop) {
|
|
17294
19378
|
return [sourcePage];
|
|
17295
19379
|
}
|
|
@@ -18479,7 +20563,7 @@ function splitIntoRuns(text, mainSupportsChar) {
|
|
|
18479
20563
|
return runs;
|
|
18480
20564
|
}
|
|
18481
20565
|
function rewriteSvgFontsForJsPDF(svgStr) {
|
|
18482
|
-
var _a2,
|
|
20566
|
+
var _a2, _b2;
|
|
18483
20567
|
const parser = new DOMParser();
|
|
18484
20568
|
const doc = parser.parseFromString(svgStr, "image/svg+xml");
|
|
18485
20569
|
const allTextEls = Array.from(doc.querySelectorAll("text, tspan, textPath"));
|
|
@@ -18584,7 +20668,7 @@ function rewriteSvgFontsForJsPDF(svgStr) {
|
|
|
18584
20668
|
for (const node of childNodes) {
|
|
18585
20669
|
if (node.nodeType !== 3 || !node.textContent) continue;
|
|
18586
20670
|
const runs = splitIntoRuns(node.textContent, mainSupportsChar);
|
|
18587
|
-
if (runs.length <= 1 && ((
|
|
20671
|
+
if (runs.length <= 1 && ((_b2 = runs[0]) == null ? void 0 : _b2.runType) === "main") continue;
|
|
18588
20672
|
const fragment = doc.createDocumentFragment();
|
|
18589
20673
|
for (const run of runs) {
|
|
18590
20674
|
const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan");
|
|
@@ -18894,9 +20978,9 @@ function appendDataUriFontFaceRule(family, weight, style, dataUri) {
|
|
|
18894
20978
|
styleEl.appendChild(document.createTextNode(cssText));
|
|
18895
20979
|
}
|
|
18896
20980
|
function resolveHarnessFontProxyUrl() {
|
|
18897
|
-
var _a2,
|
|
20981
|
+
var _a2, _b2;
|
|
18898
20982
|
try {
|
|
18899
|
-
const runtimeBase = typeof window !== "undefined" && (window.__PIXLDOCS_SUPABASE_URL || ((_a2 = window.__CONFIG__) == null ? void 0 : _a2.supabaseUrl)) || typeof globalThis !== "undefined" && (globalThis.__PIXLDOCS_SUPABASE_URL || ((
|
|
20983
|
+
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)) || "";
|
|
18900
20984
|
const base = String(runtimeBase || "").replace(/\/$/, "");
|
|
18901
20985
|
return base ? `${base}/functions/v1/font-proxy` : "";
|
|
18902
20986
|
} catch {
|
|
@@ -19558,7 +21642,7 @@ async function resolveTemplateData(options) {
|
|
|
19558
21642
|
};
|
|
19559
21643
|
}
|
|
19560
21644
|
async function resolveFromForm(options) {
|
|
19561
|
-
var _a2,
|
|
21645
|
+
var _a2, _b2, _c;
|
|
19562
21646
|
const { templateId, formSchemaId, sectionState, flatFormData: directFlatFormData, themeId, supabaseUrl, supabaseAnonKey, prefetched } = options;
|
|
19563
21647
|
const hasSectionStateInput = !!sectionState && Object.keys(sectionState).length > 0;
|
|
19564
21648
|
if (!formSchemaId && !hasSectionStateInput) {
|
|
@@ -19608,7 +21692,7 @@ async function resolveFromForm(options) {
|
|
|
19608
21692
|
inferredSections = inferFormSchemaFromTemplate(
|
|
19609
21693
|
templateConfig.dynamicFields,
|
|
19610
21694
|
groups,
|
|
19611
|
-
((
|
|
21695
|
+
((_b2 = templateConfig.pages) == null ? void 0 : _b2.length) ? { pages: templateConfig.pages } : void 0
|
|
19612
21696
|
);
|
|
19613
21697
|
} else {
|
|
19614
21698
|
inferredSections = [];
|
|
@@ -19795,10 +21879,10 @@ function themeBaseId(id) {
|
|
|
19795
21879
|
return out;
|
|
19796
21880
|
}
|
|
19797
21881
|
function applyThemeVariantToConfig(config, themeConfig, themeId) {
|
|
19798
|
-
var _a2,
|
|
21882
|
+
var _a2, _b2, _c, _d;
|
|
19799
21883
|
if (!themeConfig) return config;
|
|
19800
21884
|
const variant = themeId && themeId !== "default" ? (_a2 = themeConfig.variants) == null ? void 0 : _a2.find((v) => v.id === themeId) : null;
|
|
19801
|
-
const shouldApplyDefaults = !variant && ((
|
|
21885
|
+
const shouldApplyDefaults = !variant && ((_b2 = themeConfig.properties) == null ? void 0 : _b2.length);
|
|
19802
21886
|
if (!variant && !shouldApplyDefaults) return config;
|
|
19803
21887
|
if (!((_c = themeConfig.properties) == null ? void 0 : _c.length)) return config;
|
|
19804
21888
|
const result = JSON.parse(JSON.stringify(config));
|
|
@@ -19819,8 +21903,8 @@ function applyThemeVariantToConfig(config, themeConfig, themeId) {
|
|
|
19819
21903
|
if (stopMatch) {
|
|
19820
21904
|
const stopIndex = parseInt(stopMatch[1], 10);
|
|
19821
21905
|
result.pages.forEach((p) => {
|
|
19822
|
-
var _a3,
|
|
19823
|
-
if ((
|
|
21906
|
+
var _a3, _b3;
|
|
21907
|
+
if ((_b3 = (_a3 = p.settings.backgroundGradient) == null ? void 0 : _a3.stops) == null ? void 0 : _b3[stopIndex]) {
|
|
19824
21908
|
p.settings.backgroundGradient = {
|
|
19825
21909
|
...p.settings.backgroundGradient,
|
|
19826
21910
|
stops: p.settings.backgroundGradient.stops.map(
|
|
@@ -19897,7 +21981,7 @@ function normalizeLayoutModes(config) {
|
|
|
19897
21981
|
}
|
|
19898
21982
|
}
|
|
19899
21983
|
function paintRepeatableSections(config, repeatableSections, formSchema) {
|
|
19900
|
-
var _a2,
|
|
21984
|
+
var _a2, _b2;
|
|
19901
21985
|
const pages = config.pages ?? [];
|
|
19902
21986
|
const entryFilters = (formSchema == null ? void 0 : formSchema.entryFilters) ?? [];
|
|
19903
21987
|
const entryFilterBases = new Set(entryFilters.map((f) => baseId(f.nodeId)));
|
|
@@ -19925,7 +22009,7 @@ function paintRepeatableSections(config, repeatableSections, formSchema) {
|
|
|
19925
22009
|
return painted;
|
|
19926
22010
|
}
|
|
19927
22011
|
for (const section of repeatableSections) {
|
|
19928
|
-
const inlineRange = ((_a2 = section.entryFilter) == null ? void 0 : _a2.mode) === "range" ? (
|
|
22012
|
+
const inlineRange = ((_a2 = section.entryFilter) == null ? void 0 : _a2.mode) === "range" ? (_b2 = section.entryFilter.range) == null ? void 0 : _b2.trim() : void 0;
|
|
19929
22013
|
const shouldUseInlineFilter = !!inlineRange && !entryFilterBases.has(baseId(section.nodeId));
|
|
19930
22014
|
const payload = { label: section.label };
|
|
19931
22015
|
if (section.minEntries !== void 0) payload.minEntries = section.minEntries;
|
|
@@ -19961,7 +22045,7 @@ function paintRepeatableSections(config, repeatableSections, formSchema) {
|
|
|
19961
22045
|
}
|
|
19962
22046
|
}
|
|
19963
22047
|
async function getTemplateForm(options) {
|
|
19964
|
-
var _a2,
|
|
22048
|
+
var _a2, _b2;
|
|
19965
22049
|
const { templateId, supabaseUrl, supabaseAnonKey } = options;
|
|
19966
22050
|
if (!supabaseUrl || !supabaseAnonKey) {
|
|
19967
22051
|
throw new Error("[getTemplateForm] supabaseUrl and supabaseAnonKey are required");
|
|
@@ -20005,7 +22089,7 @@ async function getTemplateForm(options) {
|
|
|
20005
22089
|
sections = inferFormSchemaFromTemplate(
|
|
20006
22090
|
templateConfig.dynamicFields,
|
|
20007
22091
|
templateConfig.fieldGroups || [],
|
|
20008
|
-
((
|
|
22092
|
+
((_b2 = templateConfig.pages) == null ? void 0 : _b2.length) ? { pages: templateConfig.pages } : void 0
|
|
20009
22093
|
);
|
|
20010
22094
|
} else {
|
|
20011
22095
|
sections = [];
|
|
@@ -20389,7 +22473,7 @@ function computeFrostedBoundsForPage(config, pageIndex, extraBaseIds, extraExact
|
|
|
20389
22473
|
return out;
|
|
20390
22474
|
}
|
|
20391
22475
|
function PixldocsPreview(props) {
|
|
20392
|
-
var _a2,
|
|
22476
|
+
var _a2, _b2;
|
|
20393
22477
|
const {
|
|
20394
22478
|
pageIndex = 0,
|
|
20395
22479
|
zoom = 1,
|
|
@@ -20457,10 +22541,10 @@ function PixldocsPreview(props) {
|
|
|
20457
22541
|
supabaseUrl: p.supabaseUrl,
|
|
20458
22542
|
supabaseAnonKey: p.supabaseAnonKey
|
|
20459
22543
|
}).then((resolved) => {
|
|
20460
|
-
var _a3,
|
|
22544
|
+
var _a3, _b3;
|
|
20461
22545
|
if (!cancelled) {
|
|
20462
22546
|
console.log(PREVIEW_DEBUG_PREFIX, "resolve-done", {
|
|
20463
|
-
pages: ((
|
|
22547
|
+
pages: ((_b3 = (_a3 = resolved.config) == null ? void 0 : _a3.pages) == null ? void 0 : _b3.length) ?? 0,
|
|
20464
22548
|
underlinedNodes: countUnderlinedNodes(resolved.config)
|
|
20465
22549
|
});
|
|
20466
22550
|
setResolvedConfig(resolved.config);
|
|
@@ -20570,7 +22654,7 @@ function PixldocsPreview(props) {
|
|
|
20570
22654
|
const satPct = (frostedBlurOptions == null ? void 0 : frostedBlurOptions.saturatePct) ?? 130;
|
|
20571
22655
|
const bgTint = (frostedBlurOptions == null ? void 0 : frostedBlurOptions.background) ?? "rgba(255,255,255,0.12)";
|
|
20572
22656
|
const canvasW = getNum((_a2 = config == null ? void 0 : config.canvas) == null ? void 0 : _a2.width, 0);
|
|
20573
|
-
const canvasH = getNum((
|
|
22657
|
+
const canvasH = getNum((_b2 = config == null ? void 0 : config.canvas) == null ? void 0 : _b2.height, 0);
|
|
20574
22658
|
const hasOverlays = frostedBounds.length > 0 && canvasW > 0 && canvasH > 0;
|
|
20575
22659
|
if (isLoading) {
|
|
20576
22660
|
return /* @__PURE__ */ jsx("div", { className, style: { ...style, position: "relative", minHeight: 200, display: "flex", alignItems: "center", justifyContent: "center" }, children: loadingFallback ?? /* @__PURE__ */ jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) });
|
|
@@ -20711,7 +22795,7 @@ function ensureFabricGradientDef(doc, obj, width, height) {
|
|
|
20711
22795
|
return `url(#${id})`;
|
|
20712
22796
|
}
|
|
20713
22797
|
function warpTextboxSvgAlongPath(svg, obj) {
|
|
20714
|
-
var _a2,
|
|
22798
|
+
var _a2, _b2, _c, _d, _e;
|
|
20715
22799
|
const tp = obj == null ? void 0 : obj.textPath;
|
|
20716
22800
|
if (!tp || !tp.preset || tp.preset === "none") return svg;
|
|
20717
22801
|
if (tp.preset === "rise" || tp.preset === "angle") {
|
|
@@ -20775,7 +22859,7 @@ function warpTextboxSvgAlongPath(svg, obj) {
|
|
|
20775
22859
|
}
|
|
20776
22860
|
for (const clone of Array.from(doc.querySelectorAll("g.__pdTextShadowClone"))) {
|
|
20777
22861
|
try {
|
|
20778
|
-
(
|
|
22862
|
+
(_b2 = clone.parentNode) == null ? void 0 : _b2.removeChild(clone);
|
|
20779
22863
|
} catch {
|
|
20780
22864
|
}
|
|
20781
22865
|
}
|
|
@@ -20795,9 +22879,9 @@ function warpTextboxSvgAlongPath(svg, obj) {
|
|
|
20795
22879
|
const fw = obj.fontWeight ?? 400;
|
|
20796
22880
|
const fst = obj.fontStyle || "normal";
|
|
20797
22881
|
const readFill = (el) => {
|
|
20798
|
-
var _a3,
|
|
22882
|
+
var _a3, _b3;
|
|
20799
22883
|
if (!el) return "";
|
|
20800
|
-
return el.getAttribute("fill") || ((
|
|
22884
|
+
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()) || "";
|
|
20801
22885
|
};
|
|
20802
22886
|
const w = Number(obj.width) || 0;
|
|
20803
22887
|
const h = Number(obj.height) || 0;
|
|
@@ -21150,9 +23234,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
21150
23234
|
}
|
|
21151
23235
|
return svgString;
|
|
21152
23236
|
}
|
|
21153
|
-
const resolvedPackageVersion = "0.5.
|
|
23237
|
+
const resolvedPackageVersion = "0.5.242";
|
|
21154
23238
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
21155
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
23239
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.242";
|
|
21156
23240
|
const roundParityValue = (value) => {
|
|
21157
23241
|
if (typeof value !== "number") return value;
|
|
21158
23242
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -21329,11 +23413,11 @@ function installUnderlineFix(fab) {
|
|
|
21329
23413
|
if (!TextProto || typeof TextProto._renderTextDecoration !== "function") return;
|
|
21330
23414
|
const original = TextProto._renderTextDecoration;
|
|
21331
23415
|
const measureLineTextWidth = (obj, ctx, lineIndex) => {
|
|
21332
|
-
var _a3,
|
|
23416
|
+
var _a3, _b2, _c, _d, _e, _f;
|
|
21333
23417
|
const rawLine = (_a3 = obj._textLines) == null ? void 0 : _a3[lineIndex];
|
|
21334
23418
|
const lineText = Array.isArray(rawLine) ? rawLine.join("") : String(rawLine ?? "");
|
|
21335
23419
|
if (!lineText) return 0;
|
|
21336
|
-
const fontSize = Number(((
|
|
23420
|
+
const fontSize = Number(((_b2 = obj.getValueOfPropertyAt) == null ? void 0 : _b2.call(obj, lineIndex, 0, "fontSize")) ?? obj.fontSize ?? 0);
|
|
21337
23421
|
const fontStyle = String(((_c = obj.getValueOfPropertyAt) == null ? void 0 : _c.call(obj, lineIndex, 0, "fontStyle")) ?? obj.fontStyle ?? "normal");
|
|
21338
23422
|
const fontWeight = String(((_d = obj.getValueOfPropertyAt) == null ? void 0 : _d.call(obj, lineIndex, 0, "fontWeight")) ?? obj.fontWeight ?? "400");
|
|
21339
23423
|
const fontFamily = String(((_e = obj.getValueOfPropertyAt) == null ? void 0 : _e.call(obj, lineIndex, 0, "fontFamily")) ?? obj.fontFamily ?? "sans-serif");
|
|
@@ -21473,11 +23557,78 @@ function installTextboxBoxExtensions(fab) {
|
|
|
21473
23557
|
if (Array.isArray(stateProps2)) {
|
|
21474
23558
|
if (!stateProps2.includes("minBoxHeight")) stateProps2.push("minBoxHeight");
|
|
21475
23559
|
if (!stateProps2.includes("verticalAlign")) stateProps2.push("verticalAlign");
|
|
23560
|
+
if (!stateProps2.includes("smartWrap")) stateProps2.push("smartWrap");
|
|
21476
23561
|
}
|
|
21477
23562
|
const cacheProps2 = TextboxProto2.cacheProperties;
|
|
21478
23563
|
if (Array.isArray(cacheProps2)) {
|
|
21479
23564
|
if (!cacheProps2.includes("minBoxHeight")) cacheProps2.push("minBoxHeight");
|
|
21480
23565
|
if (!cacheProps2.includes("verticalAlign")) cacheProps2.push("verticalAlign");
|
|
23566
|
+
if (!cacheProps2.includes("smartWrap")) cacheProps2.push("smartWrap");
|
|
23567
|
+
}
|
|
23568
|
+
TextboxProto2.smartWrap = true;
|
|
23569
|
+
if (typeof TextboxProto2._wrapLine === "function" && !TextboxProto2.__pixldocsOrigWrapLine) {
|
|
23570
|
+
const origWrapLine = TextboxProto2._wrapLine;
|
|
23571
|
+
TextboxProto2.__pixldocsOrigWrapLine = origWrapLine;
|
|
23572
|
+
TextboxProto2._wrapLine = function(lineIndex, desiredWidth, ref, reservedSpace = 0) {
|
|
23573
|
+
var _a3;
|
|
23574
|
+
if (!this.smartWrap || this.splitByGrapheme) {
|
|
23575
|
+
return origWrapLine.call(this, lineIndex, desiredWidth, ref, reservedSpace);
|
|
23576
|
+
}
|
|
23577
|
+
try {
|
|
23578
|
+
const additionalSpace = this._getWidthOfCharSpacing();
|
|
23579
|
+
const data = ((_a3 = ref == null ? void 0 : ref.wordsData) == null ? void 0 : _a3[lineIndex]) || [];
|
|
23580
|
+
const effective = Math.max(1, desiredWidth - reservedSpace);
|
|
23581
|
+
const infix = " ";
|
|
23582
|
+
const infixWidth = this._measureWord([infix], lineIndex, 0);
|
|
23583
|
+
const graphemeLines = [];
|
|
23584
|
+
let line = [];
|
|
23585
|
+
let lineWidth = 0;
|
|
23586
|
+
let lineJustStarted = true;
|
|
23587
|
+
let largestWordWidth = 0;
|
|
23588
|
+
let offset = 0;
|
|
23589
|
+
const pushLine = () => {
|
|
23590
|
+
graphemeLines.push(line);
|
|
23591
|
+
line = [];
|
|
23592
|
+
lineWidth = 0;
|
|
23593
|
+
lineJustStarted = true;
|
|
23594
|
+
};
|
|
23595
|
+
for (let i = 0; i < data.length; i++) {
|
|
23596
|
+
const { word, width: wordWidth } = data[i];
|
|
23597
|
+
if (wordWidth <= effective) {
|
|
23598
|
+
if (wordWidth > largestWordWidth) largestWordWidth = wordWidth;
|
|
23599
|
+
const projected = lineJustStarted ? wordWidth : lineWidth + infixWidth + wordWidth - additionalSpace;
|
|
23600
|
+
if (!lineJustStarted && projected > effective) pushLine();
|
|
23601
|
+
if (!lineJustStarted) {
|
|
23602
|
+
line.push(infix);
|
|
23603
|
+
lineWidth += infixWidth;
|
|
23604
|
+
}
|
|
23605
|
+
line = line.concat(word);
|
|
23606
|
+
lineWidth += wordWidth;
|
|
23607
|
+
lineJustStarted = false;
|
|
23608
|
+
} else {
|
|
23609
|
+
if (!lineJustStarted) pushLine();
|
|
23610
|
+
for (const g of word) {
|
|
23611
|
+
const gw = this._measureWord([g], lineIndex, offset);
|
|
23612
|
+
if (gw > largestWordWidth) largestWordWidth = gw;
|
|
23613
|
+
const gProj = lineJustStarted ? gw : lineWidth + gw - additionalSpace;
|
|
23614
|
+
if (!lineJustStarted && gProj > effective) pushLine();
|
|
23615
|
+
line.push(g);
|
|
23616
|
+
lineWidth += gw;
|
|
23617
|
+
lineJustStarted = false;
|
|
23618
|
+
offset++;
|
|
23619
|
+
}
|
|
23620
|
+
offset -= word.length;
|
|
23621
|
+
}
|
|
23622
|
+
offset += word.length + 1;
|
|
23623
|
+
}
|
|
23624
|
+
if (line.length) graphemeLines.push(line);
|
|
23625
|
+
const minNeeded = Math.max(0, Math.min(largestWordWidth, effective) - additionalSpace + reservedSpace);
|
|
23626
|
+
if (minNeeded > this.dynamicMinWidth) this.dynamicMinWidth = minNeeded;
|
|
23627
|
+
return graphemeLines;
|
|
23628
|
+
} catch (e) {
|
|
23629
|
+
return origWrapLine.call(this, lineIndex, desiredWidth, ref, reservedSpace);
|
|
23630
|
+
}
|
|
23631
|
+
};
|
|
21481
23632
|
}
|
|
21482
23633
|
TextboxProto2.__pixldocsTextboxExtended = true;
|
|
21483
23634
|
__textboxBoxExtensionsInstalled = true;
|
|
@@ -21899,7 +24050,7 @@ class PixldocsRenderer {
|
|
|
21899
24050
|
await this.waitForCanvasScene(container, cloned, i);
|
|
21900
24051
|
}
|
|
21901
24052
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
21902
|
-
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-
|
|
24053
|
+
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-CsrQStE8.js");
|
|
21903
24054
|
const prepared = preparePagesForExport(
|
|
21904
24055
|
cloned.pages,
|
|
21905
24056
|
canvasWidth,
|
|
@@ -22116,9 +24267,9 @@ class PixldocsRenderer {
|
|
|
22116
24267
|
}
|
|
22117
24268
|
waitForCanvasScene(container, config, pageIndex, maxWaitMs = 8e3, pollMs = 50) {
|
|
22118
24269
|
return new Promise((resolve) => {
|
|
22119
|
-
var _a2,
|
|
24270
|
+
var _a2, _b2;
|
|
22120
24271
|
const start = Date.now();
|
|
22121
|
-
const pageHasContent = (((
|
|
24272
|
+
const pageHasContent = (((_b2 = (_a2 = config.pages[pageIndex]) == null ? void 0 : _a2.children) == null ? void 0 : _b2.length) ?? 0) > 0;
|
|
22122
24273
|
const settle = () => requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
|
|
22123
24274
|
const check = () => {
|
|
22124
24275
|
const fabricCanvas = this.getFabricCanvasFromContainer(container);
|
|
@@ -22193,9 +24344,9 @@ class PixldocsRenderer {
|
|
|
22193
24344
|
return normalized;
|
|
22194
24345
|
}
|
|
22195
24346
|
paintPageBackground(ctx, page, width, height) {
|
|
22196
|
-
var _a2,
|
|
24347
|
+
var _a2, _b2;
|
|
22197
24348
|
const backgroundColor = ((_a2 = page == null ? void 0 : page.settings) == null ? void 0 : _a2.backgroundColor) || "#ffffff";
|
|
22198
|
-
const gradient = (
|
|
24349
|
+
const gradient = (_b2 = page == null ? void 0 : page.settings) == null ? void 0 : _b2.backgroundGradient;
|
|
22199
24350
|
ctx.clearRect(0, 0, width, height);
|
|
22200
24351
|
ctx.fillStyle = backgroundColor;
|
|
22201
24352
|
ctx.fillRect(0, 0, width, height);
|
|
@@ -22443,7 +24594,7 @@ class PixldocsRenderer {
|
|
|
22443
24594
|
};
|
|
22444
24595
|
const onReady = () => {
|
|
22445
24596
|
this.waitForCanvasScene(container, renderConfig, pageIndex).then(async () => {
|
|
22446
|
-
var _a2,
|
|
24597
|
+
var _a2, _b2;
|
|
22447
24598
|
try {
|
|
22448
24599
|
const expectedImageIds = this.getExpectedImageIds(renderConfig, pageIndex);
|
|
22449
24600
|
await this.waitForCanvasImages(container, expectedImageIds);
|
|
@@ -22462,7 +24613,7 @@ class PixldocsRenderer {
|
|
|
22462
24613
|
);
|
|
22463
24614
|
const page = renderConfig.pages[pageIndex];
|
|
22464
24615
|
const backgroundColor = ((_a2 = page == null ? void 0 : page.settings) == null ? void 0 : _a2.backgroundColor) || "#ffffff";
|
|
22465
|
-
const backgroundGradient = (
|
|
24616
|
+
const backgroundGradient = (_b2 = page == null ? void 0 : page.settings) == null ? void 0 : _b2.backgroundGradient;
|
|
22466
24617
|
cleanup();
|
|
22467
24618
|
resolve({
|
|
22468
24619
|
svg: svgString,
|
|
@@ -22583,7 +24734,7 @@ class PixldocsRenderer {
|
|
|
22583
24734
|
logJsonLine("[canvas-renderer][fabric-text-parity]", { stage, textboxes: sample.length, sample });
|
|
22584
24735
|
}
|
|
22585
24736
|
async waitForStableTextMetrics(container, config, options = {}) {
|
|
22586
|
-
var _a2,
|
|
24737
|
+
var _a2, _b2, _c;
|
|
22587
24738
|
if (typeof document !== "undefined") {
|
|
22588
24739
|
void ensureFontsForResolvedConfig(config);
|
|
22589
24740
|
await this.waitForRelevantFonts(config);
|
|
@@ -22625,7 +24776,7 @@ class PixldocsRenderer {
|
|
|
22625
24776
|
}
|
|
22626
24777
|
fabricInstance.getObjects().forEach(primeCharBounds);
|
|
22627
24778
|
(_a2 = fabricInstance.calcOffset) == null ? void 0 : _a2.call(fabricInstance);
|
|
22628
|
-
(
|
|
24779
|
+
(_b2 = fabricInstance.renderAll) == null ? void 0 : _b2.call(fabricInstance);
|
|
22629
24780
|
await waitForPaint();
|
|
22630
24781
|
(_c = fabricInstance.renderAll) == null ? void 0 : _c.call(fabricInstance);
|
|
22631
24782
|
await waitForPaint();
|
|
@@ -22666,7 +24817,7 @@ function dumpSvgTextDiagnostics(svgStr, pageIndex, tag, stage, maxItems = 30) {
|
|
|
22666
24817
|
};
|
|
22667
24818
|
logParityJson(tag, stage, { kind: "summary", ...summary });
|
|
22668
24819
|
const sample = texts.slice(0, maxItems).map((t, idx) => {
|
|
22669
|
-
var _a2,
|
|
24820
|
+
var _a2, _b2;
|
|
22670
24821
|
const tspans = Array.from(t.querySelectorAll("tspan"));
|
|
22671
24822
|
const tspanInfo = tspans.slice(0, 8).map((s) => ({
|
|
22672
24823
|
x: s.getAttribute("x"),
|
|
@@ -22683,7 +24834,7 @@ function dumpSvgTextDiagnostics(svgStr, pageIndex, tag, stage, maxItems = 30) {
|
|
|
22683
24834
|
while (cursor && !containerWidth) {
|
|
22684
24835
|
containerWidth = (_a2 = cursor.getAttribute) == null ? void 0 : _a2.call(cursor, "width");
|
|
22685
24836
|
cursor = cursor.parentElement;
|
|
22686
|
-
if (cursor && ((
|
|
24837
|
+
if (cursor && ((_b2 = cursor.tagName) == null ? void 0 : _b2.toLowerCase()) === "svg") break;
|
|
22687
24838
|
}
|
|
22688
24839
|
return {
|
|
22689
24840
|
idx,
|
|
@@ -23071,10 +25222,10 @@ function normalizeSvgExplicitColors(svg) {
|
|
|
23071
25222
|
return normalizeGradientPaintRef(v);
|
|
23072
25223
|
};
|
|
23073
25224
|
const hasExplicitNonePaint = (el, attr) => {
|
|
23074
|
-
var _a2,
|
|
25225
|
+
var _a2, _b2;
|
|
23075
25226
|
const raw = (el.getAttribute(attr) ?? ((_a2 = el.style) == null ? void 0 : _a2.getPropertyValue(attr)) ?? "").trim().toLowerCase();
|
|
23076
25227
|
if (raw === "none" || raw === "transparent") return true;
|
|
23077
|
-
const rawOpacity = (el.getAttribute(`${attr}-opacity`) ?? ((
|
|
25228
|
+
const rawOpacity = (el.getAttribute(`${attr}-opacity`) ?? ((_b2 = el.style) == null ? void 0 : _b2.getPropertyValue(`${attr}-opacity`)) ?? "").trim().toLowerCase();
|
|
23078
25229
|
return rawOpacity === "0" || rawOpacity === "0%" || rawOpacity === "0.0";
|
|
23079
25230
|
};
|
|
23080
25231
|
function walk(el, parentFill, parentStroke, parentColor) {
|
|
@@ -23141,14 +25292,14 @@ function normalizeSvgExplicitColors(svg) {
|
|
|
23141
25292
|
function bakeGroupOpacityIntoChildren(svg) {
|
|
23142
25293
|
const DRAWABLE = /* @__PURE__ */ new Set(["path", "rect", "circle", "ellipse", "polygon", "polyline", "line", "text", "tspan"]);
|
|
23143
25294
|
function walkAndBake(el, inheritedOpacity) {
|
|
23144
|
-
var _a2,
|
|
25295
|
+
var _a2, _b2, _c, _d;
|
|
23145
25296
|
if (isInSvgDefinitionSubtree(el)) {
|
|
23146
25297
|
for (let i = 0; i < el.children.length; i++) walkAndBake(el.children[i], 1);
|
|
23147
25298
|
return;
|
|
23148
25299
|
}
|
|
23149
25300
|
const tag = ((_a2 = el.tagName) == null ? void 0 : _a2.toLowerCase()) ?? "";
|
|
23150
25301
|
const opacityAttr = parseSvgOpacity(el.getAttribute("opacity"));
|
|
23151
|
-
const styleOpacity = parseSvgOpacity(((
|
|
25302
|
+
const styleOpacity = parseSvgOpacity(((_b2 = el.style) == null ? void 0 : _b2.getPropertyValue("opacity")) || null);
|
|
23152
25303
|
const ownOpacity = opacityAttr ?? styleOpacity ?? 1;
|
|
23153
25304
|
const combinedOpacity = inheritedOpacity * ownOpacity;
|
|
23154
25305
|
if (ownOpacity < 0.999 && tag !== "image") {
|
|
@@ -23671,10 +25822,10 @@ function getFirstExplicitColorFromSvg(svg) {
|
|
|
23671
25822
|
return getGradientStopColorAsHex(svg, gradientId);
|
|
23672
25823
|
};
|
|
23673
25824
|
function walk(el) {
|
|
23674
|
-
var _a2,
|
|
25825
|
+
var _a2, _b2;
|
|
23675
25826
|
if (fill && stroke) return;
|
|
23676
25827
|
const f = el.getAttribute("fill") ?? ((_a2 = el.style) == null ? void 0 : _a2.getPropertyValue("fill"));
|
|
23677
|
-
const s = el.getAttribute("stroke") ?? ((
|
|
25828
|
+
const s = el.getAttribute("stroke") ?? ((_b2 = el.style) == null ? void 0 : _b2.getPropertyValue("stroke"));
|
|
23678
25829
|
if (!fill) {
|
|
23679
25830
|
if (isRealColor(f)) fill = f;
|
|
23680
25831
|
else if (f) {
|
|
@@ -23702,8 +25853,8 @@ function isNearWhite(hex) {
|
|
|
23702
25853
|
return r >= 250 && g >= 250 && b >= 250;
|
|
23703
25854
|
}
|
|
23704
25855
|
function getStopColorRaw(stop) {
|
|
23705
|
-
var _a2,
|
|
23706
|
-
return stop.getAttribute("stop-color") ?? ((
|
|
25856
|
+
var _a2, _b2;
|
|
25857
|
+
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");
|
|
23707
25858
|
}
|
|
23708
25859
|
function getGradientStopColorAsHex(svgRoot, gradientId, visited = /* @__PURE__ */ new Set()) {
|
|
23709
25860
|
var _a2;
|
|
@@ -23767,12 +25918,12 @@ async function convertTextDecorationsToLines(svg) {
|
|
|
23767
25918
|
else el.removeAttribute("style");
|
|
23768
25919
|
};
|
|
23769
25920
|
const resolveInheritedSvgValue = (el, attr, styleProp = attr) => {
|
|
23770
|
-
var _a2,
|
|
25921
|
+
var _a2, _b2;
|
|
23771
25922
|
let current = el;
|
|
23772
25923
|
while (current) {
|
|
23773
25924
|
const attrValue = (_a2 = current.getAttribute(attr)) == null ? void 0 : _a2.trim();
|
|
23774
25925
|
if (attrValue) return attrValue;
|
|
23775
|
-
const styleValue = (
|
|
25926
|
+
const styleValue = (_b2 = getInlineStyleValue(current, styleProp)) == null ? void 0 : _b2.trim();
|
|
23776
25927
|
if (styleValue) return styleValue;
|
|
23777
25928
|
current = current.parentElement;
|
|
23778
25929
|
}
|
|
@@ -23950,7 +26101,7 @@ async function convertSvgTextDecorationsToLinesString(svgStr) {
|
|
|
23950
26101
|
}
|
|
23951
26102
|
}
|
|
23952
26103
|
async function rasterizeShadowMarkers(svg) {
|
|
23953
|
-
var _a2,
|
|
26104
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
23954
26105
|
if (typeof window === "undefined" || typeof document === "undefined") return;
|
|
23955
26106
|
const markers = Array.from(svg.querySelectorAll("g.__pdShadowRaster"));
|
|
23956
26107
|
if (markers.length === 0) return;
|
|
@@ -23974,7 +26125,7 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
23974
26125
|
const alphaRaw = parseFloat(marker.getAttribute("data-alpha") || "1");
|
|
23975
26126
|
const shadowAlpha = Number.isFinite(alphaRaw) ? Math.max(0, Math.min(1, alphaRaw)) : 1;
|
|
23976
26127
|
if (!Number.isFinite(bw) || !Number.isFinite(bh) || bw <= 0 || bh <= 0) {
|
|
23977
|
-
(
|
|
26128
|
+
(_b2 = marker.parentNode) == null ? void 0 : _b2.removeChild(marker);
|
|
23978
26129
|
continue;
|
|
23979
26130
|
}
|
|
23980
26131
|
const innerXml = restoreSourceFontsForShadowRaster(
|
|
@@ -24219,7 +26370,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
24219
26370
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
24220
26371
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
24221
26372
|
try {
|
|
24222
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-
|
|
26373
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-CsrQStE8.js");
|
|
24223
26374
|
try {
|
|
24224
26375
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
24225
26376
|
} catch {
|
|
@@ -24235,7 +26386,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
24235
26386
|
}
|
|
24236
26387
|
}
|
|
24237
26388
|
function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundColor, backgroundGradient) {
|
|
24238
|
-
var _a2,
|
|
26389
|
+
var _a2, _b2;
|
|
24239
26390
|
if (backgroundGradient && ((_a2 = backgroundGradient.stops) == null ? void 0 : _a2.length) >= 2) {
|
|
24240
26391
|
const grad = backgroundGradient;
|
|
24241
26392
|
const colorStops = grad.stops.map((s) => {
|
|
@@ -24290,7 +26441,7 @@ function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundCol
|
|
|
24290
26441
|
doc.fill({ key: patternKey, matrix: doc.Matrix(1, 0, 0, 1, 0, 0) });
|
|
24291
26442
|
});
|
|
24292
26443
|
} catch {
|
|
24293
|
-
const fallback = ((
|
|
26444
|
+
const fallback = ((_b2 = colorStops[0]) == null ? void 0 : _b2.color) || [255, 255, 255];
|
|
24294
26445
|
pdf.setFillColor(fallback[0], fallback[1], fallback[2]);
|
|
24295
26446
|
pdf.rect(0, 0, pageWidth, pageHeight, "F");
|
|
24296
26447
|
}
|
|
@@ -24303,7 +26454,7 @@ function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundCol
|
|
|
24303
26454
|
}
|
|
24304
26455
|
}
|
|
24305
26456
|
async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
24306
|
-
var _a2,
|
|
26457
|
+
var _a2, _b2;
|
|
24307
26458
|
if (svgResults.length === 0) throw new Error("No pages to export");
|
|
24308
26459
|
const { title, stripPageBackground } = options;
|
|
24309
26460
|
const firstPage = svgResults[0];
|
|
@@ -24336,7 +26487,7 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
24336
26487
|
const pageOrientation = page.width > page.height ? "landscape" : "portrait";
|
|
24337
26488
|
pdf.addPage([page.width, page.height], pageOrientation);
|
|
24338
26489
|
}
|
|
24339
|
-
const hasGradient = !!((
|
|
26490
|
+
const hasGradient = !!((_b2 = (_a2 = page.backgroundGradient) == null ? void 0 : _a2.stops) == null ? void 0 : _b2.length);
|
|
24340
26491
|
drawPageBackground(pdf, i, page.width, page.height, page.backgroundColor, page.backgroundGradient);
|
|
24341
26492
|
const shouldStripBg = stripPageBackground ?? hasGradient;
|
|
24342
26493
|
const textMode = options.textMode ?? (options.outlineText === true ? "pixel-perfect" : "selectable");
|
|
@@ -24619,4 +26770,4 @@ export {
|
|
|
24619
26770
|
buildTeaserBlurFlatKeys as y,
|
|
24620
26771
|
collectFontDescriptorsFromConfig as z
|
|
24621
26772
|
};
|
|
24622
|
-
//# sourceMappingURL=index-
|
|
26773
|
+
//# sourceMappingURL=index-BQ5V2uT8.js.map
|