@pixldocs/canvas-renderer 0.5.241 → 0.5.243
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-DtyVze4W.js → index-C5mQ2kl5.js} +2300 -345
- package/dist/index-C5mQ2kl5.js.map +1 -0
- package/dist/{index-BRI84Wy6.cjs → index-UuNicsNZ.cjs} +2300 -345
- package/dist/index-UuNicsNZ.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-BBY4avH9.js → vectorPdfExport-DJD1vq7N.js} +4 -4
- package/dist/{vectorPdfExport-BBY4avH9.js.map → vectorPdfExport-DJD1vq7N.js.map} +1 -1
- package/dist/{vectorPdfExport-BQhOl3Zh.cjs → vectorPdfExport-V2qBQ4Xs.cjs} +4 -4
- package/dist/{vectorPdfExport-BQhOl3Zh.cjs.map → vectorPdfExport-V2qBQ4Xs.cjs.map} +1 -1
- package/package.json +1 -1
- package/dist/index-BRI84Wy6.cjs.map +0 -1
- package/dist/index-DtyVze4W.js.map +0 -1
|
@@ -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,
|
|
@@ -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();
|
|
@@ -5738,6 +5770,7 @@ function getObjectSnapPoints(obj) {
|
|
|
5738
5770
|
function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold) {
|
|
5739
5771
|
if (!snapToGuides) return { guides: [], snapDx: 0, snapDy: 0 };
|
|
5740
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;
|
|
@@ -5840,6 +5891,8 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5840
5891
|
const equalGap = Math.round(newLeft - bestPair.A.right);
|
|
5841
5892
|
const bracketY = (Math.max(bestPair.A.top, projectedTop, bestPair.B.top) + Math.min(bestPair.A.bottom, projectedBottom, bestPair.B.bottom)) / 2;
|
|
5842
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 };
|
|
5843
5896
|
newGuides.push({
|
|
5844
5897
|
type: "horizontal",
|
|
5845
5898
|
position: bracketY,
|
|
@@ -5847,7 +5900,8 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5847
5900
|
gap: equalGap,
|
|
5848
5901
|
start: bestPair.A.right,
|
|
5849
5902
|
end: newLeft,
|
|
5850
|
-
bracketAt: bracketY
|
|
5903
|
+
bracketAt: bracketY,
|
|
5904
|
+
targetBoundsList: [aTb, bTb]
|
|
5851
5905
|
});
|
|
5852
5906
|
newGuides.push({
|
|
5853
5907
|
type: "horizontal",
|
|
@@ -5856,7 +5910,8 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5856
5910
|
gap: equalGap,
|
|
5857
5911
|
start: newRight,
|
|
5858
5912
|
end: bestPair.B.left,
|
|
5859
|
-
bracketAt: bracketY
|
|
5913
|
+
bracketAt: bracketY,
|
|
5914
|
+
targetBoundsList: [aTb, bTb]
|
|
5860
5915
|
});
|
|
5861
5916
|
}
|
|
5862
5917
|
}
|
|
@@ -5888,6 +5943,8 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5888
5943
|
const equalGap = Math.round(newTop - bestPair.A.bottom);
|
|
5889
5944
|
const bracketX = (Math.max(bestPair.A.left, projectedLeft, bestPair.B.left) + Math.min(bestPair.A.right, projectedRight, bestPair.B.right)) / 2;
|
|
5890
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 };
|
|
5891
5948
|
newGuides.push({
|
|
5892
5949
|
type: "vertical",
|
|
5893
5950
|
position: bracketX,
|
|
@@ -5895,7 +5952,8 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5895
5952
|
gap: equalGap,
|
|
5896
5953
|
start: bestPair.A.bottom,
|
|
5897
5954
|
end: newTop,
|
|
5898
|
-
bracketAt: bracketX
|
|
5955
|
+
bracketAt: bracketX,
|
|
5956
|
+
targetBoundsList: [aTb, bTb]
|
|
5899
5957
|
});
|
|
5900
5958
|
newGuides.push({
|
|
5901
5959
|
type: "vertical",
|
|
@@ -5904,16 +5962,17 @@ function calculateSnapGuides(movingObj, canvas, canvasWidth, canvasHeight, snapT
|
|
|
5904
5962
|
gap: equalGap,
|
|
5905
5963
|
start: newBottom,
|
|
5906
5964
|
end: bestPair.B.top,
|
|
5907
|
-
bracketAt: bracketX
|
|
5965
|
+
bracketAt: bracketX,
|
|
5966
|
+
targetBoundsList: [aTb, bTb]
|
|
5908
5967
|
});
|
|
5909
5968
|
}
|
|
5910
5969
|
}
|
|
5911
5970
|
}
|
|
5912
5971
|
return { guides: newGuides, snapDx, snapDy };
|
|
5913
5972
|
}
|
|
5914
|
-
function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold) {
|
|
5973
|
+
function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canvasHeight, snapToGuides, snapThreshold, additionalBounds = []) {
|
|
5915
5974
|
if (!snapToGuides) return [];
|
|
5916
|
-
const threshold = snapThreshold
|
|
5975
|
+
const threshold = snapThreshold;
|
|
5917
5976
|
const newGuides = [];
|
|
5918
5977
|
const scaling = getObjectSnapPoints(scalingObj);
|
|
5919
5978
|
const scalingId = getObjectId(scalingObj);
|
|
@@ -5926,7 +5985,7 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5926
5985
|
const checkVerticalSnap = (edgePosition, targetPosition, guide) => {
|
|
5927
5986
|
const dist = Math.abs(edgePosition - targetPosition);
|
|
5928
5987
|
if (dist < threshold) {
|
|
5929
|
-
newGuides.push({ ...guide,
|
|
5988
|
+
newGuides.push({ ...guide, kind: "alignment" });
|
|
5930
5989
|
return true;
|
|
5931
5990
|
}
|
|
5932
5991
|
return false;
|
|
@@ -5934,7 +5993,7 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5934
5993
|
const checkHorizontalSnap = (edgePosition, targetPosition, guide) => {
|
|
5935
5994
|
const dist = Math.abs(edgePosition - targetPosition);
|
|
5936
5995
|
if (dist < threshold) {
|
|
5937
|
-
newGuides.push({ ...guide,
|
|
5996
|
+
newGuides.push({ ...guide, kind: "alignment" });
|
|
5938
5997
|
return true;
|
|
5939
5998
|
}
|
|
5940
5999
|
return false;
|
|
@@ -5956,12 +6015,39 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
5956
6015
|
checkHorizontalSnap(scaling.bottom, canvasCenterY, { type: "horizontal", position: canvasCenterY });
|
|
5957
6016
|
}
|
|
5958
6017
|
const rawObjects = canvas.getObjects();
|
|
6018
|
+
const objectBounds = [];
|
|
5959
6019
|
for (const obj of rawObjects) {
|
|
5960
6020
|
if (obj === scalingObj) continue;
|
|
5961
6021
|
const objId = getObjectId(obj);
|
|
5962
6022
|
if (objId === "__background__") continue;
|
|
5963
6023
|
if (objId && objId === scalingId) continue;
|
|
5964
|
-
|
|
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
|
+
}
|
|
5965
6051
|
if (resizingLeft) {
|
|
5966
6052
|
checkVerticalSnap(scaling.left, other.left, {
|
|
5967
6053
|
type: "vertical",
|
|
@@ -6043,6 +6129,18 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
6043
6129
|
});
|
|
6044
6130
|
}
|
|
6045
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
|
+
}
|
|
6046
6144
|
const seen = /* @__PURE__ */ new Set();
|
|
6047
6145
|
return newGuides.filter((guide) => {
|
|
6048
6146
|
const key = `${guide.type}-${guide.position.toFixed(1)}`;
|
|
@@ -6051,6 +6149,349 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
6051
6149
|
return true;
|
|
6052
6150
|
});
|
|
6053
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
|
+
}
|
|
6054
6495
|
const clamp01$1 = (v) => Math.max(0, Math.min(1, Number.isFinite(v) ? v : 0));
|
|
6055
6496
|
function arcPath(w, sag, up) {
|
|
6056
6497
|
if (sag <= 0.5) return `M 0 0 L ${w} 0`;
|
|
@@ -6221,12 +6662,87 @@ if (Array.isArray(stateProps)) {
|
|
|
6221
6662
|
if (!stateProps.includes("minBoxHeight")) stateProps.push("minBoxHeight");
|
|
6222
6663
|
if (!stateProps.includes("verticalAlign")) stateProps.push("verticalAlign");
|
|
6223
6664
|
if (!stateProps.includes("textPath")) stateProps.push("textPath");
|
|
6665
|
+
if (!stateProps.includes("smartWrap")) stateProps.push("smartWrap");
|
|
6224
6666
|
}
|
|
6225
6667
|
const cacheProps = fabric.Textbox.prototype.cacheProperties;
|
|
6226
6668
|
if (Array.isArray(cacheProps)) {
|
|
6227
6669
|
if (!cacheProps.includes("minBoxHeight")) cacheProps.push("minBoxHeight");
|
|
6228
6670
|
if (!cacheProps.includes("verticalAlign")) cacheProps.push("verticalAlign");
|
|
6229
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
|
+
};
|
|
6230
6746
|
}
|
|
6231
6747
|
const hasActiveTextPath = (obj) => {
|
|
6232
6748
|
const tp = obj.textPath;
|
|
@@ -6383,14 +6899,14 @@ function scaleLocalToScreen(target, p) {
|
|
|
6383
6899
|
return new fabric.Point(p.x * sx * zx, p.y * sy * zy);
|
|
6384
6900
|
}
|
|
6385
6901
|
function applyTextPathControls(textbox) {
|
|
6386
|
-
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;
|
|
6387
6903
|
const obj = textbox;
|
|
6388
6904
|
if (!hasActiveTextPath(obj)) {
|
|
6389
6905
|
obj.__pdTextPathHovered = false;
|
|
6390
6906
|
if (obj.__pdTextPathControls) {
|
|
6391
6907
|
try {
|
|
6392
6908
|
const cu2 = fabric.controlsUtils;
|
|
6393
|
-
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));
|
|
6394
6910
|
if (defaults) obj.controls = defaults;
|
|
6395
6911
|
} catch {
|
|
6396
6912
|
}
|
|
@@ -6654,7 +7170,7 @@ function applyTextPathControls(textbox) {
|
|
|
6654
7170
|
actionName: "tpPivot",
|
|
6655
7171
|
positionHandler: (_d2, finalMatrix, fabricObject) => scaleLocalToScreen(fabricObject, getPivotLocalCentered(fabricObject)).transform(finalMatrix),
|
|
6656
7172
|
actionHandler: (_e2, transform, x, y) => {
|
|
6657
|
-
var _a3,
|
|
7173
|
+
var _a3, _b3;
|
|
6658
7174
|
const target = transform.target;
|
|
6659
7175
|
const state = transform.__pdCirclePivotDrag || (transform.__pdCirclePivotDrag = {
|
|
6660
7176
|
startMatrix: target.calcTransformMatrix(),
|
|
@@ -6671,7 +7187,7 @@ function applyTextPathControls(textbox) {
|
|
|
6671
7187
|
y: (state.startOffset.y || 0) + dy
|
|
6672
7188
|
};
|
|
6673
7189
|
target.setCoords();
|
|
6674
|
-
(
|
|
7190
|
+
(_b3 = target.canvas) == null ? void 0 : _b3.requestRenderAll();
|
|
6675
7191
|
return true;
|
|
6676
7192
|
},
|
|
6677
7193
|
render: renderPivot
|
|
@@ -6722,13 +7238,13 @@ function applyTextPathControls(textbox) {
|
|
|
6722
7238
|
}
|
|
6723
7239
|
if (!obj.__pdCirclePivotDblWired) {
|
|
6724
7240
|
obj.on("mousedblclick", () => {
|
|
6725
|
-
var _a3,
|
|
7241
|
+
var _a3, _b3;
|
|
6726
7242
|
if (((_a3 = obj.textPath) == null ? void 0 : _a3.preset) !== "circle") return;
|
|
6727
7243
|
if (obj.__corner !== "tpPivot") return;
|
|
6728
7244
|
if (!obj.textPath.pivot) return;
|
|
6729
7245
|
obj.textPath.pivot = { x: 0, y: 0 };
|
|
6730
7246
|
obj.setCoords();
|
|
6731
|
-
(
|
|
7247
|
+
(_b3 = obj.canvas) == null ? void 0 : _b3.requestRenderAll();
|
|
6732
7248
|
});
|
|
6733
7249
|
obj.__pdCirclePivotDblWired = true;
|
|
6734
7250
|
}
|
|
@@ -7096,10 +7612,10 @@ function textPathBoundsContainScenePoint(obj, point) {
|
|
|
7096
7612
|
}
|
|
7097
7613
|
}
|
|
7098
7614
|
function drawTextPathBounds(ctx, obj, bounds, hostCanvas) {
|
|
7099
|
-
var _a2,
|
|
7615
|
+
var _a2, _b2, _c;
|
|
7100
7616
|
const host = hostCanvas || obj.canvas || ((_a2 = obj.group) == null ? void 0 : _a2.canvas);
|
|
7101
7617
|
if (!host) return;
|
|
7102
|
-
const retina = ((
|
|
7618
|
+
const retina = ((_b2 = host.getRetinaScaling) == null ? void 0 : _b2.call(host)) || ((_c = obj.getCanvasRetinaScaling) == null ? void 0 : _c.call(obj)) || 1;
|
|
7103
7619
|
const matrix = fabric.util.multiplyTransformMatrices(host.viewportTransform || [1, 0, 0, 1, 0, 0], obj.calcTransformMatrix());
|
|
7104
7620
|
const corners = [
|
|
7105
7621
|
new fabric.Point(bounds.minX, bounds.minY),
|
|
@@ -7121,8 +7637,8 @@ function drawTextPathBounds(ctx, obj, bounds, hostCanvas) {
|
|
|
7121
7637
|
}
|
|
7122
7638
|
if (typeof TextboxProto._renderControls === "function" && !TextboxProto.__pixldocsOrigRenderControls) {
|
|
7123
7639
|
let drawWarpGuides = function(ctx) {
|
|
7124
|
-
var _a2,
|
|
7125
|
-
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);
|
|
7126
7642
|
if (!hostCanvas) return;
|
|
7127
7643
|
const hoverBounds = getTextPathHitBounds(this);
|
|
7128
7644
|
const active = (_d = hostCanvas.getActiveObject) == null ? void 0 : _d.call(hostCanvas);
|
|
@@ -7545,12 +8061,12 @@ function buildRoundedRectPath2D(ctx, x, y, w, h, rTL, rTR, rBR, rBL) {
|
|
|
7545
8061
|
ctx.closePath();
|
|
7546
8062
|
}
|
|
7547
8063
|
function measureLineGlyphWidth(obj, lineIndex) {
|
|
7548
|
-
var _a2,
|
|
8064
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
7549
8065
|
try {
|
|
7550
8066
|
const rawLine = (_a2 = obj == null ? void 0 : obj._textLines) == null ? void 0 : _a2[lineIndex];
|
|
7551
8067
|
const lineText = Array.isArray(rawLine) ? rawLine.join("") : String(rawLine ?? "");
|
|
7552
8068
|
if (!lineText) return 0;
|
|
7553
|
-
const fontSize = Number(((
|
|
8069
|
+
const fontSize = Number(((_b2 = obj.getValueOfPropertyAt) == null ? void 0 : _b2.call(obj, lineIndex, 0, "fontSize")) ?? obj.fontSize ?? 0);
|
|
7554
8070
|
if (!fontSize) return 0;
|
|
7555
8071
|
const fontStyle = String(((_c = obj.getValueOfPropertyAt) == null ? void 0 : _c.call(obj, lineIndex, 0, "fontStyle")) ?? obj.fontStyle ?? "normal");
|
|
7556
8072
|
const fontWeight = String(((_d = obj.getValueOfPropertyAt) == null ? void 0 : _d.call(obj, lineIndex, 0, "fontWeight")) ?? obj.fontWeight ?? "400");
|
|
@@ -7819,7 +8335,7 @@ function applyTextBackground(obj, cfg) {
|
|
|
7819
8335
|
const originalToSVG = (_a2 = obj.toSVG) == null ? void 0 : _a2.bind(obj);
|
|
7820
8336
|
if (typeof originalToSVG === "function") {
|
|
7821
8337
|
obj.toSVG = function(reviver) {
|
|
7822
|
-
var _a3,
|
|
8338
|
+
var _a3, _b2;
|
|
7823
8339
|
let svg = originalToSVG(reviver);
|
|
7824
8340
|
const bg = this[PD_BG_KEY];
|
|
7825
8341
|
const shadow = this.shadow;
|
|
@@ -7868,7 +8384,7 @@ function applyTextBackground(obj, cfg) {
|
|
|
7868
8384
|
const bgOpacityAttr = bgOpacity < 1 ? ` fill-opacity="${bgOpacity}"` : "";
|
|
7869
8385
|
let bgGradDefs = "";
|
|
7870
8386
|
let bgFillAttr = escapeXmlAttr(bgFill);
|
|
7871
|
-
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) {
|
|
7872
8388
|
const bounds = ribbonD ? computeRibbonBoundsFor(this, pT, pR, pB, pL) : unionBounds(rects);
|
|
7873
8389
|
const gid = `__pdBgGrad_${Math.random().toString(36).slice(2, 9)}`;
|
|
7874
8390
|
const def = buildSvgGradientDef(bg.gradient, gid, bounds.x, bounds.y, bounds.w, bounds.h);
|
|
@@ -8897,9 +9413,9 @@ function createShape(element) {
|
|
|
8897
9413
|
});
|
|
8898
9414
|
}
|
|
8899
9415
|
case "circle": {
|
|
8900
|
-
|
|
8901
|
-
|
|
8902
|
-
|
|
9416
|
+
return new fabric.Ellipse({
|
|
9417
|
+
rx: w / 2,
|
|
9418
|
+
ry: h / 2,
|
|
8903
9419
|
fill,
|
|
8904
9420
|
stroke,
|
|
8905
9421
|
strokeWidth,
|
|
@@ -8908,8 +9424,7 @@ function createShape(element) {
|
|
|
8908
9424
|
objectCaching: true,
|
|
8909
9425
|
strokeUniform: true,
|
|
8910
9426
|
strokeLineJoin: "round",
|
|
8911
|
-
strokeLineCap: "round"
|
|
8912
|
-
lockUniScaling: true
|
|
9427
|
+
strokeLineCap: "round"
|
|
8913
9428
|
});
|
|
8914
9429
|
}
|
|
8915
9430
|
case "triangle": {
|
|
@@ -8944,7 +9459,7 @@ function createShape(element) {
|
|
|
8944
9459
|
}
|
|
8945
9460
|
}
|
|
8946
9461
|
function createText(element) {
|
|
8947
|
-
var _a2,
|
|
9462
|
+
var _a2, _b2, _c, _d, _e;
|
|
8948
9463
|
const overflowPolicy = element.overflowPolicy || "grow-and-push";
|
|
8949
9464
|
let text = element.text || "Text";
|
|
8950
9465
|
let fontSize = element.fontSize || 16;
|
|
@@ -9145,7 +9660,7 @@ function createText(element) {
|
|
|
9145
9660
|
textbox.setCoords();
|
|
9146
9661
|
const widthAfterSet = textbox.width ?? 0;
|
|
9147
9662
|
try {
|
|
9148
|
-
(
|
|
9663
|
+
(_b2 = textbox.setControlsVisibility) == null ? void 0 : _b2.call(textbox, {
|
|
9149
9664
|
tl: true,
|
|
9150
9665
|
tr: true,
|
|
9151
9666
|
bl: true,
|
|
@@ -9944,34 +10459,595 @@ function bakeEdgeFade(source, fade) {
|
|
|
9944
10459
|
return canvas;
|
|
9945
10460
|
}
|
|
9946
10461
|
const SELECTION_PRIMARY = "hsl(217, 91%, 60%)";
|
|
10462
|
+
const SELECTION_BORDER_SCALE = 2;
|
|
10463
|
+
let ensureCanvaControlRenders = () => {
|
|
10464
|
+
};
|
|
9947
10465
|
try {
|
|
9948
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
|
+
}
|
|
9949
10476
|
if (InteractiveBase == null ? void 0 : InteractiveBase.ownDefaults) {
|
|
9950
10477
|
Object.assign(InteractiveBase.ownDefaults, {
|
|
9951
10478
|
borderColor: SELECTION_PRIMARY,
|
|
9952
|
-
borderScaleFactor:
|
|
10479
|
+
borderScaleFactor: SELECTION_BORDER_SCALE,
|
|
9953
10480
|
cornerColor: SELECTION_PRIMARY,
|
|
9954
10481
|
cornerStrokeColor: "#ffffff",
|
|
9955
|
-
cornerStyle: "
|
|
10482
|
+
cornerStyle: "circle",
|
|
9956
10483
|
transparentCorners: false,
|
|
9957
|
-
cornerSize:
|
|
10484
|
+
cornerSize: 10,
|
|
9958
10485
|
borderOpacityWhenMoving: 0.9
|
|
9959
10486
|
});
|
|
9960
10487
|
} else if (InteractiveBase == null ? void 0 : InteractiveBase.prototype) {
|
|
9961
10488
|
Object.assign(InteractiveBase.prototype, {
|
|
9962
10489
|
borderColor: SELECTION_PRIMARY,
|
|
9963
|
-
borderScaleFactor:
|
|
10490
|
+
borderScaleFactor: SELECTION_BORDER_SCALE,
|
|
9964
10491
|
cornerColor: SELECTION_PRIMARY,
|
|
9965
10492
|
cornerStrokeColor: "#ffffff",
|
|
9966
|
-
cornerStyle: "
|
|
10493
|
+
cornerStyle: "circle",
|
|
9967
10494
|
transparentCorners: false,
|
|
9968
|
-
cornerSize:
|
|
10495
|
+
cornerSize: 10,
|
|
9969
10496
|
borderOpacityWhenMoving: 0.9
|
|
9970
10497
|
});
|
|
9971
10498
|
}
|
|
9972
10499
|
} catch (e) {
|
|
9973
10500
|
console.warn("[PageCanvas] Failed to apply global selection defaults:", e);
|
|
9974
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
|
+
};
|
|
9975
11051
|
function applyWarpAwareSelectionBorders(selection) {
|
|
9976
11052
|
if (selection.__pixldocsOrigASHasBorders !== void 0) {
|
|
9977
11053
|
selection.hasBorders = selection.__pixldocsOrigASHasBorders;
|
|
@@ -10039,6 +11115,8 @@ const PageCanvas = forwardRef(
|
|
|
10039
11115
|
const hasRunPostReadyReflowForPageRef = useRef(null);
|
|
10040
11116
|
const hasNotifiedReadyForPageRef = useRef(null);
|
|
10041
11117
|
const hasClearedCachesBeforeFirstSyncRef = useRef(false);
|
|
11118
|
+
const projectSettingsRef = useRef(projectSettings);
|
|
11119
|
+
projectSettingsRef.current = projectSettings;
|
|
10042
11120
|
const [guides, setGuides] = useState([]);
|
|
10043
11121
|
const [gridResizeLabel, setGridResizeLabel] = useState(null);
|
|
10044
11122
|
const [hoverBounds, setHoverBounds] = useState(null);
|
|
@@ -10108,7 +11186,8 @@ const PageCanvas = forwardRef(
|
|
|
10108
11186
|
useRef(null);
|
|
10109
11187
|
useRef(null);
|
|
10110
11188
|
useRef(/* @__PURE__ */ new Map());
|
|
10111
|
-
useRef(null);
|
|
11189
|
+
const groupResizeActiveSnapRef = useRef(null);
|
|
11190
|
+
const objectResizeActiveSnapRef = useRef(null);
|
|
10112
11191
|
useRef(null);
|
|
10113
11192
|
useRef(null);
|
|
10114
11193
|
useRef(null);
|
|
@@ -10250,33 +11329,358 @@ const PageCanvas = forwardRef(
|
|
|
10250
11329
|
(movingObj) => {
|
|
10251
11330
|
const fabricCanvas = fabricRef.current;
|
|
10252
11331
|
if (!fabricCanvas) return { guides: [], snapDx: 0, snapDy: 0 };
|
|
11332
|
+
const ps = projectSettingsRef.current;
|
|
10253
11333
|
return calculateSnapGuides(
|
|
10254
11334
|
movingObj,
|
|
10255
11335
|
fabricCanvas,
|
|
10256
11336
|
canvasWidth,
|
|
10257
11337
|
canvasHeight,
|
|
10258
|
-
|
|
10259
|
-
|
|
11338
|
+
ps.snapToGuides,
|
|
11339
|
+
ps.snapThreshold
|
|
10260
11340
|
);
|
|
10261
11341
|
},
|
|
10262
|
-
[canvasWidth, canvasHeight
|
|
11342
|
+
[canvasWidth, canvasHeight]
|
|
10263
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]);
|
|
10264
11412
|
const calculateScaleSnapGuidesCallback = useCallback(
|
|
10265
11413
|
(scalingObj, corner) => {
|
|
10266
11414
|
const fabricCanvas = fabricRef.current;
|
|
10267
11415
|
if (!fabricCanvas) return [];
|
|
11416
|
+
const ps = projectSettingsRef.current;
|
|
11417
|
+
const excludeIds = getResizeExcludeIdsCallback(scalingObj);
|
|
10268
11418
|
return calculateScaleSnapGuides(
|
|
10269
11419
|
scalingObj,
|
|
10270
11420
|
corner,
|
|
10271
11421
|
fabricCanvas,
|
|
10272
11422
|
canvasWidth,
|
|
10273
11423
|
canvasHeight,
|
|
10274
|
-
|
|
10275
|
-
|
|
11424
|
+
ps.snapToGuides,
|
|
11425
|
+
ps.snapThreshold || 4,
|
|
11426
|
+
getLogicalGroupSnapBoundsCallback(excludeIds)
|
|
10276
11427
|
);
|
|
10277
11428
|
},
|
|
10278
|
-
[canvasWidth, canvasHeight,
|
|
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,
|
|
11452
|
+
canvasWidth,
|
|
11453
|
+
canvasHeight,
|
|
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
|
+
}
|
|
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();
|
|
11514
|
+
},
|
|
11515
|
+
[canvasWidth, canvasHeight, getLogicalGroupSnapBoundsCallback, getResizeExcludeIdsCallback]
|
|
10279
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]);
|
|
10280
11684
|
const isTransforming = useCallback((canvas2) => {
|
|
10281
11685
|
if (!canvas2) return false;
|
|
10282
11686
|
return !!canvas2._currentTransform || !!canvas2.__isUserTransforming;
|
|
@@ -10402,6 +11806,8 @@ const PageCanvas = forwardRef(
|
|
|
10402
11806
|
// Transparent so underlay (page bg + group bgs) shows through
|
|
10403
11807
|
backgroundColor: "transparent"
|
|
10404
11808
|
});
|
|
11809
|
+
fabricCanvas.hoverCursor = "default";
|
|
11810
|
+
fabricCanvas.moveCursor = "move";
|
|
10405
11811
|
if (!allowSelection) {
|
|
10406
11812
|
fabricCanvas.selection = false;
|
|
10407
11813
|
fabricCanvas.on("selection:created", () => {
|
|
@@ -10423,6 +11829,61 @@ const PageCanvas = forwardRef(
|
|
|
10423
11829
|
fabricRef.current = fabricCanvas;
|
|
10424
11830
|
const storeRegistryKey = registerFabricCanvas(pageId, fabricCanvas);
|
|
10425
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
|
+
}
|
|
10426
11887
|
const initFonts = async () => {
|
|
10427
11888
|
try {
|
|
10428
11889
|
await preloadAllFonts();
|
|
@@ -10512,6 +11973,17 @@ const PageCanvas = forwardRef(
|
|
|
10512
11973
|
});
|
|
10513
11974
|
fabricCanvas.on("mouse:up", () => {
|
|
10514
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
|
+
}
|
|
10515
11987
|
});
|
|
10516
11988
|
fabricCanvas.on("object:scaling", () => {
|
|
10517
11989
|
fabricCanvas.__isUserTransforming = true;
|
|
@@ -10558,7 +12030,7 @@ const PageCanvas = forwardRef(
|
|
|
10558
12030
|
didTransformRef.current = true;
|
|
10559
12031
|
});
|
|
10560
12032
|
const syncSelectionToStore = () => {
|
|
10561
|
-
var _a2,
|
|
12033
|
+
var _a2, _b2, _c, _d;
|
|
10562
12034
|
if (!isActiveRef.current || isRebuildingRef.current || isSyncingSelectionToFabricRef.current || !allowSelection) return;
|
|
10563
12035
|
const walkToTopmostGroup = (childId, children, activeEditingGroupId) => {
|
|
10564
12036
|
let topmost = null;
|
|
@@ -10597,7 +12069,7 @@ const PageCanvas = forwardRef(
|
|
|
10597
12069
|
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
10598
12070
|
const clickedId = ids[0];
|
|
10599
12071
|
const state = useEditorStore.getState();
|
|
10600
|
-
const currentPage2 = (
|
|
12072
|
+
const currentPage2 = (_b2 = state.canvas.pages) == null ? void 0 : _b2.find((p) => p.id === pageId);
|
|
10601
12073
|
const children = (currentPage2 == null ? void 0 : currentPage2.children) ?? [];
|
|
10602
12074
|
const parent = walkToTopmostGroup(clickedId, children, activeEditingGroupId);
|
|
10603
12075
|
const targetIsInCrop = !!(active instanceof fabric.Group && isCropGroupInCropMode(active) || (active == null ? void 0 : active.group) instanceof fabric.Group && isCropGroupInCropMode(active.group));
|
|
@@ -10744,8 +12216,10 @@ const PageCanvas = forwardRef(
|
|
|
10744
12216
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10745
12217
|
if (activeObj instanceof fabric.ActiveSelection) applyWarpAwareSelectionBorders(activeObj);
|
|
10746
12218
|
if (activeObj) applyControlSizeForZoom(fabricCanvas, activeObj);
|
|
12219
|
+
if (activeObj) ensureCanvaControlRenders(activeObj);
|
|
10747
12220
|
if (activeObj && !(activeObj instanceof fabric.ActiveSelection) && (((_a2 = activeObj._ct) == null ? void 0 : _a2.isCropGroup) || activeObj.__cropGroup)) {
|
|
10748
|
-
|
|
12221
|
+
installImageResizeControlsWithSnap(activeObj);
|
|
12222
|
+
ensureCanvaControlRenders(activeObj);
|
|
10749
12223
|
}
|
|
10750
12224
|
});
|
|
10751
12225
|
fabricCanvas.on("selection:updated", () => {
|
|
@@ -10757,12 +12231,14 @@ const PageCanvas = forwardRef(
|
|
|
10757
12231
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10758
12232
|
if (activeObj instanceof fabric.ActiveSelection) applyWarpAwareSelectionBorders(activeObj);
|
|
10759
12233
|
if (activeObj) applyControlSizeForZoom(fabricCanvas, activeObj);
|
|
12234
|
+
if (activeObj) ensureCanvaControlRenders(activeObj);
|
|
10760
12235
|
if (activeObj && !(activeObj instanceof fabric.ActiveSelection) && (((_a2 = activeObj._ct) == null ? void 0 : _a2.isCropGroup) || activeObj.__cropGroup)) {
|
|
10761
|
-
|
|
12236
|
+
installImageResizeControlsWithSnap(activeObj);
|
|
12237
|
+
ensureCanvaControlRenders(activeObj);
|
|
10762
12238
|
}
|
|
10763
12239
|
});
|
|
10764
12240
|
fabricCanvas.on("mouse:dblclick", (opt) => {
|
|
10765
|
-
var _a2,
|
|
12241
|
+
var _a2, _b2;
|
|
10766
12242
|
const target = opt == null ? void 0 : opt.target;
|
|
10767
12243
|
if (!target) return;
|
|
10768
12244
|
if (target.isEditing) return;
|
|
@@ -10786,7 +12262,7 @@ const PageCanvas = forwardRef(
|
|
|
10786
12262
|
const childId = getObjectId(hitChild);
|
|
10787
12263
|
if (!childId) return;
|
|
10788
12264
|
const stateNow = useEditorStore.getState();
|
|
10789
|
-
const pageNow = (
|
|
12265
|
+
const pageNow = (_b2 = stateNow.canvas.pages) == null ? void 0 : _b2.find((p) => p.id === pageId);
|
|
10790
12266
|
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
10791
12267
|
const chain = [];
|
|
10792
12268
|
{
|
|
@@ -10913,7 +12389,7 @@ const PageCanvas = forwardRef(
|
|
|
10913
12389
|
transformingIdsRef.current.clear();
|
|
10914
12390
|
};
|
|
10915
12391
|
const prepareGroupSelectionTransformStart = (target) => {
|
|
10916
|
-
var _a2,
|
|
12392
|
+
var _a2, _b2;
|
|
10917
12393
|
const active = target instanceof fabric.ActiveSelection ? target : fabricCanvas.getActiveObject();
|
|
10918
12394
|
if (!(active instanceof fabric.ActiveSelection)) return;
|
|
10919
12395
|
if (!activeSelectionMoveStartRef.current || activeSelectionMoveStartRef.current.selection !== active) {
|
|
@@ -10927,7 +12403,7 @@ const PageCanvas = forwardRef(
|
|
|
10927
12403
|
const groupId = active.__pixldocsGroupSelection;
|
|
10928
12404
|
if (!groupId) return;
|
|
10929
12405
|
if (((_a2 = groupSelectionTransformStartRef.current) == null ? void 0 : _a2.groupId) === groupId && groupSelectionTransformStartRef.current.selection === active) return;
|
|
10930
|
-
const pageChildren2 = ((
|
|
12406
|
+
const pageChildren2 = ((_b2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
|
|
10931
12407
|
const groupNode = findNodeById(pageChildren2, groupId);
|
|
10932
12408
|
if (!groupNode) return;
|
|
10933
12409
|
const groupAbs = getAbsoluteBounds(groupNode, pageChildren2);
|
|
@@ -11011,7 +12487,7 @@ const PageCanvas = forwardRef(
|
|
|
11011
12487
|
};
|
|
11012
12488
|
let pendingShiftMultiSelect = null;
|
|
11013
12489
|
const applyShiftMultiSelect = (target, event, baselineActive = fabricCanvas.getActiveObject(), baselineObjects = fabricCanvas.getActiveObjects()) => {
|
|
11014
|
-
var _a2,
|
|
12490
|
+
var _a2, _b2, _c;
|
|
11015
12491
|
if (!target || !target.selectable) return false;
|
|
11016
12492
|
const active = baselineActive;
|
|
11017
12493
|
if (!active || ((_a2 = active.getActiveControl) == null ? void 0 : _a2.call(active))) return false;
|
|
@@ -11045,7 +12521,7 @@ const PageCanvas = forwardRef(
|
|
|
11045
12521
|
isSyncingSelectionToFabricRef.current = false;
|
|
11046
12522
|
});
|
|
11047
12523
|
}
|
|
11048
|
-
(
|
|
12524
|
+
(_b2 = event == null ? void 0 : event.preventDefault) == null ? void 0 : _b2.call(event);
|
|
11049
12525
|
(_c = event == null ? void 0 : event.stopPropagation) == null ? void 0 : _c.call(event);
|
|
11050
12526
|
return true;
|
|
11051
12527
|
};
|
|
@@ -11096,9 +12572,9 @@ const PageCanvas = forwardRef(
|
|
|
11096
12572
|
return !!(((_a2 = o == null ? void 0 : o._ct) == null ? void 0 : _a2.isCropGroup) || (o == null ? void 0 : o.__cropGroup));
|
|
11097
12573
|
};
|
|
11098
12574
|
const promoteToCropGroup = (opt) => {
|
|
11099
|
-
var _a2,
|
|
12575
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
11100
12576
|
const t = opt.target;
|
|
11101
|
-
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") {
|
|
11102
12578
|
if (t && isCropGroup2(t)) {
|
|
11103
12579
|
fabricCanvas._hoveredTarget = t;
|
|
11104
12580
|
} else if ((t == null ? void 0 : t.group) && isCropGroup2(t.group)) {
|
|
@@ -11114,6 +12590,8 @@ const PageCanvas = forwardRef(
|
|
|
11114
12590
|
const objects = fabricCanvas.getObjects();
|
|
11115
12591
|
for (const obj of objects) {
|
|
11116
12592
|
if (isCropGroup2(obj) && obj.containsPoint(pointer)) {
|
|
12593
|
+
installImageResizeControlsWithSnap(obj);
|
|
12594
|
+
ensureCanvaControlRenders(obj);
|
|
11117
12595
|
fabricCanvas.setActiveObject(obj);
|
|
11118
12596
|
opt.target = obj;
|
|
11119
12597
|
fabricCanvas._hoveredTarget = obj;
|
|
@@ -11124,12 +12602,16 @@ const PageCanvas = forwardRef(
|
|
|
11124
12602
|
}
|
|
11125
12603
|
const g = t.group;
|
|
11126
12604
|
if (g && isCropGroup2(g)) {
|
|
12605
|
+
installImageResizeControlsWithSnap(g);
|
|
12606
|
+
ensureCanvaControlRenders(g);
|
|
11127
12607
|
fabricCanvas.setActiveObject(g);
|
|
11128
12608
|
opt.target = g;
|
|
11129
12609
|
fabricCanvas._hoveredTarget = g;
|
|
11130
12610
|
return;
|
|
11131
12611
|
}
|
|
11132
12612
|
if (isCropGroup2(t)) {
|
|
12613
|
+
installImageResizeControlsWithSnap(t);
|
|
12614
|
+
ensureCanvaControlRenders(t);
|
|
11133
12615
|
fabricCanvas.setActiveObject(t);
|
|
11134
12616
|
t.set({
|
|
11135
12617
|
selectable: true,
|
|
@@ -11182,7 +12664,7 @@ const PageCanvas = forwardRef(
|
|
|
11182
12664
|
});
|
|
11183
12665
|
}
|
|
11184
12666
|
fabricCanvas.on("mouse:down", (opt) => {
|
|
11185
|
-
var _a2,
|
|
12667
|
+
var _a2, _b2;
|
|
11186
12668
|
if (pendingShiftMultiSelect) {
|
|
11187
12669
|
const pending = pendingShiftMultiSelect;
|
|
11188
12670
|
pendingShiftMultiSelect = null;
|
|
@@ -11190,17 +12672,19 @@ const PageCanvas = forwardRef(
|
|
|
11190
12672
|
return;
|
|
11191
12673
|
}
|
|
11192
12674
|
const target = opt.target;
|
|
11193
|
-
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;
|
|
11194
12676
|
if (cropGroup) {
|
|
11195
12677
|
lockEdits();
|
|
11196
12678
|
didTransformRef.current = false;
|
|
12679
|
+
installImageResizeControlsWithSnap(cropGroup);
|
|
12680
|
+
ensureCanvaControlRenders(cropGroup);
|
|
11197
12681
|
fabricCanvas.setActiveObject(cropGroup);
|
|
11198
12682
|
cropGroup.setCoords();
|
|
11199
12683
|
fabricCanvas.requestRenderAll();
|
|
11200
12684
|
}
|
|
11201
12685
|
});
|
|
11202
12686
|
const groupFabricUnionBBox = (g) => {
|
|
11203
|
-
var _a2,
|
|
12687
|
+
var _a2, _b2;
|
|
11204
12688
|
const memberIds = new Set(getAllElementIds(g.children ?? []));
|
|
11205
12689
|
if (memberIds.size === 0) return null;
|
|
11206
12690
|
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
@@ -11208,7 +12692,7 @@ const PageCanvas = forwardRef(
|
|
|
11208
12692
|
for (const o of fabricCanvas.getObjects()) {
|
|
11209
12693
|
const oid = getObjectId(o);
|
|
11210
12694
|
if (!oid || !memberIds.has(oid)) continue;
|
|
11211
|
-
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));
|
|
11212
12696
|
if (!br) continue;
|
|
11213
12697
|
minX = Math.min(minX, br.left);
|
|
11214
12698
|
minY = Math.min(minY, br.top);
|
|
@@ -11234,13 +12718,13 @@ const PageCanvas = forwardRef(
|
|
|
11234
12718
|
return pick;
|
|
11235
12719
|
};
|
|
11236
12720
|
fabricCanvas.on("mouse:down:before", (opt) => {
|
|
11237
|
-
var _a2,
|
|
12721
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
|
|
11238
12722
|
if (editLockRef.current) {
|
|
11239
12723
|
const active = fabricCanvas.getActiveObject();
|
|
11240
12724
|
if (active && (((_a2 = active._ct) == null ? void 0 : _a2.isCropGroup) || active.__cropGroup)) {
|
|
11241
12725
|
opt.target = active;
|
|
11242
12726
|
if (opt.e) {
|
|
11243
|
-
(_c = (
|
|
12727
|
+
(_c = (_b2 = opt.e).preventDefault) == null ? void 0 : _c.call(_b2);
|
|
11244
12728
|
(_e = (_d = opt.e).stopPropagation) == null ? void 0 : _e.call(_d);
|
|
11245
12729
|
}
|
|
11246
12730
|
}
|
|
@@ -11250,11 +12734,34 @@ const PageCanvas = forwardRef(
|
|
|
11250
12734
|
syncLockedRef.current = true;
|
|
11251
12735
|
lockEdits();
|
|
11252
12736
|
}
|
|
11253
|
-
|
|
11254
|
-
|
|
12737
|
+
let target = opt.target;
|
|
12738
|
+
let targetId = target ? getObjectId(target) : null;
|
|
12739
|
+
if (target instanceof fabric.ActiveSelection && target.__pixldocsGroupSelection && target === fabricCanvas.getActiveObject()) {
|
|
12740
|
+
try {
|
|
12741
|
+
const pointer = fabricCanvas.getViewportPoint(opt.e);
|
|
12742
|
+
const members = target.getObjects();
|
|
12743
|
+
for (let i = members.length - 1; i >= 0; i--) {
|
|
12744
|
+
const m = members[i];
|
|
12745
|
+
if (m.visible === false) continue;
|
|
12746
|
+
if (typeof m.containsPoint === "function" && m.containsPoint(pointer)) {
|
|
12747
|
+
const mid = getObjectId(m);
|
|
12748
|
+
if (mid) {
|
|
12749
|
+
target = m;
|
|
12750
|
+
targetId = mid;
|
|
12751
|
+
}
|
|
12752
|
+
break;
|
|
12753
|
+
}
|
|
12754
|
+
}
|
|
12755
|
+
} catch {
|
|
12756
|
+
}
|
|
12757
|
+
}
|
|
11255
12758
|
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
11256
12759
|
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
11257
12760
|
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
12761
|
+
if (target instanceof fabric.Textbox && target.__corner && (target.__corner === "ml" || target.__corner === "mr")) {
|
|
12762
|
+
const sourceEl = targetId ? elementsRef.current.find((el) => el.id === targetId) : void 0;
|
|
12763
|
+
bakeTextboxScaleIntoTypography(target, sourceEl);
|
|
12764
|
+
}
|
|
11258
12765
|
if (isMultiSelectModifier(opt.e)) {
|
|
11259
12766
|
const manualTarget = target && !(target instanceof fabric.ActiveSelection) && targetId && targetId !== "__background__" ? target : pickSelectableObjectAtPointer(opt.e);
|
|
11260
12767
|
if (manualTarget) {
|
|
@@ -11281,11 +12788,39 @@ const PageCanvas = forwardRef(
|
|
|
11281
12788
|
return topmost;
|
|
11282
12789
|
};
|
|
11283
12790
|
if (target && targetId && targetId !== "__background__") {
|
|
11284
|
-
|
|
11285
|
-
|
|
12791
|
+
let effectiveTarget = target;
|
|
12792
|
+
let effectiveTargetId = targetId;
|
|
12793
|
+
const activeNowEarly = fabricCanvas.getActiveObject();
|
|
12794
|
+
const asGroupId = target instanceof fabric.ActiveSelection ? target.__pixldocsGroupSelection : void 0;
|
|
12795
|
+
if (target instanceof fabric.ActiveSelection && asGroupId && target === activeNowEarly) {
|
|
12796
|
+
try {
|
|
12797
|
+
const pointer = fabricCanvas.getViewportPoint(opt.e);
|
|
12798
|
+
const members = target.getObjects();
|
|
12799
|
+
for (let i = members.length - 1; i >= 0; i--) {
|
|
12800
|
+
const m = members[i];
|
|
12801
|
+
if (m.visible === false) continue;
|
|
12802
|
+
if (typeof m.containsPoint === "function" && m.containsPoint(pointer)) {
|
|
12803
|
+
const mid = getObjectId(m);
|
|
12804
|
+
if (mid) {
|
|
12805
|
+
effectiveTarget = m;
|
|
12806
|
+
effectiveTargetId = mid;
|
|
12807
|
+
}
|
|
12808
|
+
break;
|
|
12809
|
+
}
|
|
12810
|
+
}
|
|
12811
|
+
} catch {
|
|
12812
|
+
}
|
|
12813
|
+
}
|
|
12814
|
+
const parent = findTopmostPromotableGroup(effectiveTargetId);
|
|
12815
|
+
const targetIsInCrop = !!(effectiveTarget instanceof fabric.Group && isCropGroupInCropMode(effectiveTarget) || (effectiveTarget == null ? void 0 : effectiveTarget.group) instanceof fabric.Group && isCropGroupInCropMode(effectiveTarget.group));
|
|
11286
12816
|
const activeNow = fabricCanvas.getActiveObject();
|
|
11287
12817
|
const alreadyThisGroup = activeNow instanceof fabric.ActiveSelection && activeNow.__pixldocsGroupSelection === (parent == null ? void 0 : parent.id);
|
|
11288
12818
|
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));
|
|
12819
|
+
const isDeepSelectKey = !!((_i = opt.e) == null ? void 0 : _i.altKey);
|
|
12820
|
+
if (isDeepSelectKey) {
|
|
12821
|
+
pendingGroupPromotionRef.current = null;
|
|
12822
|
+
return;
|
|
12823
|
+
}
|
|
11289
12824
|
if (parent && !parent.backgroundColor && !targetIsInCrop && activeEditingGroupId !== parent.id && !alreadyThisGroup && !isMultiSelectKey) {
|
|
11290
12825
|
const memberIds = new Set(getAllElementIds(parent.children ?? []));
|
|
11291
12826
|
const memberObjs = fabricCanvas.getObjects().filter((o) => {
|
|
@@ -11309,10 +12844,33 @@ const PageCanvas = forwardRef(
|
|
|
11309
12844
|
opt.target = only;
|
|
11310
12845
|
pendingGroupPromotionRef.current = { groupId: parent.id, selection: only };
|
|
11311
12846
|
}
|
|
12847
|
+
} else if (parent && !parent.backgroundColor && !targetIsInCrop && alreadyThisGroup && !isMultiSelectKey && effectiveTarget !== activeNow) {
|
|
12848
|
+
try {
|
|
12849
|
+
skipSelectionClearOnDiscardRef.current = true;
|
|
12850
|
+
preserveEditingScopeOnSelectionClearRef.current = true;
|
|
12851
|
+
restoreSuppressedGroupBorders();
|
|
12852
|
+
fabricCanvas.discardActiveObject();
|
|
12853
|
+
} finally {
|
|
12854
|
+
skipSelectionClearOnDiscardRef.current = false;
|
|
12855
|
+
preserveEditingScopeOnSelectionClearRef.current = false;
|
|
12856
|
+
}
|
|
12857
|
+
fabricCanvas.__activeEditingGroupId = parent.id;
|
|
12858
|
+
delete effectiveTarget.__pixldocsGroupSelection;
|
|
12859
|
+
delete effectiveTarget.__pixldocsLogicalGroupIds;
|
|
12860
|
+
try {
|
|
12861
|
+
(_j = effectiveTarget.set) == null ? void 0 : _j.call(effectiveTarget, { selectable: true, evented: true, hasBorders: true, hasControls: true });
|
|
12862
|
+
} catch {
|
|
12863
|
+
}
|
|
12864
|
+
fabricCanvas.setActiveObject(effectiveTarget);
|
|
12865
|
+
effectiveTarget.setCoords();
|
|
12866
|
+
fabricCanvas._target = effectiveTarget;
|
|
12867
|
+
opt.target = effectiveTarget;
|
|
12868
|
+
pendingGroupPromotionRef.current = null;
|
|
11312
12869
|
}
|
|
11313
12870
|
} else if (!target || targetId === "__background__") {
|
|
11314
|
-
const isMultiSelectKey = !!(((
|
|
12871
|
+
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));
|
|
11315
12872
|
if (isMultiSelectKey) return;
|
|
12873
|
+
if ((_n = opt.e) == null ? void 0 : _n.altKey) return;
|
|
11316
12874
|
try {
|
|
11317
12875
|
const pointer = fabricCanvas.getPointer(opt.e);
|
|
11318
12876
|
const px = pointer.x;
|
|
@@ -11385,11 +12943,28 @@ const PageCanvas = forwardRef(
|
|
|
11385
12943
|
const tid = t ? getObjectId(t) : null;
|
|
11386
12944
|
try {
|
|
11387
12945
|
const activeIds = new Set(selectedIdsRef.current);
|
|
12946
|
+
const pointer = fabricCanvas.getPointer(opt.e);
|
|
12947
|
+
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
12948
|
+
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
12949
|
+
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
12950
|
+
const groupPick = pickGroupAtPointer(pointer.x, pointer.y, childrenNow, activeEditingGroupId);
|
|
12951
|
+
if (groupPick && !activeIds.has(groupPick.group.id)) {
|
|
12952
|
+
const b = groupFabricUnionBBox(groupPick.group);
|
|
12953
|
+
if (b) {
|
|
12954
|
+
setHoverBounds({
|
|
12955
|
+
left: b.left,
|
|
12956
|
+
top: b.top,
|
|
12957
|
+
width: b.right - b.left,
|
|
12958
|
+
height: b.bottom - b.top,
|
|
12959
|
+
angle: 0
|
|
12960
|
+
});
|
|
12961
|
+
return;
|
|
12962
|
+
}
|
|
12963
|
+
}
|
|
11388
12964
|
const isHoveringSelected = !!(tid && activeIds.has(tid));
|
|
11389
12965
|
if (t && tid && tid !== "__background__" && !isHoveringSelected) {
|
|
11390
|
-
|
|
11391
|
-
|
|
11392
|
-
const br = outer.getBoundingRect();
|
|
12966
|
+
t.setCoords();
|
|
12967
|
+
const br = t.getBoundingRect();
|
|
11393
12968
|
setHoverBounds({
|
|
11394
12969
|
left: br.left,
|
|
11395
12970
|
top: br.top,
|
|
@@ -11410,7 +12985,7 @@ const PageCanvas = forwardRef(
|
|
|
11410
12985
|
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
11411
12986
|
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
11412
12987
|
const pick = pickGroupAtPointer(pointer.x, pointer.y, childrenNow, activeEditingGroupId);
|
|
11413
|
-
fabricCanvas.defaultCursor =
|
|
12988
|
+
fabricCanvas.defaultCursor = "default";
|
|
11414
12989
|
} catch {
|
|
11415
12990
|
fabricCanvas.defaultCursor = "default";
|
|
11416
12991
|
}
|
|
@@ -11418,6 +12993,11 @@ const PageCanvas = forwardRef(
|
|
|
11418
12993
|
fabricCanvas.on("mouse:out", () => {
|
|
11419
12994
|
setHoverBounds(null);
|
|
11420
12995
|
});
|
|
12996
|
+
fabricCanvas.on("mouse:down", () => {
|
|
12997
|
+
setHoverBounds(null);
|
|
12998
|
+
});
|
|
12999
|
+
fabricCanvas.on("selection:created", () => setHoverBounds(null));
|
|
13000
|
+
fabricCanvas.on("selection:updated", () => setHoverBounds(null));
|
|
11421
13001
|
fabricCanvas.on("mouse:down", (ev) => {
|
|
11422
13002
|
if (fabricCanvas._currentTransform) {
|
|
11423
13003
|
lockEdits();
|
|
@@ -11433,6 +13013,8 @@ const PageCanvas = forwardRef(
|
|
|
11433
13013
|
setGuides([]);
|
|
11434
13014
|
setRotationLabel(null);
|
|
11435
13015
|
setSizeLabel(null);
|
|
13016
|
+
objectResizeActiveSnapRef.current = null;
|
|
13017
|
+
groupResizeActiveSnapRef.current = null;
|
|
11436
13018
|
dragStarted = false;
|
|
11437
13019
|
const pendingPromotion = pendingGroupPromotionRef.current;
|
|
11438
13020
|
pendingGroupPromotionRef.current = null;
|
|
@@ -11587,7 +13169,9 @@ const PageCanvas = forwardRef(
|
|
|
11587
13169
|
const intrH = obj.height ?? 1;
|
|
11588
13170
|
let newW = Math.max(1, intrW * Math.abs(sx));
|
|
11589
13171
|
let newH = Math.max(1, intrH * Math.abs(sy));
|
|
11590
|
-
if (obj instanceof fabric.
|
|
13172
|
+
if (obj instanceof fabric.Ellipse) {
|
|
13173
|
+
obj.set({ rx: newW / 2, ry: newH / 2 });
|
|
13174
|
+
} else if (obj instanceof fabric.Circle) {
|
|
11591
13175
|
const diameter = Math.max(1, Math.min(newW, newH));
|
|
11592
13176
|
newW = diameter;
|
|
11593
13177
|
newH = diameter;
|
|
@@ -11704,8 +13288,128 @@ const PageCanvas = forwardRef(
|
|
|
11704
13288
|
}
|
|
11705
13289
|
const transform = e.transform;
|
|
11706
13290
|
const corner = (transform == null ? void 0 : transform.corner) || "";
|
|
13291
|
+
if (obj instanceof fabric.ActiveSelection && (corner === "ml" || corner === "mr" || corner === "mt" || corner === "mb")) {
|
|
13292
|
+
const isXSide = corner === "ml" || corner === "mr";
|
|
13293
|
+
const sAxis = isXSide ? Math.abs(obj.scaleX ?? 1) : Math.abs(obj.scaleY ?? 1);
|
|
13294
|
+
if (sAxis > 1e-3) {
|
|
13295
|
+
for (const child of obj.getObjects()) {
|
|
13296
|
+
if (!(child instanceof fabric.Textbox)) continue;
|
|
13297
|
+
if (isXSide) {
|
|
13298
|
+
if (child.__asLiveOrigW == null) {
|
|
13299
|
+
child.__asLiveOrigW = (child.width ?? 0) * (child.scaleX ?? 1);
|
|
13300
|
+
}
|
|
13301
|
+
const origW = child.__asLiveOrigW;
|
|
13302
|
+
const newW = Math.max(20, origW * sAxis);
|
|
13303
|
+
if (Math.abs((child.width ?? 0) - newW) > 0.5) {
|
|
13304
|
+
child.set({ width: newW, scaleX: 1 / sAxis });
|
|
13305
|
+
try {
|
|
13306
|
+
child.initDimensions();
|
|
13307
|
+
} catch {
|
|
13308
|
+
}
|
|
13309
|
+
child.dirty = true;
|
|
13310
|
+
}
|
|
13311
|
+
} else {
|
|
13312
|
+
if (child.__asLiveOrigH == null) {
|
|
13313
|
+
child.__asLiveOrigH = (child.height ?? 0) * (child.scaleY ?? 1);
|
|
13314
|
+
}
|
|
13315
|
+
const origH = child.__asLiveOrigH;
|
|
13316
|
+
const newH = Math.max(20, origH * sAxis);
|
|
13317
|
+
child.minBoxHeight = newH;
|
|
13318
|
+
child.set({ scaleY: 1 / sAxis });
|
|
13319
|
+
try {
|
|
13320
|
+
child.initDimensions();
|
|
13321
|
+
} catch {
|
|
13322
|
+
}
|
|
13323
|
+
child.dirty = true;
|
|
13324
|
+
}
|
|
13325
|
+
}
|
|
13326
|
+
}
|
|
13327
|
+
}
|
|
13328
|
+
snapDuringScaleCallback(obj, corner);
|
|
11707
13329
|
const scaleGuides = calculateScaleSnapGuidesCallback(obj, corner);
|
|
11708
|
-
|
|
13330
|
+
const gridGuidesForScale = [];
|
|
13331
|
+
try {
|
|
13332
|
+
const psGrid = projectSettingsRef.current;
|
|
13333
|
+
const canApplyGridSnap = psGrid.snapToGrid && corner && !obj.__cropGroup && !obj.__resizeSnapHandler;
|
|
13334
|
+
if (canApplyGridSnap) {
|
|
13335
|
+
const gridX = psGrid.gridSizeX ?? psGrid.gridSize ?? 0;
|
|
13336
|
+
const gridY = psGrid.gridSizeY ?? psGrid.gridSize ?? 0;
|
|
13337
|
+
if (gridX > 0 && gridY > 0) {
|
|
13338
|
+
obj.setCoords();
|
|
13339
|
+
const br = obj.getBoundingRect();
|
|
13340
|
+
if (br.width > 1 && br.height > 1) {
|
|
13341
|
+
const hasL = corner.includes("l");
|
|
13342
|
+
const hasR = corner.includes("r");
|
|
13343
|
+
const hasT = corner.includes("t");
|
|
13344
|
+
const hasB = corner.includes("b");
|
|
13345
|
+
const anchorRight = br.left + br.width;
|
|
13346
|
+
const anchorBottom = br.top + br.height;
|
|
13347
|
+
let newLeft = br.left;
|
|
13348
|
+
let newTop = br.top;
|
|
13349
|
+
let newWidth = br.width;
|
|
13350
|
+
let newHeight = br.height;
|
|
13351
|
+
const xAlreadySnapped = scaleGuides.some((g) => g.type === "vertical");
|
|
13352
|
+
const yAlreadySnapped = scaleGuides.some((g) => g.type === "horizontal");
|
|
13353
|
+
if (!xAlreadySnapped) {
|
|
13354
|
+
if (hasL) {
|
|
13355
|
+
const nL = Math.round(br.left / gridX) * gridX;
|
|
13356
|
+
newWidth = Math.max(20, anchorRight - nL);
|
|
13357
|
+
newLeft = anchorRight - newWidth;
|
|
13358
|
+
} else if (hasR) {
|
|
13359
|
+
const nR = Math.round(anchorRight / gridX) * gridX;
|
|
13360
|
+
newWidth = Math.max(20, nR - br.left);
|
|
13361
|
+
}
|
|
13362
|
+
}
|
|
13363
|
+
if (!yAlreadySnapped) {
|
|
13364
|
+
if (hasT) {
|
|
13365
|
+
const nT = Math.round(br.top / gridY) * gridY;
|
|
13366
|
+
newHeight = Math.max(20, anchorBottom - nT);
|
|
13367
|
+
newTop = anchorBottom - newHeight;
|
|
13368
|
+
} else if (hasB) {
|
|
13369
|
+
const nB = Math.round(anchorBottom / gridY) * gridY;
|
|
13370
|
+
newHeight = Math.max(20, nB - br.top);
|
|
13371
|
+
}
|
|
13372
|
+
}
|
|
13373
|
+
const widthChanged = Math.abs(newWidth - br.width) > 0.5;
|
|
13374
|
+
const heightChanged = Math.abs(newHeight - br.height) > 0.5;
|
|
13375
|
+
if (widthChanged || heightChanged) {
|
|
13376
|
+
const isTextWidth = obj instanceof fabric.Textbox && widthChanged && !heightChanged;
|
|
13377
|
+
if (isTextWidth) {
|
|
13378
|
+
obj.set({ width: Math.max(20, newWidth) });
|
|
13379
|
+
try {
|
|
13380
|
+
obj.initDimensions();
|
|
13381
|
+
} catch {
|
|
13382
|
+
}
|
|
13383
|
+
} else {
|
|
13384
|
+
const ratioX = widthChanged ? newWidth / br.width : 1;
|
|
13385
|
+
const ratioY = heightChanged ? newHeight / br.height : 1;
|
|
13386
|
+
const curSx = obj.scaleX ?? 1;
|
|
13387
|
+
const curSy = obj.scaleY ?? 1;
|
|
13388
|
+
obj.set({ scaleX: curSx * ratioX, scaleY: curSy * ratioY });
|
|
13389
|
+
}
|
|
13390
|
+
obj.setCoords();
|
|
13391
|
+
const after = obj.getBoundingRect();
|
|
13392
|
+
const dx = newLeft - after.left;
|
|
13393
|
+
const dy = newTop - after.top;
|
|
13394
|
+
if (Math.abs(dx) > 0.01 || Math.abs(dy) > 0.01) {
|
|
13395
|
+
obj.set({ left: (obj.left ?? 0) + dx, top: (obj.top ?? 0) + dy });
|
|
13396
|
+
obj.setCoords();
|
|
13397
|
+
}
|
|
13398
|
+
if (!xAlreadySnapped) {
|
|
13399
|
+
if (hasL) gridGuidesForScale.push({ type: "vertical", position: newLeft, kind: "grid" });
|
|
13400
|
+
else if (hasR) gridGuidesForScale.push({ type: "vertical", position: newLeft + newWidth, kind: "grid" });
|
|
13401
|
+
}
|
|
13402
|
+
if (!yAlreadySnapped) {
|
|
13403
|
+
if (hasT) gridGuidesForScale.push({ type: "horizontal", position: newTop, kind: "grid" });
|
|
13404
|
+
else if (hasB) gridGuidesForScale.push({ type: "horizontal", position: newTop + newHeight, kind: "grid" });
|
|
13405
|
+
}
|
|
13406
|
+
}
|
|
13407
|
+
}
|
|
13408
|
+
}
|
|
13409
|
+
}
|
|
13410
|
+
} catch {
|
|
13411
|
+
}
|
|
13412
|
+
setGuides(gridGuidesForScale.length ? [...scaleGuides, ...gridGuidesForScale] : scaleGuides);
|
|
11709
13413
|
});
|
|
11710
13414
|
fabricCanvas.on("object:resizing", (e) => {
|
|
11711
13415
|
if (!isActiveRef.current) return;
|
|
@@ -11731,13 +13435,70 @@ const PageCanvas = forwardRef(
|
|
|
11731
13435
|
}
|
|
11732
13436
|
const transform = e.transform;
|
|
11733
13437
|
const corner = (transform == null ? void 0 : transform.corner) || "";
|
|
13438
|
+
if (obj instanceof fabric.Textbox && (corner === "ml" || corner === "mr")) {
|
|
13439
|
+
const objId = getObjectId(obj);
|
|
13440
|
+
const sourceEl = objId ? elementsRef.current.find((el) => el.id === objId) : void 0;
|
|
13441
|
+
bakeTextboxScaleIntoTypography(obj, sourceEl);
|
|
13442
|
+
}
|
|
13443
|
+
snapDuringScaleCallback(obj, corner);
|
|
11734
13444
|
const scaleGuides = calculateScaleSnapGuidesCallback(obj, corner);
|
|
11735
|
-
|
|
13445
|
+
const gridGuidesForTextResize = [];
|
|
13446
|
+
try {
|
|
13447
|
+
const psGrid = projectSettingsRef.current;
|
|
13448
|
+
if (psGrid.snapToGrid && corner && obj instanceof fabric.Textbox && (corner === "ml" || corner === "mr")) {
|
|
13449
|
+
const gridX = psGrid.gridSizeX ?? psGrid.gridSize ?? 0;
|
|
13450
|
+
if (gridX > 0) {
|
|
13451
|
+
obj.setCoords();
|
|
13452
|
+
const br = obj.getBoundingRect();
|
|
13453
|
+
const xAlreadySnapped = scaleGuides.some((g) => g.type === "vertical");
|
|
13454
|
+
if (!xAlreadySnapped && br.width > 1) {
|
|
13455
|
+
const anchorRight = br.left + br.width;
|
|
13456
|
+
let newLeft = br.left;
|
|
13457
|
+
let newWidth = br.width;
|
|
13458
|
+
if (corner === "ml") {
|
|
13459
|
+
const nL = Math.round(br.left / gridX) * gridX;
|
|
13460
|
+
newWidth = Math.max(20, anchorRight - nL);
|
|
13461
|
+
newLeft = anchorRight - newWidth;
|
|
13462
|
+
} else {
|
|
13463
|
+
const nR = Math.round(anchorRight / gridX) * gridX;
|
|
13464
|
+
newWidth = Math.max(20, nR - br.left);
|
|
13465
|
+
}
|
|
13466
|
+
if (Math.abs(newWidth - br.width) > 0.5) {
|
|
13467
|
+
obj.set({ width: Math.max(20, newWidth) });
|
|
13468
|
+
try {
|
|
13469
|
+
obj.initDimensions();
|
|
13470
|
+
} catch {
|
|
13471
|
+
}
|
|
13472
|
+
obj.setCoords();
|
|
13473
|
+
const after = obj.getBoundingRect();
|
|
13474
|
+
const dx = newLeft - after.left;
|
|
13475
|
+
if (Math.abs(dx) > 0.01) {
|
|
13476
|
+
obj.set({ left: (obj.left ?? 0) + dx });
|
|
13477
|
+
obj.setCoords();
|
|
13478
|
+
}
|
|
13479
|
+
gridGuidesForTextResize.push({
|
|
13480
|
+
type: "vertical",
|
|
13481
|
+
position: corner === "ml" ? newLeft : newLeft + newWidth,
|
|
13482
|
+
kind: "grid"
|
|
13483
|
+
});
|
|
13484
|
+
}
|
|
13485
|
+
}
|
|
13486
|
+
}
|
|
13487
|
+
}
|
|
13488
|
+
} catch {
|
|
13489
|
+
}
|
|
13490
|
+
setGuides(gridGuidesForTextResize.length ? [...scaleGuides, ...gridGuidesForTextResize] : scaleGuides);
|
|
11736
13491
|
});
|
|
11737
13492
|
fabricCanvas.on("object:rotating", (e) => {
|
|
11738
13493
|
markSimpleTransform(e);
|
|
11739
13494
|
didTransformRef.current = true;
|
|
11740
13495
|
const tr = e.target;
|
|
13496
|
+
try {
|
|
13497
|
+
const getCursor = fabricCanvas.__pixldocsGetRotateCursor;
|
|
13498
|
+
const upper = fabricCanvas.upperCanvasEl;
|
|
13499
|
+
if (typeof getCursor === "function" && upper && tr) upper.style.cursor = getCursor(tr);
|
|
13500
|
+
} catch {
|
|
13501
|
+
}
|
|
11741
13502
|
const rotateTargetId = tr ? getObjectId(tr) : null;
|
|
11742
13503
|
if (rotateTargetId && rotateTargetId !== "__background__") {
|
|
11743
13504
|
preserveSelectionAfterTransformIdRef.current = rotateTargetId;
|
|
@@ -11764,6 +13525,7 @@ const PageCanvas = forwardRef(
|
|
|
11764
13525
|
prepareGroupSelectionTransformStart(e.target);
|
|
11765
13526
|
markTransforming(e.target);
|
|
11766
13527
|
didTransformRef.current = true;
|
|
13528
|
+
if (e.target) e.target.__pixldocsDragMoved = true;
|
|
11767
13529
|
const moveTargetId = e.target ? getObjectId(e.target) : null;
|
|
11768
13530
|
if (moveTargetId && moveTargetId !== "__background__") {
|
|
11769
13531
|
preserveSelectionAfterTransformIdRef.current = moveTargetId;
|
|
@@ -11780,20 +13542,57 @@ const PageCanvas = forwardRef(
|
|
|
11780
13542
|
if (!obj) return;
|
|
11781
13543
|
const snapTarget = fabricCanvas.getActiveObject() ?? obj;
|
|
11782
13544
|
const { guides: newGuides, snapDx, snapDy } = calculateSnapGuidesCallback(snapTarget);
|
|
11783
|
-
|
|
13545
|
+
let finalDx = snapDx;
|
|
13546
|
+
let finalDy = snapDy;
|
|
13547
|
+
let mergedGuides = newGuides;
|
|
13548
|
+
const psLive = projectSettingsRef.current;
|
|
13549
|
+
const gridX = psLive.gridSizeX ?? psLive.gridSize ?? 0;
|
|
13550
|
+
const gridY = psLive.gridSizeY ?? psLive.gridSize ?? 0;
|
|
13551
|
+
if (psLive.snapToGrid && gridX > 0 && gridY > 0) {
|
|
13552
|
+
try {
|
|
13553
|
+
snapTarget.setCoords();
|
|
13554
|
+
} catch {
|
|
13555
|
+
}
|
|
13556
|
+
const br = snapTarget.getBoundingRect();
|
|
13557
|
+
const gridGuides = [];
|
|
13558
|
+
if (finalDx === 0) {
|
|
13559
|
+
const newLeft = Math.round(br.left / gridX) * gridX;
|
|
13560
|
+
finalDx = newLeft - br.left;
|
|
13561
|
+
gridGuides.push({ type: "vertical", position: newLeft, kind: "grid" });
|
|
13562
|
+
}
|
|
13563
|
+
if (finalDy === 0) {
|
|
13564
|
+
const newTop = Math.round(br.top / gridY) * gridY;
|
|
13565
|
+
finalDy = newTop - br.top;
|
|
13566
|
+
gridGuides.push({ type: "horizontal", position: newTop, kind: "grid" });
|
|
13567
|
+
}
|
|
13568
|
+
if (gridGuides.length) mergedGuides = [...newGuides, ...gridGuides];
|
|
13569
|
+
}
|
|
13570
|
+
setGuides(mergedGuides);
|
|
11784
13571
|
setHoverBounds(null);
|
|
11785
|
-
if (
|
|
11786
|
-
snapTarget.set({ left: (snapTarget.left ?? 0) +
|
|
13572
|
+
if (finalDx !== 0 || finalDy !== 0) {
|
|
13573
|
+
snapTarget.set({ left: (snapTarget.left ?? 0) + finalDx, top: (snapTarget.top ?? 0) + finalDy });
|
|
11787
13574
|
}
|
|
11788
13575
|
});
|
|
11789
13576
|
let cropGroupSaveTimer = null;
|
|
11790
13577
|
fabricCanvas.on("object:modified", (e) => {
|
|
11791
|
-
var _a2,
|
|
13578
|
+
var _a2, _b2, _c, _d, _e, _f, _g;
|
|
11792
13579
|
try {
|
|
11793
13580
|
dragStarted = false;
|
|
11794
13581
|
setGuides([]);
|
|
11795
13582
|
setGroupOverlayLiveBoundsRef.current(null);
|
|
13583
|
+
objectResizeActiveSnapRef.current = null;
|
|
13584
|
+
groupResizeActiveSnapRef.current = null;
|
|
11796
13585
|
onDragEnd == null ? void 0 : onDragEnd();
|
|
13586
|
+
try {
|
|
13587
|
+
const t = e.target;
|
|
13588
|
+
if (t instanceof fabric.ActiveSelection) {
|
|
13589
|
+
for (const child of t.getObjects()) {
|
|
13590
|
+
delete child.__asLiveOrigW;
|
|
13591
|
+
delete child.__asLiveOrigH;
|
|
13592
|
+
}
|
|
13593
|
+
}
|
|
13594
|
+
} catch {
|
|
13595
|
+
}
|
|
11797
13596
|
lockEdits();
|
|
11798
13597
|
const modifiedTarget = e.target;
|
|
11799
13598
|
const modifiedTargetId = modifiedTarget ? getObjectId(modifiedTarget) : null;
|
|
@@ -11902,7 +13701,7 @@ const PageCanvas = forwardRef(
|
|
|
11902
13701
|
useEditorStore.getState().reflowStackGroupInPage(pageId, groupId);
|
|
11903
13702
|
}
|
|
11904
13703
|
const stateAfter = useEditorStore.getState();
|
|
11905
|
-
const pageAfter = ((
|
|
13704
|
+
const pageAfter = ((_b2 = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
|
|
11906
13705
|
const groupNodeAfter = findNodeById(pageAfter, groupId);
|
|
11907
13706
|
if (groupNodeAfter) {
|
|
11908
13707
|
const abs = getAbsoluteBounds(groupNodeAfter, pageAfter);
|
|
@@ -11929,11 +13728,11 @@ const PageCanvas = forwardRef(
|
|
|
11929
13728
|
clearTimeout(cropGroupSaveTimer);
|
|
11930
13729
|
}
|
|
11931
13730
|
cropGroupSaveTimer = setTimeout(() => {
|
|
11932
|
-
var _a3,
|
|
13731
|
+
var _a3, _b3, _c2;
|
|
11933
13732
|
const { updateElement: updateElement2 } = useEditorStore.getState();
|
|
11934
13733
|
const img = ct._img;
|
|
11935
13734
|
const zoom3 = ((_a3 = img == null ? void 0 : img._ct) == null ? void 0 : _a3.zoom) ?? 1;
|
|
11936
|
-
const panX = ((
|
|
13735
|
+
const panX = ((_b3 = img == null ? void 0 : img._ct) == null ? void 0 : _b3.panX) ?? 0.5;
|
|
11937
13736
|
const panY = ((_c2 = img == null ? void 0 : img._ct) == null ? void 0 : _c2.panY) ?? 0.5;
|
|
11938
13737
|
const stateCrop = useEditorStore.getState();
|
|
11939
13738
|
const pageCrop = stateCrop.canvas.pages.find((p) => p.id === pageId);
|
|
@@ -11952,6 +13751,8 @@ const PageCanvas = forwardRef(
|
|
|
11952
13751
|
cropZoom: zoom3
|
|
11953
13752
|
}, { recordHistory: false });
|
|
11954
13753
|
active.__isInternalCropUpdate = false;
|
|
13754
|
+
installImageResizeControlsWithSnap(active);
|
|
13755
|
+
ensureCanvaControlRenders(active);
|
|
11955
13756
|
fabricCanvas.setActiveObject(active);
|
|
11956
13757
|
setTimeout(() => justModifiedIdsRef.current.delete(objId), 150);
|
|
11957
13758
|
}, 0);
|
|
@@ -12205,6 +14006,10 @@ const PageCanvas = forwardRef(
|
|
|
12205
14006
|
for (const obj of activeObjects) {
|
|
12206
14007
|
const objId = getObjectId(obj);
|
|
12207
14008
|
if (!objId || objId === "__background__") continue;
|
|
14009
|
+
const sourceElement = elementsRef.current.find((el) => el.id === objId);
|
|
14010
|
+
if (obj instanceof fabric.Textbox && !isActiveSelection) {
|
|
14011
|
+
bakeTextboxScaleIntoTypography(obj, sourceElement);
|
|
14012
|
+
}
|
|
12208
14013
|
let intrinsicWidth;
|
|
12209
14014
|
let intrinsicHeight;
|
|
12210
14015
|
if (obj instanceof fabric.Circle) {
|
|
@@ -12271,7 +14076,6 @@ const PageCanvas = forwardRef(
|
|
|
12271
14076
|
absoluteLeft = (absoluteLeft ?? 0) - w / 2;
|
|
12272
14077
|
absoluteTop = (absoluteTop ?? 0) - h / 2;
|
|
12273
14078
|
}
|
|
12274
|
-
const sourceElement = elementsRef.current.find((el) => el.id === objId);
|
|
12275
14079
|
const preserveCornerGeometry = (sourceElement == null ? void 0 : sourceElement.type) === "shape" && (sourceElement.shapeType === "circle" || sourceElement.shapeType === "rounded-rect" || sourceElement.shapeType === "triangle");
|
|
12276
14080
|
let finalWidth = intrinsicWidth;
|
|
12277
14081
|
let finalHeight = intrinsicHeight;
|
|
@@ -12357,17 +14161,35 @@ const PageCanvas = forwardRef(
|
|
|
12357
14161
|
finalHeight = 0;
|
|
12358
14162
|
finalScaleX = 1;
|
|
12359
14163
|
finalScaleY = 1;
|
|
14164
|
+
} else if (obj instanceof fabric.Textbox && isActiveSelection && (Math.abs((decomposed.scaleX ?? 1) - 1) > 1e-3 || Math.abs((decomposed.scaleY ?? 1) - 1) > 1e-3)) {
|
|
14165
|
+
const sx = Math.abs(decomposed.scaleX || 1);
|
|
14166
|
+
const sy = Math.abs(decomposed.scaleY || 1);
|
|
14167
|
+
const bakedWidth = Math.max(20, intrinsicWidth * sx);
|
|
14168
|
+
const bakedHeight = Math.max(1, intrinsicHeight * sy);
|
|
14169
|
+
finalWidth = bakedWidth;
|
|
14170
|
+
finalHeight = bakedHeight;
|
|
14171
|
+
finalScaleX = 1;
|
|
14172
|
+
finalScaleY = 1;
|
|
14173
|
+
try {
|
|
14174
|
+
obj.set({ width: bakedWidth, scaleX: 1, scaleY: 1 });
|
|
14175
|
+
obj.initDimensions();
|
|
14176
|
+
obj.setCoords();
|
|
14177
|
+
} catch {
|
|
14178
|
+
}
|
|
14179
|
+
finalAbsoluteMatrix = fabric.util.composeMatrix({
|
|
14180
|
+
translateX: decomposed.translateX,
|
|
14181
|
+
translateY: decomposed.translateY,
|
|
14182
|
+
angle: decomposed.angle ?? 0,
|
|
14183
|
+
scaleX: 1,
|
|
14184
|
+
scaleY: 1,
|
|
14185
|
+
skewX: 0,
|
|
14186
|
+
skewY: 0
|
|
14187
|
+
});
|
|
12360
14188
|
} else if (preserveCornerGeometry) {
|
|
12361
14189
|
const scaledW = Math.max(1, intrinsicWidth * Math.abs(decomposed.scaleX || 1));
|
|
12362
14190
|
const scaledH = Math.max(1, intrinsicHeight * Math.abs(decomposed.scaleY || 1));
|
|
12363
|
-
|
|
12364
|
-
|
|
12365
|
-
finalWidth = diameter;
|
|
12366
|
-
finalHeight = diameter;
|
|
12367
|
-
} else {
|
|
12368
|
-
finalWidth = scaledW;
|
|
12369
|
-
finalHeight = scaledH;
|
|
12370
|
-
}
|
|
14191
|
+
finalWidth = scaledW;
|
|
14192
|
+
finalHeight = scaledH;
|
|
12371
14193
|
finalScaleX = 1;
|
|
12372
14194
|
finalScaleY = 1;
|
|
12373
14195
|
obj.set({ scaleX: 1, scaleY: 1 });
|
|
@@ -12406,6 +14228,11 @@ const PageCanvas = forwardRef(
|
|
|
12406
14228
|
transformMatrix: finalAbsoluteMatrix
|
|
12407
14229
|
};
|
|
12408
14230
|
if (obj instanceof fabric.Textbox) {
|
|
14231
|
+
const bakedTextScaleUpdates = obj.__pixldocsBakedTextScaleUpdates;
|
|
14232
|
+
if (bakedTextScaleUpdates && typeof bakedTextScaleUpdates === "object") {
|
|
14233
|
+
Object.assign(elementUpdate, bakedTextScaleUpdates);
|
|
14234
|
+
delete obj.__pixldocsBakedTextScaleUpdates;
|
|
14235
|
+
}
|
|
12409
14236
|
const baked = obj.minBoxHeight;
|
|
12410
14237
|
if (typeof baked === "number" && baked > 0) {
|
|
12411
14238
|
elementUpdate.minBoxHeight = baked;
|
|
@@ -12514,7 +14341,7 @@ const PageCanvas = forwardRef(
|
|
|
12514
14341
|
}
|
|
12515
14342
|
});
|
|
12516
14343
|
fabricCanvas.on("mouse:dblclick", (e) => {
|
|
12517
|
-
var _a2,
|
|
14344
|
+
var _a2, _b2;
|
|
12518
14345
|
if (!isActiveRef.current || !allowEditing) return;
|
|
12519
14346
|
let target = e.target;
|
|
12520
14347
|
if (!target) {
|
|
@@ -12524,7 +14351,7 @@ const PageCanvas = forwardRef(
|
|
|
12524
14351
|
if (target && target instanceof fabric.Group && target.__cropGroup) {
|
|
12525
14352
|
const ct = target.__cropData;
|
|
12526
14353
|
const innerImg = ct == null ? void 0 : ct._img;
|
|
12527
|
-
const innerSrc = ((_a2 = innerImg == null ? void 0 : innerImg.getSrc) == null ? void 0 : _a2.call(innerImg)) || ((
|
|
14354
|
+
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) || "";
|
|
12528
14355
|
const isPlaceholder = !innerSrc || innerSrc === EMPTY_IMAGE_PLACEHOLDER_DATA_URL;
|
|
12529
14356
|
if (innerImg && !isPlaceholder && !isCropGroupInCropMode(target)) {
|
|
12530
14357
|
enterCropMode(target);
|
|
@@ -12703,13 +14530,13 @@ const PageCanvas = forwardRef(
|
|
|
12703
14530
|
visibilityUpdateInProgressRef.current = false;
|
|
12704
14531
|
}
|
|
12705
14532
|
doSyncRef.current = () => {
|
|
12706
|
-
var _a2,
|
|
14533
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
12707
14534
|
const shouldSkipUpdates2 = syncLockedRef.current || editLockRef.current;
|
|
12708
14535
|
const state = useEditorStore.getState();
|
|
12709
14536
|
const elementsToSync = elements;
|
|
12710
14537
|
elementsRef.current = elementsToSync;
|
|
12711
14538
|
const pageTree = isPreviewMode && (pageChildren == null ? void 0 : pageChildren.length) ? pageChildren ?? [] : ((_a2 = state.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
|
|
12712
|
-
const selectedIdsFromStore = new Set(((
|
|
14539
|
+
const selectedIdsFromStore = new Set(((_b2 = state.canvas) == null ? void 0 : _b2.selectedIds) ?? []);
|
|
12713
14540
|
isRebuildingRef.current = true;
|
|
12714
14541
|
const allElementIds = new Set(elementsToSync.map((el) => el.id));
|
|
12715
14542
|
const sectionGroups = pageTree.filter(
|
|
@@ -12736,7 +14563,8 @@ const PageCanvas = forwardRef(
|
|
|
12736
14563
|
const activeObj = fc.getActiveObject();
|
|
12737
14564
|
const activeObjId = activeObj ? getObjectId(activeObj) : null;
|
|
12738
14565
|
const isTextBeingEdited = activeObjId && editingTextIdRef.current === activeObjId;
|
|
12739
|
-
|
|
14566
|
+
const isMultiSelect = activeObj instanceof fabric.ActiveSelection;
|
|
14567
|
+
if (activeObj && isMultiSelect && !(((_c = activeObj._ct) == null ? void 0 : _c.isCropGroup) || activeObj.__cropGroup) && !isTextBeingEdited) {
|
|
12740
14568
|
fc.discardActiveObject();
|
|
12741
14569
|
}
|
|
12742
14570
|
}
|
|
@@ -13056,7 +14884,7 @@ const PageCanvas = forwardRef(
|
|
|
13056
14884
|
updateCoverLayout(existingObj);
|
|
13057
14885
|
applyEdgeFadeFrameClipPath(existingObj, element, ct.frameW, ct.frameH, ct.shape || "rect", ct.rx || 0);
|
|
13058
14886
|
if (allowEditing) {
|
|
13059
|
-
|
|
14887
|
+
installImageResizeControlsWithSnap(existingObj);
|
|
13060
14888
|
} else {
|
|
13061
14889
|
existingObj.set({
|
|
13062
14890
|
hasControls: false,
|
|
@@ -13138,7 +14966,7 @@ const PageCanvas = forwardRef(
|
|
|
13138
14966
|
hoverCursor: isDynamicField && isPreviewMode ? "pointer" : void 0
|
|
13139
14967
|
});
|
|
13140
14968
|
if (allowEditing) {
|
|
13141
|
-
|
|
14969
|
+
installImageResizeControlsWithSnap(existingObj);
|
|
13142
14970
|
}
|
|
13143
14971
|
existingObj.setCoords();
|
|
13144
14972
|
fc.requestRenderAll();
|
|
@@ -13864,7 +15692,7 @@ const PageCanvas = forwardRef(
|
|
|
13864
15692
|
return unsub;
|
|
13865
15693
|
}, []);
|
|
13866
15694
|
const updateFabricObject = (obj, element, skipPositionUpdate = false) => {
|
|
13867
|
-
var _a2,
|
|
15695
|
+
var _a2, _b2, _c;
|
|
13868
15696
|
const fc = fabricRef.current;
|
|
13869
15697
|
if (fc && isTransforming(fc)) {
|
|
13870
15698
|
return;
|
|
@@ -13932,11 +15760,12 @@ const PageCanvas = forwardRef(
|
|
|
13932
15760
|
// Disable rotation for crop groups (simplifies resize math)
|
|
13933
15761
|
hasRotatingPoint: false,
|
|
13934
15762
|
// Hide rotation handle
|
|
13935
|
-
//
|
|
13936
|
-
|
|
13937
|
-
|
|
15763
|
+
// Handles are drawn in screen-space — keep them constant on-screen.
|
|
15764
|
+
// Match the global Canva-style defaults (circular dots, pill sides).
|
|
15765
|
+
cornerSize: 10,
|
|
15766
|
+
borderScaleFactor: SELECTION_BORDER_SCALE,
|
|
13938
15767
|
transparentCorners: false,
|
|
13939
|
-
cornerStyle: "
|
|
15768
|
+
cornerStyle: "circle",
|
|
13940
15769
|
cornerColor: SELECTION_PRIMARY,
|
|
13941
15770
|
cornerStrokeColor: "#ffffff",
|
|
13942
15771
|
borderColor: SELECTION_PRIMARY,
|
|
@@ -14046,7 +15875,8 @@ const PageCanvas = forwardRef(
|
|
|
14046
15875
|
obj.clipPath.dirty = true;
|
|
14047
15876
|
obj.clipPath.setCoords();
|
|
14048
15877
|
}
|
|
14049
|
-
|
|
15878
|
+
installImageResizeControlsWithSnap(obj);
|
|
15879
|
+
ensureCanvaControlRenders(obj);
|
|
14050
15880
|
obj.set({
|
|
14051
15881
|
selectable: true,
|
|
14052
15882
|
evented: true,
|
|
@@ -14141,7 +15971,7 @@ const PageCanvas = forwardRef(
|
|
|
14141
15971
|
obj.setCoords();
|
|
14142
15972
|
}
|
|
14143
15973
|
if (!isLine) {
|
|
14144
|
-
const angleTextPathActive = isTextbox && ((
|
|
15974
|
+
const angleTextPathActive = isTextbox && ((_b2 = element.textPath) == null ? void 0 : _b2.preset) === "rise";
|
|
14145
15975
|
const appliedSkewY = angleTextPathActive ? 0 : element.skewY ?? 0;
|
|
14146
15976
|
let posIfNotSkipped = skipPositionUpdate ? {} : { left: fabricPos.left, top: fabricPos.top };
|
|
14147
15977
|
if (!skipPositionUpdate && (obj instanceof fabric.FabricImage && obj.originX === "center" || obj instanceof fabric.Group && obj.__cropGroup)) {
|
|
@@ -14218,7 +16048,17 @@ const PageCanvas = forwardRef(
|
|
|
14218
16048
|
objectCaching: true
|
|
14219
16049
|
});
|
|
14220
16050
|
} else if (obj instanceof fabric.Ellipse) {
|
|
14221
|
-
obj.set({
|
|
16051
|
+
obj.set({
|
|
16052
|
+
rx: cornerSafeW / 2,
|
|
16053
|
+
ry: cornerSafeH / 2,
|
|
16054
|
+
fill: element.fill || "transparent",
|
|
16055
|
+
stroke: element.stroke || "transparent",
|
|
16056
|
+
strokeWidth: element.strokeWidth || 0,
|
|
16057
|
+
strokeUniform: true,
|
|
16058
|
+
strokeLineJoin: "round",
|
|
16059
|
+
strokeLineCap: "round",
|
|
16060
|
+
objectCaching: true
|
|
16061
|
+
});
|
|
14222
16062
|
} else if (obj instanceof fabric.Textbox) {
|
|
14223
16063
|
const overflowPolicy = element.overflowPolicy || "grow-and-push";
|
|
14224
16064
|
let text = element.text || "Text";
|
|
@@ -14412,6 +16252,16 @@ const PageCanvas = forwardRef(
|
|
|
14412
16252
|
strokeUniform: true,
|
|
14413
16253
|
objectCaching: true
|
|
14414
16254
|
});
|
|
16255
|
+
} else if (obj instanceof fabric.Ellipse) {
|
|
16256
|
+
obj.set({
|
|
16257
|
+
rx: cornerSafeW / 2,
|
|
16258
|
+
ry: cornerSafeH / 2,
|
|
16259
|
+
fill: element.fill || "transparent",
|
|
16260
|
+
stroke: element.stroke || "transparent",
|
|
16261
|
+
strokeWidth: element.strokeWidth || 0,
|
|
16262
|
+
strokeUniform: true,
|
|
16263
|
+
objectCaching: true
|
|
16264
|
+
});
|
|
14415
16265
|
} else if (obj instanceof fabric.Rect && element.shapeType === "rounded-rect") {
|
|
14416
16266
|
const toRadius = (value, fallback) => Number.isFinite(value) ? Math.max(0, Number(value)) : fallback;
|
|
14417
16267
|
const baseRx = Math.max(0, Number(element.rx ?? 0));
|
|
@@ -14671,7 +16521,7 @@ const PageCanvas = forwardRef(
|
|
|
14671
16521
|
return Math.max(min, Math.min(max, v));
|
|
14672
16522
|
};
|
|
14673
16523
|
const applyEdgeFadeFrameClipPath = (group, element, frameW, frameH, shape, rxRatio) => {
|
|
14674
|
-
var _a2,
|
|
16524
|
+
var _a2, _b2, _c;
|
|
14675
16525
|
const fadeElement = element;
|
|
14676
16526
|
const fadeGroup = group;
|
|
14677
16527
|
const inputKey = edgeFadeKey(fadeElement);
|
|
@@ -14792,7 +16642,7 @@ const PageCanvas = forwardRef(
|
|
|
14792
16642
|
delete fadeGroup.__edgeFadeRenderConfig;
|
|
14793
16643
|
delete fadeGroup.__edgeFadeKey;
|
|
14794
16644
|
delete fadeGroup.__edgeFadeInputKey;
|
|
14795
|
-
if ((
|
|
16645
|
+
if ((_b2 = group.clipPath) == null ? void 0 : _b2.__edgeFadeMask) {
|
|
14796
16646
|
group.clipPath = void 0;
|
|
14797
16647
|
updateCoverLayout(group);
|
|
14798
16648
|
}
|
|
@@ -14809,7 +16659,7 @@ const PageCanvas = forwardRef(
|
|
|
14809
16659
|
(_c = group.canvas) == null ? void 0 : _c.requestRenderAll();
|
|
14810
16660
|
};
|
|
14811
16661
|
const loadImageAsync2 = async (element, placeholder, fc) => {
|
|
14812
|
-
var _a2,
|
|
16662
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
14813
16663
|
const imageUrl = element.src || element.imageUrl;
|
|
14814
16664
|
if (!imageUrl) return;
|
|
14815
16665
|
const elementId = element.id;
|
|
@@ -14840,7 +16690,7 @@ const PageCanvas = forwardRef(
|
|
|
14840
16690
|
await normalizeSvgImageDimensions(img, imageUrl, element.sourceFormat);
|
|
14841
16691
|
if (!isLatestRequest()) return;
|
|
14842
16692
|
const imageFitForFade = element.imageFit || ((_a2 = element.style) == null ? void 0 : _a2.imageFit) || "cover";
|
|
14843
|
-
const clipShapeForFade = element.clipShape ?? ((
|
|
16693
|
+
const clipShapeForFade = element.clipShape ?? ((_b2 = element.style) == null ? void 0 : _b2.imageFrameShape) ?? (isPreviewMode ? "rectangle" : "none");
|
|
14844
16694
|
const willUseCropGroupForFade = imageFitForFade !== "fill" || clipShapeForFade && clipShapeForFade !== "none";
|
|
14845
16695
|
try {
|
|
14846
16696
|
if (hasEdgeFade(element) && !willUseCropGroupForFade) {
|
|
@@ -15058,7 +16908,7 @@ const PageCanvas = forwardRef(
|
|
|
15058
16908
|
evented: canBeEvented && !isHidden
|
|
15059
16909
|
});
|
|
15060
16910
|
} else {
|
|
15061
|
-
|
|
16911
|
+
installImageResizeControlsWithSnap(cropGroup);
|
|
15062
16912
|
}
|
|
15063
16913
|
const cropImg = (_o = cropGroup.__cropData) == null ? void 0 : _o._img;
|
|
15064
16914
|
if (cropImg) {
|
|
@@ -15269,38 +17119,7 @@ const PageCanvas = forwardRef(
|
|
|
15269
17119
|
),
|
|
15270
17120
|
sectionsOverlay,
|
|
15271
17121
|
groupBoundsOverlay,
|
|
15272
|
-
|
|
15273
|
-
"svg",
|
|
15274
|
-
{
|
|
15275
|
-
className: "absolute inset-0 pointer-events-none",
|
|
15276
|
-
style: { width: scaledWidth, height: scaledHeight },
|
|
15277
|
-
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
15278
|
-
children: [
|
|
15279
|
-
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
15280
|
-
"pattern",
|
|
15281
|
-
{
|
|
15282
|
-
id: `pixldocs-grid-${pageId}`,
|
|
15283
|
-
width: canvas.projectSettings.gridSize,
|
|
15284
|
-
height: canvas.projectSettings.gridSize,
|
|
15285
|
-
patternUnits: "userSpaceOnUse",
|
|
15286
|
-
children: /* @__PURE__ */ jsx(
|
|
15287
|
-
"path",
|
|
15288
|
-
{
|
|
15289
|
-
d: `M ${canvas.projectSettings.gridSize} 0 L 0 0 0 ${canvas.projectSettings.gridSize}`,
|
|
15290
|
-
fill: "none",
|
|
15291
|
-
stroke: "currentColor",
|
|
15292
|
-
strokeWidth: 0.5,
|
|
15293
|
-
opacity: 0.18,
|
|
15294
|
-
className: "text-foreground"
|
|
15295
|
-
}
|
|
15296
|
-
)
|
|
15297
|
-
}
|
|
15298
|
-
) }),
|
|
15299
|
-
/* @__PURE__ */ jsx("rect", { width: canvasWidth, height: canvasHeight, fill: `url(#pixldocs-grid-${pageId})` })
|
|
15300
|
-
]
|
|
15301
|
-
}
|
|
15302
|
-
),
|
|
15303
|
-
hoverBounds && !guides.length && /* @__PURE__ */ jsx(
|
|
17122
|
+
hoverBounds && !guides.length && !(selectedIdsRef.current && selectedIdsRef.current.length) && /* @__PURE__ */ jsx(
|
|
15304
17123
|
"svg",
|
|
15305
17124
|
{
|
|
15306
17125
|
className: "absolute inset-0 pointer-events-none",
|
|
@@ -15314,108 +17133,177 @@ const PageCanvas = forwardRef(
|
|
|
15314
17133
|
width: hoverBounds.width,
|
|
15315
17134
|
height: hoverBounds.height,
|
|
15316
17135
|
fill: "none",
|
|
15317
|
-
stroke:
|
|
15318
|
-
strokeWidth:
|
|
17136
|
+
stroke: SELECTION_PRIMARY,
|
|
17137
|
+
strokeWidth: 2,
|
|
17138
|
+
vectorEffect: "non-scaling-stroke",
|
|
15319
17139
|
strokeDasharray: "0",
|
|
15320
|
-
opacity:
|
|
17140
|
+
opacity: 1
|
|
15321
17141
|
}
|
|
15322
17142
|
)
|
|
15323
17143
|
}
|
|
15324
17144
|
),
|
|
15325
|
-
|
|
17145
|
+
canvas.projectSettings.showGrid && (() => {
|
|
17146
|
+
const ps = canvas.projectSettings;
|
|
17147
|
+
const gx = Math.max(1, ps.gridSizeX ?? ps.gridSize ?? 0);
|
|
17148
|
+
const gy = Math.max(1, ps.gridSizeY ?? ps.gridSize ?? 0);
|
|
17149
|
+
if (gx <= 0 || gy <= 0) return null;
|
|
17150
|
+
return /* @__PURE__ */ jsxs(
|
|
17151
|
+
"svg",
|
|
17152
|
+
{
|
|
17153
|
+
className: "absolute inset-0 pointer-events-none",
|
|
17154
|
+
style: { width: scaledWidth, height: scaledHeight },
|
|
17155
|
+
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
17156
|
+
children: [
|
|
17157
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
17158
|
+
"pattern",
|
|
17159
|
+
{
|
|
17160
|
+
id: `pixldocs-grid-${pageId}`,
|
|
17161
|
+
width: gx,
|
|
17162
|
+
height: gy,
|
|
17163
|
+
patternUnits: "userSpaceOnUse",
|
|
17164
|
+
children: /* @__PURE__ */ jsx(
|
|
17165
|
+
"path",
|
|
17166
|
+
{
|
|
17167
|
+
d: `M ${gx} 0 L 0 0 0 ${gy}`,
|
|
17168
|
+
fill: "none",
|
|
17169
|
+
stroke: ps.gridColor || "#0f172a",
|
|
17170
|
+
strokeWidth: 0.5,
|
|
17171
|
+
opacity: 0.22
|
|
17172
|
+
}
|
|
17173
|
+
)
|
|
17174
|
+
}
|
|
17175
|
+
) }),
|
|
17176
|
+
/* @__PURE__ */ jsx("rect", { width: canvasWidth, height: canvasHeight, fill: `url(#pixldocs-grid-${pageId})` })
|
|
17177
|
+
]
|
|
17178
|
+
}
|
|
17179
|
+
);
|
|
17180
|
+
})(),
|
|
17181
|
+
guides.length > 0 && /* @__PURE__ */ jsxs(
|
|
15326
17182
|
"svg",
|
|
15327
17183
|
{
|
|
15328
17184
|
className: "absolute inset-0 pointer-events-none",
|
|
15329
17185
|
style: { width: scaledWidth, height: scaledHeight },
|
|
15330
17186
|
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
15331
|
-
children:
|
|
15332
|
-
|
|
15333
|
-
|
|
15334
|
-
|
|
15335
|
-
const
|
|
15336
|
-
|
|
15337
|
-
|
|
15338
|
-
|
|
15339
|
-
|
|
15340
|
-
|
|
15341
|
-
|
|
15342
|
-
|
|
15343
|
-
|
|
15344
|
-
|
|
15345
|
-
|
|
15346
|
-
|
|
15347
|
-
|
|
15348
|
-
|
|
17187
|
+
children: [
|
|
17188
|
+
(() => {
|
|
17189
|
+
const seenBoxes = /* @__PURE__ */ new Set();
|
|
17190
|
+
const boxes = [];
|
|
17191
|
+
for (const g of guides) {
|
|
17192
|
+
const list = g.targetBoundsList ?? (g.targetBounds ? [g.targetBounds] : []);
|
|
17193
|
+
for (const b of list) {
|
|
17194
|
+
const key = `${b.left.toFixed(1)}-${b.top.toFixed(1)}-${b.width.toFixed(1)}-${b.height.toFixed(1)}`;
|
|
17195
|
+
if (seenBoxes.has(key)) continue;
|
|
17196
|
+
seenBoxes.add(key);
|
|
17197
|
+
boxes.push(b);
|
|
17198
|
+
}
|
|
17199
|
+
}
|
|
17200
|
+
return boxes.map((b, i) => /* @__PURE__ */ jsx(
|
|
17201
|
+
"rect",
|
|
17202
|
+
{
|
|
17203
|
+
x: b.left,
|
|
17204
|
+
y: b.top,
|
|
17205
|
+
width: b.width,
|
|
17206
|
+
height: b.height,
|
|
17207
|
+
fill: "none",
|
|
17208
|
+
stroke: "#f43f5e",
|
|
17209
|
+
strokeWidth: 1.5,
|
|
17210
|
+
strokeDasharray: "4,3",
|
|
17211
|
+
opacity: 0.9,
|
|
17212
|
+
vectorEffect: "non-scaling-stroke"
|
|
17213
|
+
},
|
|
17214
|
+
`tb-${i}`
|
|
17215
|
+
));
|
|
17216
|
+
})(),
|
|
17217
|
+
(() => {
|
|
17218
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17219
|
+
return guides.filter((guide) => {
|
|
17220
|
+
if (guide.kind === "gap") return true;
|
|
17221
|
+
const key = `${guide.type}-${guide.position.toFixed(1)}`;
|
|
17222
|
+
if (seen.has(key)) return false;
|
|
17223
|
+
seen.add(key);
|
|
17224
|
+
return true;
|
|
17225
|
+
}).map((guide, i) => {
|
|
17226
|
+
if (guide.kind === "gap" && guide.gap != null && guide.start != null && guide.end != null) {
|
|
17227
|
+
const gapColor = "#ec4899";
|
|
17228
|
+
const label = `${guide.gap}`;
|
|
17229
|
+
const labelW2 = Math.max(22, label.length * 7 + 8);
|
|
17230
|
+
if (guide.type === "horizontal") {
|
|
17231
|
+
const y = guide.bracketAt ?? guide.position;
|
|
17232
|
+
const x1 = guide.start;
|
|
17233
|
+
const x2 = guide.end;
|
|
17234
|
+
const mid = (x1 + x2) / 2;
|
|
17235
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
17236
|
+
/* @__PURE__ */ jsx("line", { x1, y1: y, x2, y2: y, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17237
|
+
/* @__PURE__ */ jsx("line", { x1, y1: y - 4, x2: x1, y2: y + 4, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17238
|
+
/* @__PURE__ */ jsx("line", { x1: x2, y1: y - 4, x2, y2: y + 4, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17239
|
+
/* @__PURE__ */ jsxs("g", { transform: `translate(${mid}, ${y - 12})`, children: [
|
|
17240
|
+
/* @__PURE__ */ jsx("rect", { x: -labelW2 / 2, y: -9, width: labelW2, height: 16, rx: 4, fill: gapColor }),
|
|
17241
|
+
/* @__PURE__ */ jsx("text", { x: 0, y: 3, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 600, children: label })
|
|
17242
|
+
] })
|
|
17243
|
+
] }, i);
|
|
17244
|
+
} else {
|
|
17245
|
+
const x = guide.bracketAt ?? guide.position;
|
|
17246
|
+
const y1 = guide.start;
|
|
17247
|
+
const y2 = guide.end;
|
|
17248
|
+
const mid = (y1 + y2) / 2;
|
|
17249
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
17250
|
+
/* @__PURE__ */ jsx("line", { x1: x, y1, x2: x, y2, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17251
|
+
/* @__PURE__ */ jsx("line", { x1: x - 4, y1, x2: x + 4, y2: y1, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17252
|
+
/* @__PURE__ */ jsx("line", { x1: x - 4, y1: y2, x2: x + 4, y2, stroke: gapColor, strokeWidth: 1.75, vectorEffect: "non-scaling-stroke" }),
|
|
17253
|
+
/* @__PURE__ */ jsxs("g", { transform: `translate(${x + 12}, ${mid})`, children: [
|
|
17254
|
+
/* @__PURE__ */ jsx("rect", { x: -labelW2 / 2, y: -9, width: labelW2, height: 16, rx: 4, fill: gapColor }),
|
|
17255
|
+
/* @__PURE__ */ jsx("text", { x: 0, y: 3, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 600, children: label })
|
|
17256
|
+
] })
|
|
17257
|
+
] }, i);
|
|
17258
|
+
}
|
|
17259
|
+
}
|
|
17260
|
+
const isElementRelative = guide.start !== void 0 && guide.end !== void 0;
|
|
17261
|
+
const isActive2 = guide.active === true;
|
|
17262
|
+
const isGrid = guide.kind === "grid";
|
|
17263
|
+
const strokeColor = isGrid ? "#f59e0b" : isActive2 ? "#22c55e" : isElementRelative ? "#f43f5e" : "#ec4899";
|
|
17264
|
+
const strokeWidth = isGrid ? 1.75 : 1.75;
|
|
17265
|
+
const strokeDasharray = isGrid ? "2,3" : isActive2 ? "none" : isElementRelative ? "3,3" : "4,4";
|
|
17266
|
+
const showDistance = typeof guide.distance === "number";
|
|
17267
|
+
const labelText = showDistance ? String(Math.round(guide.distance)) : "";
|
|
17268
|
+
const labelW = Math.max(24, labelText.length * 7);
|
|
17269
|
+
if (guide.type === "vertical") {
|
|
17270
|
+
const padding = isElementRelative || isActive2 ? 20 : 0;
|
|
17271
|
+
const y1 = guide.start != null && guide.end != null ? Math.max(0, guide.start - padding) : 0;
|
|
17272
|
+
const y2 = guide.start != null && guide.end != null ? Math.min(canvasHeight, guide.end + padding) : canvasHeight;
|
|
17273
|
+
const labelY = guide.start != null && guide.end != null ? (guide.start + guide.end) / 2 : canvasHeight / 2;
|
|
15349
17274
|
return /* @__PURE__ */ jsxs("g", { children: [
|
|
15350
|
-
/* @__PURE__ */ jsx("line", { x1, y1
|
|
15351
|
-
/* @__PURE__ */ jsx("
|
|
15352
|
-
/* @__PURE__ */
|
|
15353
|
-
|
|
15354
|
-
/* @__PURE__ */ jsx("
|
|
15355
|
-
|
|
17275
|
+
/* @__PURE__ */ jsx("line", { x1: guide.position, y1, x2: guide.position, y2, stroke: strokeColor, strokeWidth, strokeDasharray, vectorEffect: "non-scaling-stroke" }),
|
|
17276
|
+
isActive2 && /* @__PURE__ */ jsx("circle", { cx: guide.position, cy: y2, r: 4, fill: "#22c55e", opacity: 0.9 }),
|
|
17277
|
+
isElementRelative && !isActive2 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
17278
|
+
/* @__PURE__ */ jsx("circle", { cx: guide.position, cy: y1, r: 2, fill: "#f43f5e" }),
|
|
17279
|
+
/* @__PURE__ */ jsx("circle", { cx: guide.position, cy: y2, r: 2, fill: "#f43f5e" })
|
|
17280
|
+
] }),
|
|
17281
|
+
showDistance && /* @__PURE__ */ jsxs("g", { transform: `translate(${guide.position + 6}, ${labelY})`, children: [
|
|
17282
|
+
/* @__PURE__ */ jsx("rect", { x: -2, y: -9, width: labelW, height: 16, rx: 4, fill: "rgba(0,0,0,0.75)" }),
|
|
17283
|
+
/* @__PURE__ */ jsx("text", { x: labelW / 2 - 2, y: 4, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 500, children: labelText })
|
|
15356
17284
|
] })
|
|
15357
17285
|
] }, i);
|
|
15358
17286
|
} else {
|
|
15359
|
-
const
|
|
15360
|
-
const
|
|
15361
|
-
const
|
|
15362
|
-
const
|
|
17287
|
+
const padding = isElementRelative || isActive2 ? 20 : 0;
|
|
17288
|
+
const x1 = guide.start != null && guide.end != null ? Math.max(0, guide.start - padding) : 0;
|
|
17289
|
+
const x2 = guide.start != null && guide.end != null ? Math.min(canvasWidth, guide.end + padding) : canvasWidth;
|
|
17290
|
+
const labelX = guide.start != null && guide.end != null ? (guide.start + guide.end) / 2 : canvasWidth / 2;
|
|
15363
17291
|
return /* @__PURE__ */ jsxs("g", { children: [
|
|
15364
|
-
/* @__PURE__ */ jsx("line", { x1
|
|
15365
|
-
/* @__PURE__ */ jsx("
|
|
15366
|
-
/* @__PURE__ */
|
|
15367
|
-
|
|
15368
|
-
/* @__PURE__ */ jsx("
|
|
15369
|
-
|
|
17292
|
+
/* @__PURE__ */ jsx("line", { x1, y1: guide.position, x2, y2: guide.position, stroke: strokeColor, strokeWidth, strokeDasharray, vectorEffect: "non-scaling-stroke" }),
|
|
17293
|
+
isActive2 && /* @__PURE__ */ jsx("circle", { cx: x2, cy: guide.position, r: 4, fill: "#22c55e", opacity: 0.9 }),
|
|
17294
|
+
isElementRelative && !isActive2 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
17295
|
+
/* @__PURE__ */ jsx("circle", { cx: x1, cy: guide.position, r: 2, fill: "#f43f5e" }),
|
|
17296
|
+
/* @__PURE__ */ jsx("circle", { cx: x2, cy: guide.position, r: 2, fill: "#f43f5e" })
|
|
17297
|
+
] }),
|
|
17298
|
+
showDistance && /* @__PURE__ */ jsxs("g", { transform: `translate(${labelX}, ${guide.position - 10})`, children: [
|
|
17299
|
+
/* @__PURE__ */ jsx("rect", { x: -2, y: -9, width: labelW, height: 16, rx: 4, fill: "rgba(0,0,0,0.75)" }),
|
|
17300
|
+
/* @__PURE__ */ jsx("text", { x: labelW / 2 - 2, y: 4, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 500, children: labelText })
|
|
15370
17301
|
] })
|
|
15371
17302
|
] }, i);
|
|
15372
17303
|
}
|
|
15373
|
-
}
|
|
15374
|
-
|
|
15375
|
-
|
|
15376
|
-
const strokeColor = isActive2 ? "#22c55e" : isElementRelative ? "#f43f5e" : "#3b82f6";
|
|
15377
|
-
const strokeWidth = isActive2 ? 2.5 : 1;
|
|
15378
|
-
const strokeDasharray = isActive2 ? "none" : isElementRelative ? "3,3" : "4,4";
|
|
15379
|
-
const showDistance = typeof guide.distance === "number";
|
|
15380
|
-
const labelText = showDistance ? String(Math.round(guide.distance)) : "";
|
|
15381
|
-
const labelW = Math.max(24, labelText.length * 7);
|
|
15382
|
-
if (guide.type === "vertical") {
|
|
15383
|
-
const padding = isElementRelative || isActive2 ? 20 : 0;
|
|
15384
|
-
const y1 = guide.start != null && guide.end != null ? Math.max(0, guide.start - padding) : 0;
|
|
15385
|
-
const y2 = guide.start != null && guide.end != null ? Math.min(canvasHeight, guide.end + padding) : canvasHeight;
|
|
15386
|
-
const labelY = guide.start != null && guide.end != null ? (guide.start + guide.end) / 2 : canvasHeight / 2;
|
|
15387
|
-
return /* @__PURE__ */ jsxs("g", { children: [
|
|
15388
|
-
/* @__PURE__ */ jsx("line", { x1: guide.position, y1, x2: guide.position, y2, stroke: strokeColor, strokeWidth, strokeDasharray }),
|
|
15389
|
-
isActive2 && /* @__PURE__ */ jsx("circle", { cx: guide.position, cy: y2, r: 4, fill: "#22c55e", opacity: 0.9 }),
|
|
15390
|
-
isElementRelative && !isActive2 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
15391
|
-
/* @__PURE__ */ jsx("circle", { cx: guide.position, cy: y1, r: 2, fill: "#f43f5e" }),
|
|
15392
|
-
/* @__PURE__ */ jsx("circle", { cx: guide.position, cy: y2, r: 2, fill: "#f43f5e" })
|
|
15393
|
-
] }),
|
|
15394
|
-
showDistance && /* @__PURE__ */ jsxs("g", { transform: `translate(${guide.position + 6}, ${labelY})`, children: [
|
|
15395
|
-
/* @__PURE__ */ jsx("rect", { x: -2, y: -9, width: labelW, height: 16, rx: 4, fill: "rgba(0,0,0,0.75)" }),
|
|
15396
|
-
/* @__PURE__ */ jsx("text", { x: labelW / 2 - 2, y: 4, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 500, children: labelText })
|
|
15397
|
-
] })
|
|
15398
|
-
] }, i);
|
|
15399
|
-
} else {
|
|
15400
|
-
const padding = isElementRelative || isActive2 ? 20 : 0;
|
|
15401
|
-
const x1 = guide.start != null && guide.end != null ? Math.max(0, guide.start - padding) : 0;
|
|
15402
|
-
const x2 = guide.start != null && guide.end != null ? Math.min(canvasWidth, guide.end + padding) : canvasWidth;
|
|
15403
|
-
const labelX = guide.start != null && guide.end != null ? (guide.start + guide.end) / 2 : canvasWidth / 2;
|
|
15404
|
-
return /* @__PURE__ */ jsxs("g", { children: [
|
|
15405
|
-
/* @__PURE__ */ jsx("line", { x1, y1: guide.position, x2, y2: guide.position, stroke: strokeColor, strokeWidth, strokeDasharray }),
|
|
15406
|
-
isActive2 && /* @__PURE__ */ jsx("circle", { cx: x2, cy: guide.position, r: 4, fill: "#22c55e", opacity: 0.9 }),
|
|
15407
|
-
isElementRelative && !isActive2 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
15408
|
-
/* @__PURE__ */ jsx("circle", { cx: x1, cy: guide.position, r: 2, fill: "#f43f5e" }),
|
|
15409
|
-
/* @__PURE__ */ jsx("circle", { cx: x2, cy: guide.position, r: 2, fill: "#f43f5e" })
|
|
15410
|
-
] }),
|
|
15411
|
-
showDistance && /* @__PURE__ */ jsxs("g", { transform: `translate(${labelX}, ${guide.position - 10})`, children: [
|
|
15412
|
-
/* @__PURE__ */ jsx("rect", { x: -2, y: -9, width: labelW, height: 16, rx: 4, fill: "rgba(0,0,0,0.75)" }),
|
|
15413
|
-
/* @__PURE__ */ jsx("text", { x: labelW / 2 - 2, y: 4, textAnchor: "middle", fill: "#fff", fontSize: 10, fontFamily: "system-ui, sans-serif", fontWeight: 500, children: labelText })
|
|
15414
|
-
] })
|
|
15415
|
-
] }, i);
|
|
15416
|
-
}
|
|
15417
|
-
});
|
|
15418
|
-
})()
|
|
17304
|
+
});
|
|
17305
|
+
})()
|
|
17306
|
+
]
|
|
15419
17307
|
}
|
|
15420
17308
|
),
|
|
15421
17309
|
gridResizeLabel && /* @__PURE__ */ jsx(
|
|
@@ -15551,13 +17439,13 @@ function PreviewCanvas({
|
|
|
15551
17439
|
onDynamicFieldClick,
|
|
15552
17440
|
onReady
|
|
15553
17441
|
}) {
|
|
15554
|
-
var _a2,
|
|
17442
|
+
var _a2, _b2, _c, _d, _e;
|
|
15555
17443
|
const canvasRef = useRef(null);
|
|
15556
17444
|
const containerRef = useRef(null);
|
|
15557
17445
|
const [containerWidth, setContainerWidth] = useState(0);
|
|
15558
17446
|
const [hoveredFieldId, setHoveredFieldId] = useState(null);
|
|
15559
17447
|
const page = (_a2 = config == null ? void 0 : config.pages) == null ? void 0 : _a2[pageIndex];
|
|
15560
|
-
const canvasWidth = ((
|
|
17448
|
+
const canvasWidth = ((_b2 = config == null ? void 0 : config.canvas) == null ? void 0 : _b2.width) || 612;
|
|
15561
17449
|
const canvasHeight = ((_c = config == null ? void 0 : config.canvas) == null ? void 0 : _c.height) || 792;
|
|
15562
17450
|
const elementToFieldMap = useMemo(
|
|
15563
17451
|
() => buildElementToFieldMap(config == null ? void 0 : config.dynamicFields),
|
|
@@ -15607,14 +17495,14 @@ function PreviewCanvas({
|
|
|
15607
17495
|
}
|
|
15608
17496
|
}, [elements]);
|
|
15609
17497
|
const pageSettings = useMemo(() => {
|
|
15610
|
-
var _a3,
|
|
17498
|
+
var _a3, _b3;
|
|
15611
17499
|
return {
|
|
15612
17500
|
backgroundColor: ((_a3 = page == null ? void 0 : page.settings) == null ? void 0 : _a3.backgroundColor) || "#ffffff",
|
|
15613
|
-
backgroundGradient: (
|
|
17501
|
+
backgroundGradient: (_b3 = page == null ? void 0 : page.settings) == null ? void 0 : _b3.backgroundGradient
|
|
15614
17502
|
};
|
|
15615
17503
|
}, [(_d = page == null ? void 0 : page.settings) == null ? void 0 : _d.backgroundColor, (_e = page == null ? void 0 : page.settings) == null ? void 0 : _e.backgroundGradient]);
|
|
15616
17504
|
const projectSettings = useMemo(() => {
|
|
15617
|
-
var _a3,
|
|
17505
|
+
var _a3, _b3, _c2;
|
|
15618
17506
|
const vars = ((_a3 = config.themeConfig) == null ? void 0 : _a3.variables) || {};
|
|
15619
17507
|
return {
|
|
15620
17508
|
showGrid: false,
|
|
@@ -15622,7 +17510,7 @@ function PreviewCanvas({
|
|
|
15622
17510
|
gridSize: 10,
|
|
15623
17511
|
snapToGuides: false,
|
|
15624
17512
|
snapThreshold: 5,
|
|
15625
|
-
primaryColor: (
|
|
17513
|
+
primaryColor: (_b3 = vars.primary) == null ? void 0 : _b3.value,
|
|
15626
17514
|
secondaryColor: (_c2 = vars.secondary) == null ? void 0 : _c2.value
|
|
15627
17515
|
};
|
|
15628
17516
|
}, [config.themeConfig]);
|
|
@@ -15774,7 +17662,7 @@ const PreviewCanvas$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
|
|
|
15774
17662
|
PreviewCanvas
|
|
15775
17663
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
15776
17664
|
function applyThemeToConfig(config, themeOverrides) {
|
|
15777
|
-
var _a2,
|
|
17665
|
+
var _a2, _b2, _c;
|
|
15778
17666
|
if (!themeOverrides || Object.keys(themeOverrides).length === 0) return config;
|
|
15779
17667
|
const cloned = JSON.parse(JSON.stringify(config));
|
|
15780
17668
|
if ((_a2 = cloned.themeConfig) == null ? void 0 : _a2.variables) {
|
|
@@ -15785,7 +17673,7 @@ function applyThemeToConfig(config, themeOverrides) {
|
|
|
15785
17673
|
}
|
|
15786
17674
|
}
|
|
15787
17675
|
const varMap = /* @__PURE__ */ new Map();
|
|
15788
|
-
if ((
|
|
17676
|
+
if ((_b2 = cloned.themeConfig) == null ? void 0 : _b2.variables) {
|
|
15789
17677
|
for (const [key, def] of Object.entries(cloned.themeConfig.variables)) {
|
|
15790
17678
|
varMap.set(key, themeOverrides[key] ?? def.value);
|
|
15791
17679
|
}
|
|
@@ -15822,7 +17710,7 @@ function mapFormDefFieldType(t) {
|
|
|
15822
17710
|
function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
15823
17711
|
const sections = [];
|
|
15824
17712
|
function convert(defs, parentId) {
|
|
15825
|
-
var _a2,
|
|
17713
|
+
var _a2, _b2;
|
|
15826
17714
|
for (const def of defs) {
|
|
15827
17715
|
const isRepeatable = def.repeatable === true || def.type === "repeatable";
|
|
15828
17716
|
const defFields = def.fields ?? def.entryFields ?? [];
|
|
@@ -15874,7 +17762,7 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
15874
17762
|
placeholder: f.placeholder
|
|
15875
17763
|
}))
|
|
15876
17764
|
});
|
|
15877
|
-
if ((
|
|
17765
|
+
if ((_b2 = def.children) == null ? void 0 : _b2.length) {
|
|
15878
17766
|
convert(def.children, def.id);
|
|
15879
17767
|
}
|
|
15880
17768
|
}
|
|
@@ -16503,7 +18391,7 @@ function findAllRepeatableElementsBySourceId(pages, baseNodeId, oneBasedIndex, s
|
|
|
16503
18391
|
return out;
|
|
16504
18392
|
}
|
|
16505
18393
|
function findNestedRepeatableElementBySourceId(pages, parentBaseNodeId, parentPi, childBaseNodeId, childCi, sourceElementId) {
|
|
16506
|
-
var _a2,
|
|
18394
|
+
var _a2, _b2;
|
|
16507
18395
|
const parentGroups = collectGroupsByBaseId(pages, parentBaseNodeId);
|
|
16508
18396
|
const parentGroup = parentGroups[parentPi - 1];
|
|
16509
18397
|
if (!parentGroup || !isGroup(parentGroup) || !((_a2 = parentGroup.children) == null ? void 0 : _a2.length)) return void 0;
|
|
@@ -16518,7 +18406,7 @@ function findNestedRepeatableElementBySourceId(pages, parentBaseNodeId, parentPi
|
|
|
16518
18406
|
}
|
|
16519
18407
|
collectChild(parentGroup.children);
|
|
16520
18408
|
const childGroup = childGroups[childCi - 1];
|
|
16521
|
-
if (!childGroup || !isGroup(childGroup) || !((
|
|
18409
|
+
if (!childGroup || !isGroup(childGroup) || !((_b2 = childGroup.children) == null ? void 0 : _b2.length)) return void 0;
|
|
16522
18410
|
return findElementBySourceIdInSubtree(childGroup.children, sourceElementId) ?? (childGroup.__sourceId === sourceElementId ? childGroup.id : void 0);
|
|
16523
18411
|
}
|
|
16524
18412
|
function repeatableLabelKey(label) {
|
|
@@ -16568,7 +18456,7 @@ function getRepeatableFromConfig(pages) {
|
|
|
16568
18456
|
var _a2;
|
|
16569
18457
|
const result = [];
|
|
16570
18458
|
function walk(children) {
|
|
16571
|
-
var _a3,
|
|
18459
|
+
var _a3, _b2;
|
|
16572
18460
|
if (!children) return;
|
|
16573
18461
|
for (const node of children) {
|
|
16574
18462
|
if (isGroup(node) && isVerticalStackLayoutMode(node.layoutMode) && ((_a3 = node.children) == null ? void 0 : _a3.length)) {
|
|
@@ -16577,7 +18465,7 @@ function getRepeatableFromConfig(pages) {
|
|
|
16577
18465
|
if (rep == null ? void 0 : rep.label) result.push({ nodeId: child.id, label: rep.label });
|
|
16578
18466
|
}
|
|
16579
18467
|
}
|
|
16580
|
-
if (isGroup(node) && ((
|
|
18468
|
+
if (isGroup(node) && ((_b2 = node.children) == null ? void 0 : _b2.length)) walk(node.children);
|
|
16581
18469
|
}
|
|
16582
18470
|
}
|
|
16583
18471
|
for (const page of pages) if ((_a2 = page.children) == null ? void 0 : _a2.length) walk(page.children);
|
|
@@ -16593,7 +18481,7 @@ function findRepeatableByNodeIds(pages, nodeIds) {
|
|
|
16593
18481
|
return !!((_a3 = n.repeatableSection) == null ? void 0 : _a3.label);
|
|
16594
18482
|
};
|
|
16595
18483
|
function walk(children, parentRepeatableBaseId, parentInfo, parentRepeatableEntryIndex) {
|
|
16596
|
-
var _a3,
|
|
18484
|
+
var _a3, _b2;
|
|
16597
18485
|
if (!Array.isArray(children)) return;
|
|
16598
18486
|
for (let i = 0; i < children.length; i++) {
|
|
16599
18487
|
const node = children[i];
|
|
@@ -16636,7 +18524,7 @@ function findRepeatableByNodeIds(pages, nodeIds) {
|
|
|
16636
18524
|
if (isGroup(child) && Array.isArray(child.children)) walk(child.children, effectiveChildBase, void 0, childEntryIndex);
|
|
16637
18525
|
j += count;
|
|
16638
18526
|
}
|
|
16639
|
-
} else if (isGroup(node) && ((
|
|
18527
|
+
} else if (isGroup(node) && ((_b2 = node.children) == null ? void 0 : _b2.length)) {
|
|
16640
18528
|
const nodeBase = baseId(node.id);
|
|
16641
18529
|
const selfMatch = schemaBaseIds.has(node.id) || schemaBaseIds.has(nodeBase) || node.__baseNodeId != null && schemaBaseIds.has(node.__baseNodeId);
|
|
16642
18530
|
const isSelfRepeatable = selfMatch && hasRepeatableSection(node);
|
|
@@ -16725,7 +18613,7 @@ function getNestedRepeatableEntryCount(parentId, parentIndex, childId, formValue
|
|
|
16725
18613
|
return Math.max(1, maxIndex);
|
|
16726
18614
|
}
|
|
16727
18615
|
function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsFromSchema, repeatableEntryCounts, repeatableNestedEntryCounts, displayFormatMap, repeatablePagesFromSchema) {
|
|
16728
|
-
var _a2,
|
|
18616
|
+
var _a2, _b2, _c;
|
|
16729
18617
|
const cloned = JSON.parse(JSON.stringify(config));
|
|
16730
18618
|
if (!cloned.pages) return cloned;
|
|
16731
18619
|
const dynamicFields = cloned.dynamicFields;
|
|
@@ -16906,7 +18794,7 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
|
|
|
16906
18794
|
const { node, baseNodeId, startIndex, count } = block;
|
|
16907
18795
|
const occIdx = block.__occurrenceIndex ?? 1;
|
|
16908
18796
|
const N = computeN(baseNodeId, node.id);
|
|
16909
|
-
const entryFilter = ((
|
|
18797
|
+
const entryFilter = ((_b2 = node.repeatableSection) == null ? void 0 : _b2.entryFilter) ?? entryFilterFromList(baseNodeId);
|
|
16910
18798
|
let entryIndices;
|
|
16911
18799
|
if (entryFilter && entryFilter.mode === "range" && entryFilter.range) {
|
|
16912
18800
|
const parsed = parseEntryRange(entryFilter.range, N, entryMetaFromList(baseNodeId));
|
|
@@ -17363,7 +19251,7 @@ function findAllFlowStacks(pageChildren) {
|
|
|
17363
19251
|
return result;
|
|
17364
19252
|
}
|
|
17365
19253
|
function findNestedFlowStack(entry) {
|
|
17366
|
-
var _a2,
|
|
19254
|
+
var _a2, _b2;
|
|
17367
19255
|
const queue = [...entry.children ?? []];
|
|
17368
19256
|
while (queue.length > 0) {
|
|
17369
19257
|
const node = queue.shift();
|
|
@@ -17371,7 +19259,7 @@ function findNestedFlowStack(entry) {
|
|
|
17371
19259
|
const g = node;
|
|
17372
19260
|
const hasRepeatableChildren = ((_a2 = g.children) == null ? void 0 : _a2.length) && (g.children.some(hasBaseNodeId) || g.children.some((c) => isGroup(c)));
|
|
17373
19261
|
if (isVerticalStackLayoutMode(g.layoutMode) && hasRepeatableChildren) return g;
|
|
17374
|
-
if ((
|
|
19262
|
+
if ((_b2 = g.children) == null ? void 0 : _b2.length) queue.push(...g.children);
|
|
17375
19263
|
}
|
|
17376
19264
|
return null;
|
|
17377
19265
|
}
|
|
@@ -17502,9 +19390,9 @@ function splitNestedForOverflow(flowStack, stayChildren, overflowChildren, overf
|
|
|
17502
19390
|
return { stayChildren: newStay, overflowChildren: newOverflow };
|
|
17503
19391
|
}
|
|
17504
19392
|
function paginateSinglePage(sourcePage, pageOffsetIndex) {
|
|
17505
|
-
var _a2,
|
|
19393
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
17506
19394
|
const contentTop = (_a2 = sourcePage.settings) == null ? void 0 : _a2.contentTop;
|
|
17507
|
-
const contentBottom = (
|
|
19395
|
+
const contentBottom = (_b2 = sourcePage.settings) == null ? void 0 : _b2.contentBottom;
|
|
17508
19396
|
if (contentTop == null || contentBottom == null || contentBottom <= contentTop) {
|
|
17509
19397
|
return [sourcePage];
|
|
17510
19398
|
}
|
|
@@ -18694,7 +20582,7 @@ function splitIntoRuns(text, mainSupportsChar) {
|
|
|
18694
20582
|
return runs;
|
|
18695
20583
|
}
|
|
18696
20584
|
function rewriteSvgFontsForJsPDF(svgStr) {
|
|
18697
|
-
var _a2,
|
|
20585
|
+
var _a2, _b2;
|
|
18698
20586
|
const parser = new DOMParser();
|
|
18699
20587
|
const doc = parser.parseFromString(svgStr, "image/svg+xml");
|
|
18700
20588
|
const allTextEls = Array.from(doc.querySelectorAll("text, tspan, textPath"));
|
|
@@ -18799,7 +20687,7 @@ function rewriteSvgFontsForJsPDF(svgStr) {
|
|
|
18799
20687
|
for (const node of childNodes) {
|
|
18800
20688
|
if (node.nodeType !== 3 || !node.textContent) continue;
|
|
18801
20689
|
const runs = splitIntoRuns(node.textContent, mainSupportsChar);
|
|
18802
|
-
if (runs.length <= 1 && ((
|
|
20690
|
+
if (runs.length <= 1 && ((_b2 = runs[0]) == null ? void 0 : _b2.runType) === "main") continue;
|
|
18803
20691
|
const fragment = doc.createDocumentFragment();
|
|
18804
20692
|
for (const run of runs) {
|
|
18805
20693
|
const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan");
|
|
@@ -19109,9 +20997,9 @@ function appendDataUriFontFaceRule(family, weight, style, dataUri) {
|
|
|
19109
20997
|
styleEl.appendChild(document.createTextNode(cssText));
|
|
19110
20998
|
}
|
|
19111
20999
|
function resolveHarnessFontProxyUrl() {
|
|
19112
|
-
var _a2,
|
|
21000
|
+
var _a2, _b2;
|
|
19113
21001
|
try {
|
|
19114
|
-
const runtimeBase = typeof window !== "undefined" && (window.__PIXLDOCS_SUPABASE_URL || ((_a2 = window.__CONFIG__) == null ? void 0 : _a2.supabaseUrl)) || typeof globalThis !== "undefined" && (globalThis.__PIXLDOCS_SUPABASE_URL || ((
|
|
21002
|
+
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)) || "";
|
|
19115
21003
|
const base = String(runtimeBase || "").replace(/\/$/, "");
|
|
19116
21004
|
return base ? `${base}/functions/v1/font-proxy` : "";
|
|
19117
21005
|
} catch {
|
|
@@ -19773,7 +21661,7 @@ async function resolveTemplateData(options) {
|
|
|
19773
21661
|
};
|
|
19774
21662
|
}
|
|
19775
21663
|
async function resolveFromForm(options) {
|
|
19776
|
-
var _a2,
|
|
21664
|
+
var _a2, _b2, _c;
|
|
19777
21665
|
const { templateId, formSchemaId, sectionState, flatFormData: directFlatFormData, themeId, supabaseUrl, supabaseAnonKey, prefetched } = options;
|
|
19778
21666
|
const hasSectionStateInput = !!sectionState && Object.keys(sectionState).length > 0;
|
|
19779
21667
|
if (!formSchemaId && !hasSectionStateInput) {
|
|
@@ -19823,7 +21711,7 @@ async function resolveFromForm(options) {
|
|
|
19823
21711
|
inferredSections = inferFormSchemaFromTemplate(
|
|
19824
21712
|
templateConfig.dynamicFields,
|
|
19825
21713
|
groups,
|
|
19826
|
-
((
|
|
21714
|
+
((_b2 = templateConfig.pages) == null ? void 0 : _b2.length) ? { pages: templateConfig.pages } : void 0
|
|
19827
21715
|
);
|
|
19828
21716
|
} else {
|
|
19829
21717
|
inferredSections = [];
|
|
@@ -20010,10 +21898,10 @@ function themeBaseId(id) {
|
|
|
20010
21898
|
return out;
|
|
20011
21899
|
}
|
|
20012
21900
|
function applyThemeVariantToConfig(config, themeConfig, themeId) {
|
|
20013
|
-
var _a2,
|
|
21901
|
+
var _a2, _b2, _c, _d;
|
|
20014
21902
|
if (!themeConfig) return config;
|
|
20015
21903
|
const variant = themeId && themeId !== "default" ? (_a2 = themeConfig.variants) == null ? void 0 : _a2.find((v) => v.id === themeId) : null;
|
|
20016
|
-
const shouldApplyDefaults = !variant && ((
|
|
21904
|
+
const shouldApplyDefaults = !variant && ((_b2 = themeConfig.properties) == null ? void 0 : _b2.length);
|
|
20017
21905
|
if (!variant && !shouldApplyDefaults) return config;
|
|
20018
21906
|
if (!((_c = themeConfig.properties) == null ? void 0 : _c.length)) return config;
|
|
20019
21907
|
const result = JSON.parse(JSON.stringify(config));
|
|
@@ -20034,8 +21922,8 @@ function applyThemeVariantToConfig(config, themeConfig, themeId) {
|
|
|
20034
21922
|
if (stopMatch) {
|
|
20035
21923
|
const stopIndex = parseInt(stopMatch[1], 10);
|
|
20036
21924
|
result.pages.forEach((p) => {
|
|
20037
|
-
var _a3,
|
|
20038
|
-
if ((
|
|
21925
|
+
var _a3, _b3;
|
|
21926
|
+
if ((_b3 = (_a3 = p.settings.backgroundGradient) == null ? void 0 : _a3.stops) == null ? void 0 : _b3[stopIndex]) {
|
|
20039
21927
|
p.settings.backgroundGradient = {
|
|
20040
21928
|
...p.settings.backgroundGradient,
|
|
20041
21929
|
stops: p.settings.backgroundGradient.stops.map(
|
|
@@ -20112,7 +22000,7 @@ function normalizeLayoutModes(config) {
|
|
|
20112
22000
|
}
|
|
20113
22001
|
}
|
|
20114
22002
|
function paintRepeatableSections(config, repeatableSections, formSchema) {
|
|
20115
|
-
var _a2,
|
|
22003
|
+
var _a2, _b2;
|
|
20116
22004
|
const pages = config.pages ?? [];
|
|
20117
22005
|
const entryFilters = (formSchema == null ? void 0 : formSchema.entryFilters) ?? [];
|
|
20118
22006
|
const entryFilterBases = new Set(entryFilters.map((f) => baseId(f.nodeId)));
|
|
@@ -20140,7 +22028,7 @@ function paintRepeatableSections(config, repeatableSections, formSchema) {
|
|
|
20140
22028
|
return painted;
|
|
20141
22029
|
}
|
|
20142
22030
|
for (const section of repeatableSections) {
|
|
20143
|
-
const inlineRange = ((_a2 = section.entryFilter) == null ? void 0 : _a2.mode) === "range" ? (
|
|
22031
|
+
const inlineRange = ((_a2 = section.entryFilter) == null ? void 0 : _a2.mode) === "range" ? (_b2 = section.entryFilter.range) == null ? void 0 : _b2.trim() : void 0;
|
|
20144
22032
|
const shouldUseInlineFilter = !!inlineRange && !entryFilterBases.has(baseId(section.nodeId));
|
|
20145
22033
|
const payload = { label: section.label };
|
|
20146
22034
|
if (section.minEntries !== void 0) payload.minEntries = section.minEntries;
|
|
@@ -20176,7 +22064,7 @@ function paintRepeatableSections(config, repeatableSections, formSchema) {
|
|
|
20176
22064
|
}
|
|
20177
22065
|
}
|
|
20178
22066
|
async function getTemplateForm(options) {
|
|
20179
|
-
var _a2,
|
|
22067
|
+
var _a2, _b2;
|
|
20180
22068
|
const { templateId, supabaseUrl, supabaseAnonKey } = options;
|
|
20181
22069
|
if (!supabaseUrl || !supabaseAnonKey) {
|
|
20182
22070
|
throw new Error("[getTemplateForm] supabaseUrl and supabaseAnonKey are required");
|
|
@@ -20220,7 +22108,7 @@ async function getTemplateForm(options) {
|
|
|
20220
22108
|
sections = inferFormSchemaFromTemplate(
|
|
20221
22109
|
templateConfig.dynamicFields,
|
|
20222
22110
|
templateConfig.fieldGroups || [],
|
|
20223
|
-
((
|
|
22111
|
+
((_b2 = templateConfig.pages) == null ? void 0 : _b2.length) ? { pages: templateConfig.pages } : void 0
|
|
20224
22112
|
);
|
|
20225
22113
|
} else {
|
|
20226
22114
|
sections = [];
|
|
@@ -20604,7 +22492,7 @@ function computeFrostedBoundsForPage(config, pageIndex, extraBaseIds, extraExact
|
|
|
20604
22492
|
return out;
|
|
20605
22493
|
}
|
|
20606
22494
|
function PixldocsPreview(props) {
|
|
20607
|
-
var _a2,
|
|
22495
|
+
var _a2, _b2;
|
|
20608
22496
|
const {
|
|
20609
22497
|
pageIndex = 0,
|
|
20610
22498
|
zoom = 1,
|
|
@@ -20672,10 +22560,10 @@ function PixldocsPreview(props) {
|
|
|
20672
22560
|
supabaseUrl: p.supabaseUrl,
|
|
20673
22561
|
supabaseAnonKey: p.supabaseAnonKey
|
|
20674
22562
|
}).then((resolved) => {
|
|
20675
|
-
var _a3,
|
|
22563
|
+
var _a3, _b3;
|
|
20676
22564
|
if (!cancelled) {
|
|
20677
22565
|
console.log(PREVIEW_DEBUG_PREFIX, "resolve-done", {
|
|
20678
|
-
pages: ((
|
|
22566
|
+
pages: ((_b3 = (_a3 = resolved.config) == null ? void 0 : _a3.pages) == null ? void 0 : _b3.length) ?? 0,
|
|
20679
22567
|
underlinedNodes: countUnderlinedNodes(resolved.config)
|
|
20680
22568
|
});
|
|
20681
22569
|
setResolvedConfig(resolved.config);
|
|
@@ -20785,7 +22673,7 @@ function PixldocsPreview(props) {
|
|
|
20785
22673
|
const satPct = (frostedBlurOptions == null ? void 0 : frostedBlurOptions.saturatePct) ?? 130;
|
|
20786
22674
|
const bgTint = (frostedBlurOptions == null ? void 0 : frostedBlurOptions.background) ?? "rgba(255,255,255,0.12)";
|
|
20787
22675
|
const canvasW = getNum((_a2 = config == null ? void 0 : config.canvas) == null ? void 0 : _a2.width, 0);
|
|
20788
|
-
const canvasH = getNum((
|
|
22676
|
+
const canvasH = getNum((_b2 = config == null ? void 0 : config.canvas) == null ? void 0 : _b2.height, 0);
|
|
20789
22677
|
const hasOverlays = frostedBounds.length > 0 && canvasW > 0 && canvasH > 0;
|
|
20790
22678
|
if (isLoading) {
|
|
20791
22679
|
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..." }) });
|
|
@@ -20926,7 +22814,7 @@ function ensureFabricGradientDef(doc, obj, width, height) {
|
|
|
20926
22814
|
return `url(#${id})`;
|
|
20927
22815
|
}
|
|
20928
22816
|
function warpTextboxSvgAlongPath(svg, obj) {
|
|
20929
|
-
var _a2,
|
|
22817
|
+
var _a2, _b2, _c, _d, _e;
|
|
20930
22818
|
const tp = obj == null ? void 0 : obj.textPath;
|
|
20931
22819
|
if (!tp || !tp.preset || tp.preset === "none") return svg;
|
|
20932
22820
|
if (tp.preset === "rise" || tp.preset === "angle") {
|
|
@@ -20990,7 +22878,7 @@ function warpTextboxSvgAlongPath(svg, obj) {
|
|
|
20990
22878
|
}
|
|
20991
22879
|
for (const clone of Array.from(doc.querySelectorAll("g.__pdTextShadowClone"))) {
|
|
20992
22880
|
try {
|
|
20993
|
-
(
|
|
22881
|
+
(_b2 = clone.parentNode) == null ? void 0 : _b2.removeChild(clone);
|
|
20994
22882
|
} catch {
|
|
20995
22883
|
}
|
|
20996
22884
|
}
|
|
@@ -21010,9 +22898,9 @@ function warpTextboxSvgAlongPath(svg, obj) {
|
|
|
21010
22898
|
const fw = obj.fontWeight ?? 400;
|
|
21011
22899
|
const fst = obj.fontStyle || "normal";
|
|
21012
22900
|
const readFill = (el) => {
|
|
21013
|
-
var _a3,
|
|
22901
|
+
var _a3, _b3;
|
|
21014
22902
|
if (!el) return "";
|
|
21015
|
-
return el.getAttribute("fill") || ((
|
|
22903
|
+
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()) || "";
|
|
21016
22904
|
};
|
|
21017
22905
|
const w = Number(obj.width) || 0;
|
|
21018
22906
|
const h = Number(obj.height) || 0;
|
|
@@ -21365,9 +23253,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
21365
23253
|
}
|
|
21366
23254
|
return svgString;
|
|
21367
23255
|
}
|
|
21368
|
-
const resolvedPackageVersion = "0.5.
|
|
23256
|
+
const resolvedPackageVersion = "0.5.243";
|
|
21369
23257
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
21370
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
23258
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.243";
|
|
21371
23259
|
const roundParityValue = (value) => {
|
|
21372
23260
|
if (typeof value !== "number") return value;
|
|
21373
23261
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -21544,11 +23432,11 @@ function installUnderlineFix(fab) {
|
|
|
21544
23432
|
if (!TextProto || typeof TextProto._renderTextDecoration !== "function") return;
|
|
21545
23433
|
const original = TextProto._renderTextDecoration;
|
|
21546
23434
|
const measureLineTextWidth = (obj, ctx, lineIndex) => {
|
|
21547
|
-
var _a3,
|
|
23435
|
+
var _a3, _b2, _c, _d, _e, _f;
|
|
21548
23436
|
const rawLine = (_a3 = obj._textLines) == null ? void 0 : _a3[lineIndex];
|
|
21549
23437
|
const lineText = Array.isArray(rawLine) ? rawLine.join("") : String(rawLine ?? "");
|
|
21550
23438
|
if (!lineText) return 0;
|
|
21551
|
-
const fontSize = Number(((
|
|
23439
|
+
const fontSize = Number(((_b2 = obj.getValueOfPropertyAt) == null ? void 0 : _b2.call(obj, lineIndex, 0, "fontSize")) ?? obj.fontSize ?? 0);
|
|
21552
23440
|
const fontStyle = String(((_c = obj.getValueOfPropertyAt) == null ? void 0 : _c.call(obj, lineIndex, 0, "fontStyle")) ?? obj.fontStyle ?? "normal");
|
|
21553
23441
|
const fontWeight = String(((_d = obj.getValueOfPropertyAt) == null ? void 0 : _d.call(obj, lineIndex, 0, "fontWeight")) ?? obj.fontWeight ?? "400");
|
|
21554
23442
|
const fontFamily = String(((_e = obj.getValueOfPropertyAt) == null ? void 0 : _e.call(obj, lineIndex, 0, "fontFamily")) ?? obj.fontFamily ?? "sans-serif");
|
|
@@ -21688,11 +23576,78 @@ function installTextboxBoxExtensions(fab) {
|
|
|
21688
23576
|
if (Array.isArray(stateProps2)) {
|
|
21689
23577
|
if (!stateProps2.includes("minBoxHeight")) stateProps2.push("minBoxHeight");
|
|
21690
23578
|
if (!stateProps2.includes("verticalAlign")) stateProps2.push("verticalAlign");
|
|
23579
|
+
if (!stateProps2.includes("smartWrap")) stateProps2.push("smartWrap");
|
|
21691
23580
|
}
|
|
21692
23581
|
const cacheProps2 = TextboxProto2.cacheProperties;
|
|
21693
23582
|
if (Array.isArray(cacheProps2)) {
|
|
21694
23583
|
if (!cacheProps2.includes("minBoxHeight")) cacheProps2.push("minBoxHeight");
|
|
21695
23584
|
if (!cacheProps2.includes("verticalAlign")) cacheProps2.push("verticalAlign");
|
|
23585
|
+
if (!cacheProps2.includes("smartWrap")) cacheProps2.push("smartWrap");
|
|
23586
|
+
}
|
|
23587
|
+
TextboxProto2.smartWrap = true;
|
|
23588
|
+
if (typeof TextboxProto2._wrapLine === "function" && !TextboxProto2.__pixldocsOrigWrapLine) {
|
|
23589
|
+
const origWrapLine = TextboxProto2._wrapLine;
|
|
23590
|
+
TextboxProto2.__pixldocsOrigWrapLine = origWrapLine;
|
|
23591
|
+
TextboxProto2._wrapLine = function(lineIndex, desiredWidth, ref, reservedSpace = 0) {
|
|
23592
|
+
var _a3;
|
|
23593
|
+
if (!this.smartWrap || this.splitByGrapheme) {
|
|
23594
|
+
return origWrapLine.call(this, lineIndex, desiredWidth, ref, reservedSpace);
|
|
23595
|
+
}
|
|
23596
|
+
try {
|
|
23597
|
+
const additionalSpace = this._getWidthOfCharSpacing();
|
|
23598
|
+
const data = ((_a3 = ref == null ? void 0 : ref.wordsData) == null ? void 0 : _a3[lineIndex]) || [];
|
|
23599
|
+
const effective = Math.max(1, desiredWidth - reservedSpace);
|
|
23600
|
+
const infix = " ";
|
|
23601
|
+
const infixWidth = this._measureWord([infix], lineIndex, 0);
|
|
23602
|
+
const graphemeLines = [];
|
|
23603
|
+
let line = [];
|
|
23604
|
+
let lineWidth = 0;
|
|
23605
|
+
let lineJustStarted = true;
|
|
23606
|
+
let largestWordWidth = 0;
|
|
23607
|
+
let offset = 0;
|
|
23608
|
+
const pushLine = () => {
|
|
23609
|
+
graphemeLines.push(line);
|
|
23610
|
+
line = [];
|
|
23611
|
+
lineWidth = 0;
|
|
23612
|
+
lineJustStarted = true;
|
|
23613
|
+
};
|
|
23614
|
+
for (let i = 0; i < data.length; i++) {
|
|
23615
|
+
const { word, width: wordWidth } = data[i];
|
|
23616
|
+
if (wordWidth <= effective) {
|
|
23617
|
+
if (wordWidth > largestWordWidth) largestWordWidth = wordWidth;
|
|
23618
|
+
const projected = lineJustStarted ? wordWidth : lineWidth + infixWidth + wordWidth - additionalSpace;
|
|
23619
|
+
if (!lineJustStarted && projected > effective) pushLine();
|
|
23620
|
+
if (!lineJustStarted) {
|
|
23621
|
+
line.push(infix);
|
|
23622
|
+
lineWidth += infixWidth;
|
|
23623
|
+
}
|
|
23624
|
+
line = line.concat(word);
|
|
23625
|
+
lineWidth += wordWidth;
|
|
23626
|
+
lineJustStarted = false;
|
|
23627
|
+
} else {
|
|
23628
|
+
if (!lineJustStarted) pushLine();
|
|
23629
|
+
for (const g of word) {
|
|
23630
|
+
const gw = this._measureWord([g], lineIndex, offset);
|
|
23631
|
+
if (gw > largestWordWidth) largestWordWidth = gw;
|
|
23632
|
+
const gProj = lineJustStarted ? gw : lineWidth + gw - additionalSpace;
|
|
23633
|
+
if (!lineJustStarted && gProj > effective) pushLine();
|
|
23634
|
+
line.push(g);
|
|
23635
|
+
lineWidth += gw;
|
|
23636
|
+
lineJustStarted = false;
|
|
23637
|
+
offset++;
|
|
23638
|
+
}
|
|
23639
|
+
offset -= word.length;
|
|
23640
|
+
}
|
|
23641
|
+
offset += word.length + 1;
|
|
23642
|
+
}
|
|
23643
|
+
if (line.length) graphemeLines.push(line);
|
|
23644
|
+
const minNeeded = Math.max(0, Math.min(largestWordWidth, effective) - additionalSpace + reservedSpace);
|
|
23645
|
+
if (minNeeded > this.dynamicMinWidth) this.dynamicMinWidth = minNeeded;
|
|
23646
|
+
return graphemeLines;
|
|
23647
|
+
} catch (e) {
|
|
23648
|
+
return origWrapLine.call(this, lineIndex, desiredWidth, ref, reservedSpace);
|
|
23649
|
+
}
|
|
23650
|
+
};
|
|
21696
23651
|
}
|
|
21697
23652
|
TextboxProto2.__pixldocsTextboxExtended = true;
|
|
21698
23653
|
__textboxBoxExtensionsInstalled = true;
|
|
@@ -22114,7 +24069,7 @@ class PixldocsRenderer {
|
|
|
22114
24069
|
await this.waitForCanvasScene(container, cloned, i);
|
|
22115
24070
|
}
|
|
22116
24071
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
22117
|
-
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-
|
|
24072
|
+
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-DJD1vq7N.js");
|
|
22118
24073
|
const prepared = preparePagesForExport(
|
|
22119
24074
|
cloned.pages,
|
|
22120
24075
|
canvasWidth,
|
|
@@ -22331,9 +24286,9 @@ class PixldocsRenderer {
|
|
|
22331
24286
|
}
|
|
22332
24287
|
waitForCanvasScene(container, config, pageIndex, maxWaitMs = 8e3, pollMs = 50) {
|
|
22333
24288
|
return new Promise((resolve) => {
|
|
22334
|
-
var _a2,
|
|
24289
|
+
var _a2, _b2;
|
|
22335
24290
|
const start = Date.now();
|
|
22336
|
-
const pageHasContent = (((
|
|
24291
|
+
const pageHasContent = (((_b2 = (_a2 = config.pages[pageIndex]) == null ? void 0 : _a2.children) == null ? void 0 : _b2.length) ?? 0) > 0;
|
|
22337
24292
|
const settle = () => requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
|
|
22338
24293
|
const check = () => {
|
|
22339
24294
|
const fabricCanvas = this.getFabricCanvasFromContainer(container);
|
|
@@ -22408,9 +24363,9 @@ class PixldocsRenderer {
|
|
|
22408
24363
|
return normalized;
|
|
22409
24364
|
}
|
|
22410
24365
|
paintPageBackground(ctx, page, width, height) {
|
|
22411
|
-
var _a2,
|
|
24366
|
+
var _a2, _b2;
|
|
22412
24367
|
const backgroundColor = ((_a2 = page == null ? void 0 : page.settings) == null ? void 0 : _a2.backgroundColor) || "#ffffff";
|
|
22413
|
-
const gradient = (
|
|
24368
|
+
const gradient = (_b2 = page == null ? void 0 : page.settings) == null ? void 0 : _b2.backgroundGradient;
|
|
22414
24369
|
ctx.clearRect(0, 0, width, height);
|
|
22415
24370
|
ctx.fillStyle = backgroundColor;
|
|
22416
24371
|
ctx.fillRect(0, 0, width, height);
|
|
@@ -22658,7 +24613,7 @@ class PixldocsRenderer {
|
|
|
22658
24613
|
};
|
|
22659
24614
|
const onReady = () => {
|
|
22660
24615
|
this.waitForCanvasScene(container, renderConfig, pageIndex).then(async () => {
|
|
22661
|
-
var _a2,
|
|
24616
|
+
var _a2, _b2;
|
|
22662
24617
|
try {
|
|
22663
24618
|
const expectedImageIds = this.getExpectedImageIds(renderConfig, pageIndex);
|
|
22664
24619
|
await this.waitForCanvasImages(container, expectedImageIds);
|
|
@@ -22677,7 +24632,7 @@ class PixldocsRenderer {
|
|
|
22677
24632
|
);
|
|
22678
24633
|
const page = renderConfig.pages[pageIndex];
|
|
22679
24634
|
const backgroundColor = ((_a2 = page == null ? void 0 : page.settings) == null ? void 0 : _a2.backgroundColor) || "#ffffff";
|
|
22680
|
-
const backgroundGradient = (
|
|
24635
|
+
const backgroundGradient = (_b2 = page == null ? void 0 : page.settings) == null ? void 0 : _b2.backgroundGradient;
|
|
22681
24636
|
cleanup();
|
|
22682
24637
|
resolve({
|
|
22683
24638
|
svg: svgString,
|
|
@@ -22798,7 +24753,7 @@ class PixldocsRenderer {
|
|
|
22798
24753
|
logJsonLine("[canvas-renderer][fabric-text-parity]", { stage, textboxes: sample.length, sample });
|
|
22799
24754
|
}
|
|
22800
24755
|
async waitForStableTextMetrics(container, config, options = {}) {
|
|
22801
|
-
var _a2,
|
|
24756
|
+
var _a2, _b2, _c;
|
|
22802
24757
|
if (typeof document !== "undefined") {
|
|
22803
24758
|
void ensureFontsForResolvedConfig(config);
|
|
22804
24759
|
await this.waitForRelevantFonts(config);
|
|
@@ -22840,7 +24795,7 @@ class PixldocsRenderer {
|
|
|
22840
24795
|
}
|
|
22841
24796
|
fabricInstance.getObjects().forEach(primeCharBounds);
|
|
22842
24797
|
(_a2 = fabricInstance.calcOffset) == null ? void 0 : _a2.call(fabricInstance);
|
|
22843
|
-
(
|
|
24798
|
+
(_b2 = fabricInstance.renderAll) == null ? void 0 : _b2.call(fabricInstance);
|
|
22844
24799
|
await waitForPaint();
|
|
22845
24800
|
(_c = fabricInstance.renderAll) == null ? void 0 : _c.call(fabricInstance);
|
|
22846
24801
|
await waitForPaint();
|
|
@@ -22881,7 +24836,7 @@ function dumpSvgTextDiagnostics(svgStr, pageIndex, tag, stage, maxItems = 30) {
|
|
|
22881
24836
|
};
|
|
22882
24837
|
logParityJson(tag, stage, { kind: "summary", ...summary });
|
|
22883
24838
|
const sample = texts.slice(0, maxItems).map((t, idx) => {
|
|
22884
|
-
var _a2,
|
|
24839
|
+
var _a2, _b2;
|
|
22885
24840
|
const tspans = Array.from(t.querySelectorAll("tspan"));
|
|
22886
24841
|
const tspanInfo = tspans.slice(0, 8).map((s) => ({
|
|
22887
24842
|
x: s.getAttribute("x"),
|
|
@@ -22898,7 +24853,7 @@ function dumpSvgTextDiagnostics(svgStr, pageIndex, tag, stage, maxItems = 30) {
|
|
|
22898
24853
|
while (cursor && !containerWidth) {
|
|
22899
24854
|
containerWidth = (_a2 = cursor.getAttribute) == null ? void 0 : _a2.call(cursor, "width");
|
|
22900
24855
|
cursor = cursor.parentElement;
|
|
22901
|
-
if (cursor && ((
|
|
24856
|
+
if (cursor && ((_b2 = cursor.tagName) == null ? void 0 : _b2.toLowerCase()) === "svg") break;
|
|
22902
24857
|
}
|
|
22903
24858
|
return {
|
|
22904
24859
|
idx,
|
|
@@ -23286,10 +25241,10 @@ function normalizeSvgExplicitColors(svg) {
|
|
|
23286
25241
|
return normalizeGradientPaintRef(v);
|
|
23287
25242
|
};
|
|
23288
25243
|
const hasExplicitNonePaint = (el, attr) => {
|
|
23289
|
-
var _a2,
|
|
25244
|
+
var _a2, _b2;
|
|
23290
25245
|
const raw = (el.getAttribute(attr) ?? ((_a2 = el.style) == null ? void 0 : _a2.getPropertyValue(attr)) ?? "").trim().toLowerCase();
|
|
23291
25246
|
if (raw === "none" || raw === "transparent") return true;
|
|
23292
|
-
const rawOpacity = (el.getAttribute(`${attr}-opacity`) ?? ((
|
|
25247
|
+
const rawOpacity = (el.getAttribute(`${attr}-opacity`) ?? ((_b2 = el.style) == null ? void 0 : _b2.getPropertyValue(`${attr}-opacity`)) ?? "").trim().toLowerCase();
|
|
23293
25248
|
return rawOpacity === "0" || rawOpacity === "0%" || rawOpacity === "0.0";
|
|
23294
25249
|
};
|
|
23295
25250
|
function walk(el, parentFill, parentStroke, parentColor) {
|
|
@@ -23356,14 +25311,14 @@ function normalizeSvgExplicitColors(svg) {
|
|
|
23356
25311
|
function bakeGroupOpacityIntoChildren(svg) {
|
|
23357
25312
|
const DRAWABLE = /* @__PURE__ */ new Set(["path", "rect", "circle", "ellipse", "polygon", "polyline", "line", "text", "tspan"]);
|
|
23358
25313
|
function walkAndBake(el, inheritedOpacity) {
|
|
23359
|
-
var _a2,
|
|
25314
|
+
var _a2, _b2, _c, _d;
|
|
23360
25315
|
if (isInSvgDefinitionSubtree(el)) {
|
|
23361
25316
|
for (let i = 0; i < el.children.length; i++) walkAndBake(el.children[i], 1);
|
|
23362
25317
|
return;
|
|
23363
25318
|
}
|
|
23364
25319
|
const tag = ((_a2 = el.tagName) == null ? void 0 : _a2.toLowerCase()) ?? "";
|
|
23365
25320
|
const opacityAttr = parseSvgOpacity(el.getAttribute("opacity"));
|
|
23366
|
-
const styleOpacity = parseSvgOpacity(((
|
|
25321
|
+
const styleOpacity = parseSvgOpacity(((_b2 = el.style) == null ? void 0 : _b2.getPropertyValue("opacity")) || null);
|
|
23367
25322
|
const ownOpacity = opacityAttr ?? styleOpacity ?? 1;
|
|
23368
25323
|
const combinedOpacity = inheritedOpacity * ownOpacity;
|
|
23369
25324
|
if (ownOpacity < 0.999 && tag !== "image") {
|
|
@@ -23886,10 +25841,10 @@ function getFirstExplicitColorFromSvg(svg) {
|
|
|
23886
25841
|
return getGradientStopColorAsHex(svg, gradientId);
|
|
23887
25842
|
};
|
|
23888
25843
|
function walk(el) {
|
|
23889
|
-
var _a2,
|
|
25844
|
+
var _a2, _b2;
|
|
23890
25845
|
if (fill && stroke) return;
|
|
23891
25846
|
const f = el.getAttribute("fill") ?? ((_a2 = el.style) == null ? void 0 : _a2.getPropertyValue("fill"));
|
|
23892
|
-
const s = el.getAttribute("stroke") ?? ((
|
|
25847
|
+
const s = el.getAttribute("stroke") ?? ((_b2 = el.style) == null ? void 0 : _b2.getPropertyValue("stroke"));
|
|
23893
25848
|
if (!fill) {
|
|
23894
25849
|
if (isRealColor(f)) fill = f;
|
|
23895
25850
|
else if (f) {
|
|
@@ -23917,8 +25872,8 @@ function isNearWhite(hex) {
|
|
|
23917
25872
|
return r >= 250 && g >= 250 && b >= 250;
|
|
23918
25873
|
}
|
|
23919
25874
|
function getStopColorRaw(stop) {
|
|
23920
|
-
var _a2,
|
|
23921
|
-
return stop.getAttribute("stop-color") ?? ((
|
|
25875
|
+
var _a2, _b2;
|
|
25876
|
+
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");
|
|
23922
25877
|
}
|
|
23923
25878
|
function getGradientStopColorAsHex(svgRoot, gradientId, visited = /* @__PURE__ */ new Set()) {
|
|
23924
25879
|
var _a2;
|
|
@@ -23982,12 +25937,12 @@ async function convertTextDecorationsToLines(svg) {
|
|
|
23982
25937
|
else el.removeAttribute("style");
|
|
23983
25938
|
};
|
|
23984
25939
|
const resolveInheritedSvgValue = (el, attr, styleProp = attr) => {
|
|
23985
|
-
var _a2,
|
|
25940
|
+
var _a2, _b2;
|
|
23986
25941
|
let current = el;
|
|
23987
25942
|
while (current) {
|
|
23988
25943
|
const attrValue = (_a2 = current.getAttribute(attr)) == null ? void 0 : _a2.trim();
|
|
23989
25944
|
if (attrValue) return attrValue;
|
|
23990
|
-
const styleValue = (
|
|
25945
|
+
const styleValue = (_b2 = getInlineStyleValue(current, styleProp)) == null ? void 0 : _b2.trim();
|
|
23991
25946
|
if (styleValue) return styleValue;
|
|
23992
25947
|
current = current.parentElement;
|
|
23993
25948
|
}
|
|
@@ -24165,7 +26120,7 @@ async function convertSvgTextDecorationsToLinesString(svgStr) {
|
|
|
24165
26120
|
}
|
|
24166
26121
|
}
|
|
24167
26122
|
async function rasterizeShadowMarkers(svg) {
|
|
24168
|
-
var _a2,
|
|
26123
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
24169
26124
|
if (typeof window === "undefined" || typeof document === "undefined") return;
|
|
24170
26125
|
const markers = Array.from(svg.querySelectorAll("g.__pdShadowRaster"));
|
|
24171
26126
|
if (markers.length === 0) return;
|
|
@@ -24189,7 +26144,7 @@ async function rasterizeShadowMarkers(svg) {
|
|
|
24189
26144
|
const alphaRaw = parseFloat(marker.getAttribute("data-alpha") || "1");
|
|
24190
26145
|
const shadowAlpha = Number.isFinite(alphaRaw) ? Math.max(0, Math.min(1, alphaRaw)) : 1;
|
|
24191
26146
|
if (!Number.isFinite(bw) || !Number.isFinite(bh) || bw <= 0 || bh <= 0) {
|
|
24192
|
-
(
|
|
26147
|
+
(_b2 = marker.parentNode) == null ? void 0 : _b2.removeChild(marker);
|
|
24193
26148
|
continue;
|
|
24194
26149
|
}
|
|
24195
26150
|
const innerXml = restoreSourceFontsForShadowRaster(
|
|
@@ -24434,7 +26389,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
24434
26389
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
24435
26390
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
24436
26391
|
try {
|
|
24437
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-
|
|
26392
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-DJD1vq7N.js");
|
|
24438
26393
|
try {
|
|
24439
26394
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
24440
26395
|
} catch {
|
|
@@ -24450,7 +26405,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
24450
26405
|
}
|
|
24451
26406
|
}
|
|
24452
26407
|
function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundColor, backgroundGradient) {
|
|
24453
|
-
var _a2,
|
|
26408
|
+
var _a2, _b2;
|
|
24454
26409
|
if (backgroundGradient && ((_a2 = backgroundGradient.stops) == null ? void 0 : _a2.length) >= 2) {
|
|
24455
26410
|
const grad = backgroundGradient;
|
|
24456
26411
|
const colorStops = grad.stops.map((s) => {
|
|
@@ -24505,7 +26460,7 @@ function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundCol
|
|
|
24505
26460
|
doc.fill({ key: patternKey, matrix: doc.Matrix(1, 0, 0, 1, 0, 0) });
|
|
24506
26461
|
});
|
|
24507
26462
|
} catch {
|
|
24508
|
-
const fallback = ((
|
|
26463
|
+
const fallback = ((_b2 = colorStops[0]) == null ? void 0 : _b2.color) || [255, 255, 255];
|
|
24509
26464
|
pdf.setFillColor(fallback[0], fallback[1], fallback[2]);
|
|
24510
26465
|
pdf.rect(0, 0, pageWidth, pageHeight, "F");
|
|
24511
26466
|
}
|
|
@@ -24518,7 +26473,7 @@ function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundCol
|
|
|
24518
26473
|
}
|
|
24519
26474
|
}
|
|
24520
26475
|
async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
24521
|
-
var _a2,
|
|
26476
|
+
var _a2, _b2;
|
|
24522
26477
|
if (svgResults.length === 0) throw new Error("No pages to export");
|
|
24523
26478
|
const { title, stripPageBackground } = options;
|
|
24524
26479
|
const firstPage = svgResults[0];
|
|
@@ -24551,7 +26506,7 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
|
|
|
24551
26506
|
const pageOrientation = page.width > page.height ? "landscape" : "portrait";
|
|
24552
26507
|
pdf.addPage([page.width, page.height], pageOrientation);
|
|
24553
26508
|
}
|
|
24554
|
-
const hasGradient = !!((
|
|
26509
|
+
const hasGradient = !!((_b2 = (_a2 = page.backgroundGradient) == null ? void 0 : _a2.stops) == null ? void 0 : _b2.length);
|
|
24555
26510
|
drawPageBackground(pdf, i, page.width, page.height, page.backgroundColor, page.backgroundGradient);
|
|
24556
26511
|
const shouldStripBg = stripPageBackground ?? hasGradient;
|
|
24557
26512
|
const textMode = options.textMode ?? (options.outlineText === true ? "pixel-perfect" : "selectable");
|
|
@@ -24834,4 +26789,4 @@ export {
|
|
|
24834
26789
|
buildTeaserBlurFlatKeys as y,
|
|
24835
26790
|
collectFontDescriptorsFromConfig as z
|
|
24836
26791
|
};
|
|
24837
|
-
//# sourceMappingURL=index-
|
|
26792
|
+
//# sourceMappingURL=index-C5mQ2kl5.js.map
|