@pixldocs/canvas-renderer 0.5.225 → 0.5.226
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-6nrov1rx.cjs → index-CXOoVCq1.cjs} +1232 -195
- package/dist/index-CXOoVCq1.cjs.map +1 -0
- package/dist/{index-BpViFQMO.js → index-ZjC8BLGn.js} +1233 -196
- package/dist/index-ZjC8BLGn.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-CVeK--lR.cjs → vectorPdfExport-C18SGeJb.cjs} +26 -11
- package/dist/vectorPdfExport-C18SGeJb.cjs.map +1 -0
- package/dist/{vectorPdfExport-D46sZGKA.js → vectorPdfExport-DVspHEZh.js} +26 -11
- package/dist/vectorPdfExport-DVspHEZh.js.map +1 -0
- package/package.json +1 -1
- package/dist/index-6nrov1rx.cjs.map +0 -1
- package/dist/index-BpViFQMO.js.map +0 -1
- package/dist/vectorPdfExport-CVeK--lR.cjs.map +0 -1
- package/dist/vectorPdfExport-D46sZGKA.js.map +0 -1
|
@@ -454,6 +454,148 @@ function fallbackEstimateHeight(element) {
|
|
|
454
454
|
function clearMeasurementCache() {
|
|
455
455
|
heightCache.clear();
|
|
456
456
|
}
|
|
457
|
+
function computeAutoShrinkFontSize(element) {
|
|
458
|
+
const baseFontSize = element.fontSize || 16;
|
|
459
|
+
if (element.overflowPolicy !== "auto-shrink") return baseFontSize;
|
|
460
|
+
const text = element.text || element.content || "";
|
|
461
|
+
if (!text) return baseFontSize;
|
|
462
|
+
const width = element.width || 200;
|
|
463
|
+
const height = element.height;
|
|
464
|
+
if (!height) return baseFontSize;
|
|
465
|
+
let fontSize = baseFontSize;
|
|
466
|
+
try {
|
|
467
|
+
while (fontSize > 1) {
|
|
468
|
+
const testTb = new fabric__namespace.Textbox(text, {
|
|
469
|
+
width,
|
|
470
|
+
fontSize,
|
|
471
|
+
fontFamily: element.fontFamily || "Open Sans",
|
|
472
|
+
fontWeight: element.fontWeight || 400,
|
|
473
|
+
fontStyle: element.fontStyle || "normal",
|
|
474
|
+
lineHeight: element.lineHeight || 1.2,
|
|
475
|
+
charSpacing: element.charSpacing || 0,
|
|
476
|
+
splitByGrapheme: false
|
|
477
|
+
});
|
|
478
|
+
testTb.initDimensions();
|
|
479
|
+
const textHeight = testTb.height || 0;
|
|
480
|
+
const fitsHeight = textHeight <= height;
|
|
481
|
+
const lineWidths = testTb.__lineWidths;
|
|
482
|
+
const maxLineWidth = lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : 0;
|
|
483
|
+
const fitsWidth = maxLineWidth <= width + 1;
|
|
484
|
+
if (fitsHeight && fitsWidth) break;
|
|
485
|
+
fontSize--;
|
|
486
|
+
}
|
|
487
|
+
} catch (e) {
|
|
488
|
+
console.warn("[autoShrink] Failed to compute shrunk font size:", e);
|
|
489
|
+
return baseFontSize;
|
|
490
|
+
}
|
|
491
|
+
return fontSize;
|
|
492
|
+
}
|
|
493
|
+
function measureTextGlyphHeightForStackHug(el) {
|
|
494
|
+
const text = el.text || " ";
|
|
495
|
+
const width = Math.max(1, typeof el.width === "number" ? el.width : 200);
|
|
496
|
+
let fontSize = el.fontSize || 16;
|
|
497
|
+
const lineHeight = el.lineHeight || 1.2;
|
|
498
|
+
const charSpacing = el.charSpacing || 0;
|
|
499
|
+
const fontFamily = el.fontFamily || "Open Sans";
|
|
500
|
+
const fontWeight = el.fontWeight || 400;
|
|
501
|
+
const fontStyle = el.fontStyle || "normal";
|
|
502
|
+
const isAutoShrink = el.overflowPolicy === "auto-shrink";
|
|
503
|
+
const splitByGrapheme = isAutoShrink ? false : el.splitByGrapheme ?? el.wordWrap === "break-word";
|
|
504
|
+
if (isAutoShrink) {
|
|
505
|
+
const minBoxH = Math.max(0, Number(el.minBoxHeight) || 0);
|
|
506
|
+
const heightBound = Math.max(typeof el.height === "number" ? el.height : 0, minBoxH);
|
|
507
|
+
while (fontSize > 1) {
|
|
508
|
+
const testTb = new fabric__namespace.Textbox(text, {
|
|
509
|
+
width,
|
|
510
|
+
fontSize,
|
|
511
|
+
fontFamily,
|
|
512
|
+
fontWeight,
|
|
513
|
+
fontStyle,
|
|
514
|
+
lineHeight,
|
|
515
|
+
charSpacing,
|
|
516
|
+
splitByGrapheme: false
|
|
517
|
+
});
|
|
518
|
+
testTb.initDimensions();
|
|
519
|
+
const textHeight = testTb.height || 0;
|
|
520
|
+
const lineWidths = getCanvasMeasuredTextboxLineWidths(testTb);
|
|
521
|
+
const maxLineWidth = lineWidths.length > 0 ? Math.max(...lineWidths) : 0;
|
|
522
|
+
if ((heightBound <= 0 || textHeight <= heightBound) && maxLineWidth <= width + 1) break;
|
|
523
|
+
fontSize--;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
const textbox = new fabric__namespace.Textbox(text, {
|
|
527
|
+
width,
|
|
528
|
+
fontSize,
|
|
529
|
+
fontFamily,
|
|
530
|
+
fontWeight,
|
|
531
|
+
fontStyle,
|
|
532
|
+
lineHeight,
|
|
533
|
+
charSpacing,
|
|
534
|
+
splitByGrapheme
|
|
535
|
+
});
|
|
536
|
+
textbox.initDimensions();
|
|
537
|
+
return Math.max(1, (textbox.height || 20) * (el.scaleY || 1));
|
|
538
|
+
}
|
|
539
|
+
function getStackChildLayoutSize(parent, child, pageChildren, options) {
|
|
540
|
+
const b = getNodeBounds(child, pageChildren);
|
|
541
|
+
if (!parent.hugContent) return { width: b.width, height: b.height };
|
|
542
|
+
if (!isElement(child)) return { width: b.width, height: b.height };
|
|
543
|
+
const el = child;
|
|
544
|
+
if (el.type !== "text") return { width: b.width, height: b.height };
|
|
545
|
+
const isHorizontal = parent.layoutMode === "horizontal-stack";
|
|
546
|
+
if (isHorizontal) {
|
|
547
|
+
try {
|
|
548
|
+
const isAutoShrink = el.overflowPolicy === "auto-shrink";
|
|
549
|
+
const effectiveFontSize = isAutoShrink ? computeAutoShrinkFontSize(el) : el.fontSize || 16;
|
|
550
|
+
const probeWidth = isAutoShrink && typeof el.width === "number" ? el.width : 1e4;
|
|
551
|
+
const probe = new fabric__namespace.Textbox(el.text || " ", {
|
|
552
|
+
width: probeWidth,
|
|
553
|
+
fontSize: effectiveFontSize,
|
|
554
|
+
fontFamily: el.fontFamily || "Open Sans",
|
|
555
|
+
fontWeight: el.fontWeight || 400,
|
|
556
|
+
fontStyle: el.fontStyle || "normal",
|
|
557
|
+
lineHeight: el.lineHeight || 1.2,
|
|
558
|
+
charSpacing: el.charSpacing || 0,
|
|
559
|
+
splitByGrapheme: el.splitByGrapheme ?? el.wordWrap === "break-word"
|
|
560
|
+
});
|
|
561
|
+
probe.initDimensions();
|
|
562
|
+
const lineWidths = getCanvasMeasuredTextboxLineWidths(probe);
|
|
563
|
+
const maxLine = lineWidths.length > 0 ? Math.max(...lineWidths) : typeof el.width === "number" ? el.width : b.width;
|
|
564
|
+
const measuredW = Math.ceil(maxLine) + 2;
|
|
565
|
+
const w = Math.max(1, measuredW * (el.scaleX || 1));
|
|
566
|
+
return { width: w, height: b.height };
|
|
567
|
+
} catch {
|
|
568
|
+
return { width: b.width, height: b.height };
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
try {
|
|
572
|
+
const measuredH = measureTextGlyphHeightForStackHug(el);
|
|
573
|
+
const h = Math.max(1, measuredH);
|
|
574
|
+
return { width: b.width, height: h };
|
|
575
|
+
} catch {
|
|
576
|
+
return { width: b.width, height: b.height };
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
function getVerticalHugTextAdjust(parent, child) {
|
|
580
|
+
if (!parent.hugContent) return null;
|
|
581
|
+
if (parent.layoutMode !== "vertical-stack" && parent.layoutMode !== "stack") return null;
|
|
582
|
+
if (!isElement(child)) return null;
|
|
583
|
+
const el = child;
|
|
584
|
+
if (el.type !== "text") return null;
|
|
585
|
+
try {
|
|
586
|
+
const glyphHeight = measureTextGlyphHeightForStackHug(el);
|
|
587
|
+
const minBoxHeight = Math.max(0, Number(el.minBoxHeight) || 0);
|
|
588
|
+
const boxHeight = Math.max(typeof el.height === "number" ? el.height : glyphHeight, minBoxHeight);
|
|
589
|
+
const vAlign = el.verticalAlign ?? "top";
|
|
590
|
+
const extra = Math.max(0, boxHeight - glyphHeight);
|
|
591
|
+
let topOffset = 0;
|
|
592
|
+
if (vAlign === "middle" || vAlign === "center") topOffset = extra / 2;
|
|
593
|
+
else if (vAlign === "bottom") topOffset = extra;
|
|
594
|
+
return { topOffset, glyphHeight };
|
|
595
|
+
} catch {
|
|
596
|
+
return null;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
457
599
|
function simpleWidth(node) {
|
|
458
600
|
if (isElement(node)) {
|
|
459
601
|
const w = node.width;
|
|
@@ -494,23 +636,33 @@ function resolveStackGroupEffectivePositions(group, pageChildren, options) {
|
|
|
494
636
|
const out = /* @__PURE__ */ new Map();
|
|
495
637
|
const sizes = /* @__PURE__ */ new Map();
|
|
496
638
|
for (const c of kids) {
|
|
497
|
-
|
|
498
|
-
sizes.set(c.id, { width: b.width, height: b.height });
|
|
639
|
+
sizes.set(c.id, getStackChildLayoutSize(group, c, pageChildren));
|
|
499
640
|
}
|
|
500
641
|
if (isVertical) {
|
|
501
642
|
let prevBottom = padTop;
|
|
502
643
|
let firstSeen = false;
|
|
644
|
+
const placedIds = [];
|
|
503
645
|
for (let i = 0; i < kids.length; i++) {
|
|
504
646
|
const child = kids[i];
|
|
505
647
|
const storedTop = getNodeTop(child);
|
|
506
648
|
const storedLeft = getNodeLeft(child);
|
|
507
649
|
const mTop = child.marginTop ?? 0;
|
|
508
650
|
const mLeft = child.marginLeft ?? 0;
|
|
509
|
-
const
|
|
651
|
+
const hugAdjust = getVerticalHugTextAdjust(group, child);
|
|
652
|
+
const hugTopOffset = hugAdjust ? hugAdjust.topOffset : 0;
|
|
653
|
+
const visualTop = !firstSeen ? padTop + storedTop + mTop : prevBottom + gap + storedTop + mTop;
|
|
654
|
+
const effectiveTop = firstSeen ? visualTop : visualTop - hugTopOffset;
|
|
655
|
+
if (firstSeen && hugTopOffset > 0 && placedIds.length > 0) {
|
|
656
|
+
for (const placedId of placedIds) {
|
|
657
|
+
const placed = out.get(placedId);
|
|
658
|
+
if (placed) out.set(placedId, { ...placed, top: placed.top + hugTopOffset });
|
|
659
|
+
}
|
|
660
|
+
}
|
|
510
661
|
firstSeen = true;
|
|
511
662
|
out.set(child.id, { top: effectiveTop, left: padLeft + storedLeft + mLeft });
|
|
512
|
-
const h = sizes.get(child.id).height;
|
|
513
|
-
prevBottom = effectiveTop + h + (child.marginBottom ?? 0);
|
|
663
|
+
const h = hugAdjust ? hugAdjust.glyphHeight : sizes.get(child.id).height;
|
|
664
|
+
prevBottom = effectiveTop + hugTopOffset + h + (child.marginBottom ?? 0);
|
|
665
|
+
placedIds.push(child.id);
|
|
514
666
|
}
|
|
515
667
|
} else {
|
|
516
668
|
let prevRight = padLeft;
|
|
@@ -531,7 +683,20 @@ function resolveStackGroupEffectivePositions(group, pageChildren, options) {
|
|
|
531
683
|
const containerW = typeof group.width === "number" ? group.width : void 0;
|
|
532
684
|
const containerH = typeof group.height === "number" ? group.height : void 0;
|
|
533
685
|
const mainContainer = isVertical ? containerH : containerW;
|
|
534
|
-
|
|
686
|
+
let crossContainer = isVertical ? containerW : containerH;
|
|
687
|
+
if (kids.length > 0) {
|
|
688
|
+
let maxCross = 0;
|
|
689
|
+
for (const c of kids) {
|
|
690
|
+
const sz = sizes.get(c.id);
|
|
691
|
+
if (!sz) continue;
|
|
692
|
+
const cross = isVertical ? sz.width : sz.height;
|
|
693
|
+
if (cross > maxCross) maxCross = cross;
|
|
694
|
+
}
|
|
695
|
+
const crossPad0 = isVertical ? padLeft : padTop;
|
|
696
|
+
const crossPadEnd = isVertical ? padRight : padBottom;
|
|
697
|
+
const computed = maxCross + crossPad0 + crossPadEnd;
|
|
698
|
+
crossContainer = crossContainer != null ? Math.max(crossContainer, computed) : computed;
|
|
699
|
+
}
|
|
535
700
|
if (align !== "start" && crossContainer != null && kids.length > 0) {
|
|
536
701
|
const crossPad0 = isVertical ? padLeft : padTop;
|
|
537
702
|
const crossPadEnd = isVertical ? padRight : padBottom;
|
|
@@ -609,7 +774,8 @@ function resolveStackGroupEffectivePositions(group, pageChildren, options) {
|
|
|
609
774
|
if (!pos) continue;
|
|
610
775
|
const startMain = cursor + marginStart;
|
|
611
776
|
if (isVertical) {
|
|
612
|
-
|
|
777
|
+
const hugAdjust = getVerticalHugTextAdjust(group, child);
|
|
778
|
+
out.set(child.id, { top: startMain - ((hugAdjust == null ? void 0 : hugAdjust.topOffset) ?? 0), left: pos.left });
|
|
613
779
|
} else {
|
|
614
780
|
out.set(child.id, { top: pos.top, left: startMain });
|
|
615
781
|
}
|
|
@@ -631,13 +797,16 @@ function groupBoundsFromChildren(group, pageChildren, options) {
|
|
|
631
797
|
const positions = isStack ? resolveStackGroupEffectivePositions(group, pageChildren) : null;
|
|
632
798
|
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
633
799
|
for (const child of kids) {
|
|
634
|
-
const
|
|
800
|
+
const sz = isStack ? getStackChildLayoutSize(group, child, pageChildren) : (() => {
|
|
801
|
+
const b = getNodeBounds(child, pageChildren);
|
|
802
|
+
return { width: b.width, height: b.height };
|
|
803
|
+
})();
|
|
635
804
|
const cl = positions ? ((_a2 = positions.get(child.id)) == null ? void 0 : _a2.left) ?? getNodeLeft(child) : getNodeLeft(child);
|
|
636
805
|
const ct = positions ? ((_b = positions.get(child.id)) == null ? void 0 : _b.top) ?? getNodeTop(child) : getNodeTop(child);
|
|
637
806
|
minX = Math.min(minX, cl);
|
|
638
807
|
minY = Math.min(minY, ct);
|
|
639
|
-
maxX = Math.max(maxX, cl +
|
|
640
|
-
maxY = Math.max(maxY, ct +
|
|
808
|
+
maxX = Math.max(maxX, cl + sz.width);
|
|
809
|
+
maxY = Math.max(maxY, ct + sz.height);
|
|
641
810
|
}
|
|
642
811
|
if (isStack) {
|
|
643
812
|
const padRight = group.paddingRight ?? 0;
|
|
@@ -1058,6 +1227,7 @@ const useEditorStore = zustand.create((set, get) => ({
|
|
|
1058
1227
|
showDynamicLabels: false,
|
|
1059
1228
|
showSections: false,
|
|
1060
1229
|
hoveredGroupId: null,
|
|
1230
|
+
revealedLayerId: null,
|
|
1061
1231
|
history: [cloneCanvas(initialCanvas)],
|
|
1062
1232
|
historyIndex: 0,
|
|
1063
1233
|
lastCommittedSignature: canvasSignature(initialCanvas),
|
|
@@ -1597,7 +1767,16 @@ const useEditorStore = zustand.create((set, get) => ({
|
|
|
1597
1767
|
let nextChildren = currentPage.children;
|
|
1598
1768
|
const newNodes = [];
|
|
1599
1769
|
const duplicateAtPageLevel = [];
|
|
1600
|
-
|
|
1770
|
+
const idSet = new Set(ids);
|
|
1771
|
+
const filteredIds = ids.filter((id) => {
|
|
1772
|
+
let p = findParentGroup(currentPage.children, id);
|
|
1773
|
+
while (p) {
|
|
1774
|
+
if (idSet.has(p.id)) return false;
|
|
1775
|
+
p = findParentGroup(currentPage.children, p.id);
|
|
1776
|
+
}
|
|
1777
|
+
return true;
|
|
1778
|
+
});
|
|
1779
|
+
for (const id of filteredIds) {
|
|
1601
1780
|
const node = findNodeById(nextChildren, id);
|
|
1602
1781
|
if (!node) continue;
|
|
1603
1782
|
const parent = findParentGroup(nextChildren, id);
|
|
@@ -1614,19 +1793,9 @@ const useEditorStore = zustand.create((set, get) => ({
|
|
|
1614
1793
|
}
|
|
1615
1794
|
const pageLevelIds = new Set(duplicateAtPageLevel);
|
|
1616
1795
|
if (pageLevelIds.size > 0) {
|
|
1617
|
-
const
|
|
1618
|
-
const PAGE_GAP = 16;
|
|
1619
|
-
let maxBottom = PAGE_MARGIN;
|
|
1620
|
-
for (const node of currentPage.children) {
|
|
1621
|
-
const b = getNodeBounds(node, currentPage.children);
|
|
1622
|
-
if (b.bottom > maxBottom) maxBottom = b.bottom;
|
|
1623
|
-
}
|
|
1624
|
-
const pageLevelClones = newNodes.filter((n) => pageLevelIds.has(n.id));
|
|
1625
|
-
const bbox = getBoundingBoxOfRoots(pageLevelClones);
|
|
1626
|
-
const shiftX = PAGE_MARGIN - bbox.left;
|
|
1627
|
-
const shiftY = maxBottom + PAGE_GAP - bbox.top;
|
|
1796
|
+
const DUPLICATE_NUDGE = 16;
|
|
1628
1797
|
nextChildren = nextChildren.map(
|
|
1629
|
-
(node) => pageLevelIds.has(node.id) ? shiftNodeBy(node,
|
|
1798
|
+
(node) => pageLevelIds.has(node.id) ? shiftNodeBy(node, DUPLICATE_NUDGE, DUPLICATE_NUDGE) : node
|
|
1630
1799
|
);
|
|
1631
1800
|
}
|
|
1632
1801
|
let nextCanvas = updateCurrentPageChildren(state.canvas, () => nextChildren);
|
|
@@ -2043,12 +2212,19 @@ const useEditorStore = zustand.create((set, get) => ({
|
|
|
2043
2212
|
if (firstNodeIndex >= 0) {
|
|
2044
2213
|
insertIndex = firstNodeIndex;
|
|
2045
2214
|
}
|
|
2215
|
+
} else if (!commonParent && topLevelIds.length > 0) {
|
|
2216
|
+
const firstNodeIndex = currentPage.children.findIndex((child) => child.id === topLevelIds[0]);
|
|
2217
|
+
if (firstNodeIndex >= 0) {
|
|
2218
|
+
insertIndex = firstNodeIndex;
|
|
2219
|
+
}
|
|
2046
2220
|
}
|
|
2047
|
-
const
|
|
2221
|
+
const orderSource = commonParent ? commonParent.children : currentPage.children;
|
|
2222
|
+
const orderIndex = /* @__PURE__ */ new Map();
|
|
2223
|
+
orderSource.forEach((n, i) => orderIndex.set(n.id, i));
|
|
2048
2224
|
nodesToGroup.sort((a, b) => {
|
|
2049
|
-
const
|
|
2050
|
-
const
|
|
2051
|
-
return
|
|
2225
|
+
const ai = orderIndex.has(a.id) ? orderIndex.get(a.id) : Number.MAX_SAFE_INTEGER;
|
|
2226
|
+
const bi = orderIndex.has(b.id) ? orderIndex.get(b.id) : Number.MAX_SAFE_INTEGER;
|
|
2227
|
+
return ai - bi;
|
|
2052
2228
|
});
|
|
2053
2229
|
const pageChildren = currentPage.children;
|
|
2054
2230
|
let groupLeft = Infinity, groupTop = Infinity;
|
|
@@ -2139,8 +2315,7 @@ const useEditorStore = zustand.create((set, get) => ({
|
|
|
2139
2315
|
const dt = target.top - cur.top;
|
|
2140
2316
|
return updateNodeInTree(t, nodeId, { left: dl, top: dt });
|
|
2141
2317
|
};
|
|
2142
|
-
const
|
|
2143
|
-
const promotionOrder = insertReversed ? group.children.map((_, i) => group.children.length - 1 - i) : group.children.map((_, i) => i);
|
|
2318
|
+
const promotionOrder = group.children.map((_, i) => i);
|
|
2144
2319
|
for (let slot = 0; slot < promotionOrder.length; slot++) {
|
|
2145
2320
|
const i = promotionOrder[slot];
|
|
2146
2321
|
const child = group.children[i];
|
|
@@ -2184,6 +2359,18 @@ const useEditorStore = zustand.create((set, get) => ({
|
|
|
2184
2359
|
}
|
|
2185
2360
|
return { collapsedGroups: newCollapsedSet };
|
|
2186
2361
|
}),
|
|
2362
|
+
revealLayerNode: (id) => set((state) => {
|
|
2363
|
+
if (!id) return { revealedLayerId: null };
|
|
2364
|
+
const currentPage = getCurrentPageFromCanvas(state.canvas);
|
|
2365
|
+
const next = new Set(state.collapsedGroups);
|
|
2366
|
+
let parent = findParentGroup(currentPage.children, id);
|
|
2367
|
+
let guard = 0;
|
|
2368
|
+
while (parent && guard++ < 32) {
|
|
2369
|
+
next.delete(parent.id);
|
|
2370
|
+
parent = findParentGroup(currentPage.children, parent.id);
|
|
2371
|
+
}
|
|
2372
|
+
return { collapsedGroups: next, revealedLayerId: id };
|
|
2373
|
+
}),
|
|
2187
2374
|
// Convenience aliases
|
|
2188
2375
|
groupElements: (ids, name) => get().groupNodes(ids, name),
|
|
2189
2376
|
ungroupElements: (groupId) => get().ungroupNodes(groupId),
|
|
@@ -2630,7 +2817,7 @@ const useEditorStore = zustand.create((set, get) => ({
|
|
|
2630
2817
|
boundFormDefId: config.boundFormDefId,
|
|
2631
2818
|
boundFormDefName: config.boundFormDefName,
|
|
2632
2819
|
themeConfig: config.themeConfig ?? void 0,
|
|
2633
|
-
pdfTextMode: config.pdfTextMode ?? "
|
|
2820
|
+
pdfTextMode: config.pdfTextMode ?? "auto"
|
|
2634
2821
|
};
|
|
2635
2822
|
const committed = commitFromState(state, nextCanvas);
|
|
2636
2823
|
const out = {
|
|
@@ -4236,6 +4423,9 @@ async function loadSvgAsGroup(url) {
|
|
|
4236
4423
|
obj.fill = "#000";
|
|
4237
4424
|
obj.stroke = null;
|
|
4238
4425
|
obj.strokeWidth = 0;
|
|
4426
|
+
obj.objectCaching = false;
|
|
4427
|
+
obj.statefullCache = false;
|
|
4428
|
+
obj.noScaleCache = true;
|
|
4239
4429
|
}
|
|
4240
4430
|
const group = new fabric__namespace.Group(objects, {
|
|
4241
4431
|
originX: "center",
|
|
@@ -4243,8 +4433,14 @@ async function loadSvgAsGroup(url) {
|
|
|
4243
4433
|
selectable: false,
|
|
4244
4434
|
evented: false,
|
|
4245
4435
|
hasControls: false,
|
|
4246
|
-
hasBorders: false
|
|
4436
|
+
hasBorders: false,
|
|
4437
|
+
// Do NOT cache the mask group — Fabric would otherwise bake it to a
|
|
4438
|
+
// bitmap at the group's natural size, so the clipPath edges look soft
|
|
4439
|
+
// / pixelated whenever the host image is scaled up on the canvas.
|
|
4440
|
+
objectCaching: false
|
|
4247
4441
|
});
|
|
4442
|
+
group.statefullCache = false;
|
|
4443
|
+
group.noScaleCache = true;
|
|
4248
4444
|
const viewBoxW = Number(options.width) || group.width || 1;
|
|
4249
4445
|
const viewBoxH = Number(options.height) || group.height || 1;
|
|
4250
4446
|
return { group, viewBoxW, viewBoxH };
|
|
@@ -4262,8 +4458,18 @@ function fitMaskGroupToFrame(maskGroup, frameW, frameH) {
|
|
|
4262
4458
|
selectable: false,
|
|
4263
4459
|
evented: false,
|
|
4264
4460
|
hasControls: false,
|
|
4265
|
-
hasBorders: false
|
|
4461
|
+
hasBorders: false,
|
|
4462
|
+
objectCaching: false
|
|
4266
4463
|
});
|
|
4464
|
+
const stack = [maskGroup];
|
|
4465
|
+
while (stack.length) {
|
|
4466
|
+
const node = stack.pop();
|
|
4467
|
+
node.objectCaching = false;
|
|
4468
|
+
node.statefullCache = false;
|
|
4469
|
+
node.noScaleCache = true;
|
|
4470
|
+
const kids = node._objects;
|
|
4471
|
+
if (kids && kids.length) stack.push(...kids);
|
|
4472
|
+
}
|
|
4267
4473
|
maskGroup.absolutePositioned = false;
|
|
4268
4474
|
maskGroup.excludeFromExport = true;
|
|
4269
4475
|
maskGroup.inverted = false;
|
|
@@ -4386,7 +4592,7 @@ async function buildLuminanceAlphaCanvas(svgUrl, frameW, frameH) {
|
|
|
4386
4592
|
const b = px[i + 2];
|
|
4387
4593
|
const a = px[i + 3];
|
|
4388
4594
|
const lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
4389
|
-
const alpha = lum / 255 * a;
|
|
4595
|
+
const alpha = (255 - lum) / 255 * a;
|
|
4390
4596
|
px[i] = 255;
|
|
4391
4597
|
px[i + 1] = 255;
|
|
4392
4598
|
px[i + 2] = 255;
|
|
@@ -5950,10 +6156,6 @@ const shouldShowOriginalTextBounds = () => {
|
|
|
5950
6156
|
return false;
|
|
5951
6157
|
}
|
|
5952
6158
|
};
|
|
5953
|
-
const hasActiveTextPathDescendant = (obj) => {
|
|
5954
|
-
const kids = (obj == null ? void 0 : obj._objects) || [];
|
|
5955
|
-
return kids.some((child) => hasActiveTextPath(child) || hasActiveTextPathDescendant(child));
|
|
5956
|
-
};
|
|
5957
6159
|
function applyWarpFillStyle(ctx, obj) {
|
|
5958
6160
|
const filler = obj.fill;
|
|
5959
6161
|
if (filler && typeof filler === "object" && Array.isArray(filler.colorStops) && filler.coords) {
|
|
@@ -6146,6 +6348,79 @@ function applyTextPathControls(textbox) {
|
|
|
6146
6348
|
obj.controls = { ...defaultControls };
|
|
6147
6349
|
const halfWOf = (t) => (t.width || 0) / 2;
|
|
6148
6350
|
const halfHOf = (t) => (t.height || 0) / 2;
|
|
6351
|
+
{
|
|
6352
|
+
const cornerLayout = {
|
|
6353
|
+
tl: { sx: -1, sy: -1 },
|
|
6354
|
+
tr: { sx: 1, sy: -1 },
|
|
6355
|
+
br: { sx: 1, sy: 1 },
|
|
6356
|
+
bl: { sx: -1, sy: 1 },
|
|
6357
|
+
mt: { sx: 0, sy: -1 },
|
|
6358
|
+
mb: { sx: 0, sy: 1 },
|
|
6359
|
+
ml: { sx: -1, sy: 0 },
|
|
6360
|
+
mr: { sx: 1, sy: 0 }
|
|
6361
|
+
};
|
|
6362
|
+
for (const key of Object.keys(cornerLayout)) {
|
|
6363
|
+
const existing = obj.controls[key];
|
|
6364
|
+
if (!existing) continue;
|
|
6365
|
+
const { sx, sy } = cornerLayout[key];
|
|
6366
|
+
const customPosition = (_d2, finalMatrix, target) => {
|
|
6367
|
+
const t = target;
|
|
6368
|
+
const bounds = getTextPathHitBounds(t);
|
|
6369
|
+
if (!bounds) {
|
|
6370
|
+
return existing.positionHandler.call(existing, _d2, finalMatrix, target);
|
|
6371
|
+
}
|
|
6372
|
+
const cx = (bounds.minX + bounds.maxX) / 2;
|
|
6373
|
+
const cy = (bounds.minY + bounds.maxY) / 2;
|
|
6374
|
+
const x = sx < 0 ? bounds.minX : sx > 0 ? bounds.maxX : cx;
|
|
6375
|
+
const y = sy < 0 ? bounds.minY : sy > 0 ? bounds.maxY : cy;
|
|
6376
|
+
return scaleLocalToScreen(t, new fabric__namespace.Point(x, y)).transform(finalMatrix);
|
|
6377
|
+
};
|
|
6378
|
+
obj.controls[key] = new fabric__namespace.Control({
|
|
6379
|
+
x: existing.x,
|
|
6380
|
+
y: existing.y,
|
|
6381
|
+
offsetX: existing.offsetX,
|
|
6382
|
+
offsetY: existing.offsetY,
|
|
6383
|
+
cursorStyle: existing.cursorStyle,
|
|
6384
|
+
cursorStyleHandler: existing.cursorStyleHandler,
|
|
6385
|
+
actionName: existing.actionName,
|
|
6386
|
+
actionHandler: existing.actionHandler,
|
|
6387
|
+
mouseDownHandler: existing.mouseDownHandler,
|
|
6388
|
+
mouseUpHandler: existing.mouseUpHandler,
|
|
6389
|
+
getActionName: existing.getActionName,
|
|
6390
|
+
render: existing.render,
|
|
6391
|
+
sizeX: existing.sizeX,
|
|
6392
|
+
sizeY: existing.sizeY,
|
|
6393
|
+
touchSizeX: existing.touchSizeX,
|
|
6394
|
+
touchSizeY: existing.touchSizeY,
|
|
6395
|
+
withConnection: existing.withConnection,
|
|
6396
|
+
positionHandler: customPosition
|
|
6397
|
+
});
|
|
6398
|
+
}
|
|
6399
|
+
const mtrExisting = obj.controls.mtr;
|
|
6400
|
+
if (mtrExisting) {
|
|
6401
|
+
const customMtrPosition = (_d2, finalMatrix, target) => {
|
|
6402
|
+
const t = target;
|
|
6403
|
+
const bounds = getTextPathHitBounds(t);
|
|
6404
|
+
if (!bounds) return mtrExisting.positionHandler.call(mtrExisting, _d2, finalMatrix, target);
|
|
6405
|
+
const cx = (bounds.minX + bounds.maxX) / 2;
|
|
6406
|
+
const offset = mtrExisting.offsetY ?? -40;
|
|
6407
|
+
return scaleLocalToScreen(t, new fabric__namespace.Point(cx, bounds.minY)).transform(finalMatrix).add(new fabric__namespace.Point(0, offset));
|
|
6408
|
+
};
|
|
6409
|
+
obj.controls.mtr = new fabric__namespace.Control({
|
|
6410
|
+
x: mtrExisting.x,
|
|
6411
|
+
y: mtrExisting.y,
|
|
6412
|
+
offsetX: mtrExisting.offsetX,
|
|
6413
|
+
offsetY: mtrExisting.offsetY,
|
|
6414
|
+
cursorStyle: mtrExisting.cursorStyle,
|
|
6415
|
+
cursorStyleHandler: mtrExisting.cursorStyleHandler,
|
|
6416
|
+
actionName: mtrExisting.actionName,
|
|
6417
|
+
actionHandler: mtrExisting.actionHandler,
|
|
6418
|
+
render: mtrExisting.render,
|
|
6419
|
+
withConnection: mtrExisting.withConnection,
|
|
6420
|
+
positionHandler: customMtrPosition
|
|
6421
|
+
});
|
|
6422
|
+
}
|
|
6423
|
+
}
|
|
6149
6424
|
const renderPivot = (ctx, left, top) => {
|
|
6150
6425
|
ctx.save();
|
|
6151
6426
|
ctx.translate(left, top);
|
|
@@ -6767,10 +7042,11 @@ if (typeof TextboxProto._renderControls === "function" && !TextboxProto.__pixldo
|
|
|
6767
7042
|
if (!hostCanvas) return;
|
|
6768
7043
|
const hoverBounds = getTextPathHitBounds(this);
|
|
6769
7044
|
const active = (_d = hostCanvas.getActiveObject) == null ? void 0 : _d.call(hostCanvas);
|
|
6770
|
-
const
|
|
6771
|
-
if (hoverBounds && (this.__pdTextPathHovered ||
|
|
7045
|
+
const isDirectlyActive = active === this;
|
|
7046
|
+
if (hoverBounds && (this.__pdTextPathHovered || isDirectlyActive)) {
|
|
6772
7047
|
drawTextPathBounds(ctx, this, hoverBounds, hostCanvas);
|
|
6773
7048
|
}
|
|
7049
|
+
if (!isDirectlyActive) return;
|
|
6774
7050
|
const resolved = resolveTextPath(this.textPath, this.width || 0, this.fontSize || 16);
|
|
6775
7051
|
const path = resolved ? measurePath(resolved.d) : null;
|
|
6776
7052
|
if (!path) return;
|
|
@@ -6884,13 +7160,6 @@ if (typeof TextboxProto._renderControls === "function" && !TextboxProto.__pixldo
|
|
|
6884
7160
|
if (!showOrig) {
|
|
6885
7161
|
this.hasBorders = false;
|
|
6886
7162
|
this.borderColor = "rgba(0,0,0,0)";
|
|
6887
|
-
const filtered = {};
|
|
6888
|
-
for (const key of Object.keys(prevControls || {})) {
|
|
6889
|
-
if (key === "mtr" || key === "tpPivot" || key.startsWith("cr") || key.startsWith("rs") || key.startsWith("bz")) {
|
|
6890
|
-
filtered[key] = prevControls[key];
|
|
6891
|
-
}
|
|
6892
|
-
}
|
|
6893
|
-
this.controls = filtered;
|
|
6894
7163
|
}
|
|
6895
7164
|
try {
|
|
6896
7165
|
drawWarpGuides.call(this, ctx);
|
|
@@ -7001,26 +7270,7 @@ if (GroupProto && typeof GroupProto._renderControls === "function" && !GroupProt
|
|
|
7001
7270
|
const host = this.canvas;
|
|
7002
7271
|
const active = (_a2 = host == null ? void 0 : host.getActiveObject) == null ? void 0 : _a2.call(host);
|
|
7003
7272
|
const isActiveOrInActive = !!host && (active === this || !!active && typeof active.contains === "function" && active.contains(this, true));
|
|
7004
|
-
|
|
7005
|
-
const prevBorders = this.hasBorders;
|
|
7006
|
-
const prevControls = this.hasControls;
|
|
7007
|
-
const prevBorderColor = this.borderColor;
|
|
7008
|
-
if (hideWarpChildBounds) {
|
|
7009
|
-
this.hasBorders = false;
|
|
7010
|
-
this.hasControls = false;
|
|
7011
|
-
this.borderColor = "rgba(0,0,0,0)";
|
|
7012
|
-
styleOverride = { ...styleOverride || {}, hasBorders: false, hasControls: false, borderColor: "rgba(0,0,0,0)" };
|
|
7013
|
-
childrenOverride = { ...childrenOverride || {}, hasBorders: false, borderColor: "rgba(0,0,0,0)" };
|
|
7014
|
-
}
|
|
7015
|
-
try {
|
|
7016
|
-
GroupProto.__pixldocsOrigRenderControls.call(this, ctx, styleOverride, childrenOverride);
|
|
7017
|
-
} finally {
|
|
7018
|
-
if (hideWarpChildBounds) {
|
|
7019
|
-
this.hasBorders = prevBorders;
|
|
7020
|
-
this.hasControls = prevControls;
|
|
7021
|
-
this.borderColor = prevBorderColor;
|
|
7022
|
-
}
|
|
7023
|
-
}
|
|
7273
|
+
GroupProto.__pixldocsOrigRenderControls.call(this, ctx, styleOverride, childrenOverride);
|
|
7024
7274
|
if (!host || !isActiveOrInActive) return;
|
|
7025
7275
|
const drawForDescendants = (parent) => {
|
|
7026
7276
|
const kids = (parent == null ? void 0 : parent._objects) || [];
|
|
@@ -7045,17 +7295,12 @@ if (!TextboxProtoHit.__pixldocsOrigGetCoords && typeof TextboxProtoHit.getCoords
|
|
|
7045
7295
|
const bounds = getTextPathHitBounds(this);
|
|
7046
7296
|
if (!bounds) return TextboxProtoHit.__pixldocsOrigGetCoords.call(this);
|
|
7047
7297
|
const matrix = this.calcTransformMatrix();
|
|
7048
|
-
|
|
7298
|
+
return [
|
|
7049
7299
|
new fabric__namespace.Point(bounds.minX, bounds.minY),
|
|
7050
7300
|
new fabric__namespace.Point(bounds.maxX, bounds.minY),
|
|
7051
7301
|
new fabric__namespace.Point(bounds.maxX, bounds.maxY),
|
|
7052
7302
|
new fabric__namespace.Point(bounds.minX, bounds.maxY)
|
|
7053
7303
|
].map((p) => fabric__namespace.util.transformPoint(p, matrix));
|
|
7054
|
-
if (this.group) {
|
|
7055
|
-
const groupMatrix = this.group.calcTransformMatrix();
|
|
7056
|
-
return coords.map((p) => fabric__namespace.util.transformPoint(p, groupMatrix));
|
|
7057
|
-
}
|
|
7058
|
-
return coords;
|
|
7059
7304
|
};
|
|
7060
7305
|
}
|
|
7061
7306
|
if (!TextboxProtoHit.__pixldocsOrigContainsPoint && typeof TextboxProtoHit.containsPoint === "function") {
|
|
@@ -8564,7 +8809,7 @@ function createShape(element) {
|
|
|
8564
8809
|
}
|
|
8565
8810
|
}
|
|
8566
8811
|
function createText(element) {
|
|
8567
|
-
var _a2, _b, _c;
|
|
8812
|
+
var _a2, _b, _c, _d, _e;
|
|
8568
8813
|
const overflowPolicy = element.overflowPolicy || "grow-and-push";
|
|
8569
8814
|
let text = element.text || "Text";
|
|
8570
8815
|
let fontSize = element.fontSize || 16;
|
|
@@ -8712,6 +8957,23 @@ function createText(element) {
|
|
|
8712
8957
|
objectCaching: false,
|
|
8713
8958
|
noScaleCache: true,
|
|
8714
8959
|
splitByGrapheme,
|
|
8960
|
+
// Outline (stroke) support for text — kept in sync with PageCanvas
|
|
8961
|
+
// sync path. Only apply when BOTH a stroke color and positive width are
|
|
8962
|
+
// explicitly set; otherwise fabric defaults stroke to black and renders
|
|
8963
|
+
// an unwanted outline on existing text elements that carry a stray
|
|
8964
|
+
// strokeWidth (e.g. from PDF imports).
|
|
8965
|
+
...(() => {
|
|
8966
|
+
const s = element.stroke;
|
|
8967
|
+
const w = Number(element.strokeWidth) || 0;
|
|
8968
|
+
const has = !!s && w > 0;
|
|
8969
|
+
return has ? {
|
|
8970
|
+
stroke: s,
|
|
8971
|
+
strokeWidth: w,
|
|
8972
|
+
paintFirst: element.paintFirst || "fill",
|
|
8973
|
+
strokeUniform: true,
|
|
8974
|
+
strokeLineJoin: "round"
|
|
8975
|
+
} : { stroke: void 0, strokeWidth: 0 };
|
|
8976
|
+
})(),
|
|
8715
8977
|
// When inline markdown formatting is enabled, the displayed text is the
|
|
8716
8978
|
// PARSED plain text (markdown source lives separately on the element).
|
|
8717
8979
|
// Allowing canvas inline editing would let the user edit that plain text
|
|
@@ -8761,6 +9023,21 @@ function createText(element) {
|
|
|
8761
9023
|
});
|
|
8762
9024
|
} catch {
|
|
8763
9025
|
}
|
|
9026
|
+
try {
|
|
9027
|
+
const baseCtrls = (_d = (_c = fabric__namespace.Object) == null ? void 0 : _c.prototype) == null ? void 0 : _d.controls;
|
|
9028
|
+
if (baseCtrls) {
|
|
9029
|
+
textbox.controls = {
|
|
9030
|
+
...textbox.controls || {},
|
|
9031
|
+
tl: baseCtrls.tl,
|
|
9032
|
+
tr: baseCtrls.tr,
|
|
9033
|
+
bl: baseCtrls.bl,
|
|
9034
|
+
br: baseCtrls.br,
|
|
9035
|
+
mt: baseCtrls.mt,
|
|
9036
|
+
mb: baseCtrls.mb
|
|
9037
|
+
};
|
|
9038
|
+
}
|
|
9039
|
+
} catch {
|
|
9040
|
+
}
|
|
8764
9041
|
const scaleXAfterSet = textbox.scaleX ?? 1;
|
|
8765
9042
|
const scaleYAfterSet = textbox.scaleY ?? 1;
|
|
8766
9043
|
if (Math.abs(widthAfterSet - targetWidth) > 0.01 || Math.abs(scaleXAfterSet - targetScaleX) > 0.01 || Math.abs(scaleYAfterSet - targetScaleY) > 0.01) {
|
|
@@ -8791,7 +9068,7 @@ function createText(element) {
|
|
|
8791
9068
|
finalFontSize: fontSize,
|
|
8792
9069
|
textboxWidth: textbox.width,
|
|
8793
9070
|
textboxHeight: textbox.height,
|
|
8794
|
-
lineCount: ((
|
|
9071
|
+
lineCount: ((_e = textbox.textLines) == null ? void 0 : _e.length) || 0,
|
|
8795
9072
|
lines: (textbox.textLines || []).map((line) => Array.isArray(line) ? line.join("") : String(line ?? "")),
|
|
8796
9073
|
widthMetrics: getTextboxWidthFitMetrics(textbox, targetWidth)
|
|
8797
9074
|
}));
|
|
@@ -9350,16 +9627,7 @@ function renderSmartElementToDataUri(type, props, width, height) {
|
|
|
9350
9627
|
if (!svg) return null;
|
|
9351
9628
|
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
9352
9629
|
}
|
|
9353
|
-
const KEY_SHOW_ORIG_TEXT_BOUNDS = "pixldocs:showOriginalTextBounds";
|
|
9354
9630
|
const EVT_SHOW_ORIG_TEXT_BOUNDS = "pixldocs:showOriginalTextBoundsChanged";
|
|
9355
|
-
function getShowOriginalTextBounds() {
|
|
9356
|
-
if (typeof window === "undefined") return false;
|
|
9357
|
-
try {
|
|
9358
|
-
return window.localStorage.getItem(KEY_SHOW_ORIG_TEXT_BOUNDS) === "1";
|
|
9359
|
-
} catch {
|
|
9360
|
-
return false;
|
|
9361
|
-
}
|
|
9362
|
-
}
|
|
9363
9631
|
function subscribeShowOriginalTextBounds(cb) {
|
|
9364
9632
|
const handler = (e) => cb(!!e.detail);
|
|
9365
9633
|
window.addEventListener(EVT_SHOW_ORIG_TEXT_BOUNDS, handler);
|
|
@@ -9513,31 +9781,12 @@ try {
|
|
|
9513
9781
|
console.warn("[PageCanvas] Failed to apply global selection defaults:", e);
|
|
9514
9782
|
}
|
|
9515
9783
|
function applyWarpAwareSelectionBorders(selection) {
|
|
9516
|
-
if (
|
|
9517
|
-
|
|
9518
|
-
|
|
9519
|
-
}
|
|
9520
|
-
return;
|
|
9521
|
-
}
|
|
9522
|
-
const hasWarpedTextObject = (obj) => {
|
|
9523
|
-
if (obj instanceof fabric__namespace.Textbox) {
|
|
9524
|
-
const tp = obj.textPath;
|
|
9525
|
-
return !!(tp && tp.preset && tp.preset !== "none");
|
|
9526
|
-
}
|
|
9527
|
-
const children = obj._objects;
|
|
9528
|
-
return Array.isArray(children) && children.some((child) => hasWarpedTextObject(child));
|
|
9529
|
-
};
|
|
9530
|
-
const hasWarpedText = selection.getObjects().some((obj) => {
|
|
9531
|
-
if (!hasWarpedTextObject(obj)) return false;
|
|
9532
|
-
const tp = obj.textPath;
|
|
9533
|
-
return !tp || tp.preset !== "none";
|
|
9534
|
-
});
|
|
9535
|
-
if (hasWarpedText) {
|
|
9536
|
-
if (selection.__pixldocsOrigASHasBorders === void 0) {
|
|
9537
|
-
selection.__pixldocsOrigASHasBorders = selection.hasBorders;
|
|
9538
|
-
}
|
|
9539
|
-
selection.hasBorders = false;
|
|
9784
|
+
if (selection.__pixldocsOrigASHasBorders !== void 0) {
|
|
9785
|
+
selection.hasBorders = selection.__pixldocsOrigASHasBorders;
|
|
9786
|
+
delete selection.__pixldocsOrigASHasBorders;
|
|
9540
9787
|
}
|
|
9788
|
+
selection.hasBorders = true;
|
|
9789
|
+
selection.hasControls = true;
|
|
9541
9790
|
}
|
|
9542
9791
|
const PageCanvas = react.forwardRef(
|
|
9543
9792
|
({
|
|
@@ -9603,7 +9852,46 @@ const PageCanvas = react.forwardRef(
|
|
|
9603
9852
|
const [sizeLabel, setSizeLabel] = react.useState(null);
|
|
9604
9853
|
const [ready, setReady] = react.useState(false);
|
|
9605
9854
|
const [unlockRequestId, setUnlockRequestId] = react.useState(0);
|
|
9606
|
-
react.
|
|
9855
|
+
const applyLogicalGroupSelectionVisualState = react.useCallback((selection, groupId) => {
|
|
9856
|
+
var _a2;
|
|
9857
|
+
selection.__pixldocsGroupSelection = groupId;
|
|
9858
|
+
delete selection.__pixldocsLogicalGroupIds;
|
|
9859
|
+
selection.hasBorders = true;
|
|
9860
|
+
const members = selection.getObjects();
|
|
9861
|
+
for (const prev of suppressGroupMemberBordersRef.current) {
|
|
9862
|
+
if (members.includes(prev)) continue;
|
|
9863
|
+
const origBorders = prev.__pixldocsOrigHasBorders;
|
|
9864
|
+
const origControls = prev.__pixldocsOrigHasControls;
|
|
9865
|
+
const origLockX = prev.__pixldocsOrigLockScalingX;
|
|
9866
|
+
if (origBorders !== void 0) prev.hasBorders = origBorders;
|
|
9867
|
+
if (origControls !== void 0) prev.hasControls = origControls;
|
|
9868
|
+
if (origLockX !== void 0) {
|
|
9869
|
+
prev.lockScalingX = origLockX;
|
|
9870
|
+
prev.lockScalingY = prev.__pixldocsOrigLockScalingY;
|
|
9871
|
+
}
|
|
9872
|
+
delete prev.__pixldocsOrigHasBorders;
|
|
9873
|
+
delete prev.__pixldocsOrigHasControls;
|
|
9874
|
+
delete prev.__pixldocsOrigLockScalingX;
|
|
9875
|
+
delete prev.__pixldocsOrigLockScalingY;
|
|
9876
|
+
}
|
|
9877
|
+
suppressGroupMemberBordersRef.current = members;
|
|
9878
|
+
for (const m of members) {
|
|
9879
|
+
if (m.__pixldocsOrigHasBorders === void 0) m.__pixldocsOrigHasBorders = m.hasBorders;
|
|
9880
|
+
if (m.__pixldocsOrigHasControls === void 0) m.__pixldocsOrigHasControls = m.hasControls;
|
|
9881
|
+
m.hasBorders = false;
|
|
9882
|
+
m.hasControls = false;
|
|
9883
|
+
if (m.__cropGroup || ((_a2 = m._ct) == null ? void 0 : _a2.isCropGroup)) {
|
|
9884
|
+
if (m.__pixldocsOrigLockScalingX === void 0) {
|
|
9885
|
+
m.__pixldocsOrigLockScalingX = m.lockScalingX;
|
|
9886
|
+
m.__pixldocsOrigLockScalingY = m.lockScalingY;
|
|
9887
|
+
}
|
|
9888
|
+
m.lockScalingX = false;
|
|
9889
|
+
m.lockScalingY = false;
|
|
9890
|
+
}
|
|
9891
|
+
}
|
|
9892
|
+
applyWarpAwareSelectionBorders(selection);
|
|
9893
|
+
}, []);
|
|
9894
|
+
const pageBoundsOptions = react.useMemo(
|
|
9607
9895
|
() => ({ pageContentWidth: canvasWidth, pageContentHeight: canvasHeight }),
|
|
9608
9896
|
[canvasWidth, canvasHeight]
|
|
9609
9897
|
);
|
|
@@ -9613,7 +9901,9 @@ const PageCanvas = react.forwardRef(
|
|
|
9613
9901
|
const setGroupOverlayLiveBoundsRef = react.useRef(setGroupOverlayLiveBounds);
|
|
9614
9902
|
const skipSelectionClearOnDiscardRef = react.useRef(false);
|
|
9615
9903
|
const skipActiveSelectionBakeOnClearRef = react.useRef(false);
|
|
9904
|
+
const preserveEditingScopeOnSelectionClearRef = react.useRef(false);
|
|
9616
9905
|
const preserveActiveSelectionAfterTransformRef = react.useRef(null);
|
|
9906
|
+
const pendingGroupPromotionRef = react.useRef(null);
|
|
9617
9907
|
const imageReloadRequestSeqRef = react.useRef(/* @__PURE__ */ new Map());
|
|
9618
9908
|
react.useRef(null);
|
|
9619
9909
|
const groupBoundsResizingRef = react.useRef(false);
|
|
@@ -9633,6 +9923,7 @@ const PageCanvas = react.forwardRef(
|
|
|
9633
9923
|
const lastResizeScaleTargetRef = react.useRef(null);
|
|
9634
9924
|
const preserveSelectionAfterTransformIdRef = react.useRef(null);
|
|
9635
9925
|
const groupSelectionTransformStartRef = react.useRef(null);
|
|
9926
|
+
const activeSelectionMoveStartRef = react.useRef(null);
|
|
9636
9927
|
setGroupOverlayLiveBoundsRef.current = setGroupOverlayLiveBounds;
|
|
9637
9928
|
const {
|
|
9638
9929
|
selectElements,
|
|
@@ -9653,7 +9944,11 @@ const PageCanvas = react.forwardRef(
|
|
|
9653
9944
|
if (!currentPage || ids.length === 0) return null;
|
|
9654
9945
|
for (const id of ids) {
|
|
9655
9946
|
const node = findNodeById(children, id);
|
|
9656
|
-
if (node && isGroup(node))
|
|
9947
|
+
if (node && isGroup(node)) {
|
|
9948
|
+
const memberIds2 = new Set(getAllElementIds(node.children ?? []));
|
|
9949
|
+
const pureGroupOnly = ids.every((selectedId) => selectedId === node.id || memberIds2.has(selectedId));
|
|
9950
|
+
return pureGroupOnly ? node : null;
|
|
9951
|
+
}
|
|
9657
9952
|
}
|
|
9658
9953
|
const firstId = ids[0];
|
|
9659
9954
|
const parent = findParentGroup(children, firstId);
|
|
@@ -10007,6 +10302,16 @@ const PageCanvas = react.forwardRef(
|
|
|
10007
10302
|
fabricCanvas.__isUserTransforming = false;
|
|
10008
10303
|
fabricCanvas.on("mouse:down", () => {
|
|
10009
10304
|
groupSelectionTransformStartRef.current = null;
|
|
10305
|
+
activeSelectionMoveStartRef.current = null;
|
|
10306
|
+
const active = fabricCanvas.getActiveObject();
|
|
10307
|
+
if (active instanceof fabric__namespace.ActiveSelection) {
|
|
10308
|
+
const rect = active.getBoundingRect();
|
|
10309
|
+
activeSelectionMoveStartRef.current = {
|
|
10310
|
+
selection: active,
|
|
10311
|
+
selectionLeft: rect.left,
|
|
10312
|
+
selectionTop: rect.top
|
|
10313
|
+
};
|
|
10314
|
+
}
|
|
10010
10315
|
if (fabricCanvas._currentTransform) {
|
|
10011
10316
|
fabricCanvas.__isUserTransforming = true;
|
|
10012
10317
|
}
|
|
@@ -10059,8 +10364,21 @@ const PageCanvas = react.forwardRef(
|
|
|
10059
10364
|
didTransformRef.current = true;
|
|
10060
10365
|
});
|
|
10061
10366
|
const syncSelectionToStore = () => {
|
|
10062
|
-
var _a2, _b, _c, _d
|
|
10367
|
+
var _a2, _b, _c, _d;
|
|
10063
10368
|
if (!isActiveRef.current || isRebuildingRef.current || isSyncingSelectionToFabricRef.current || !allowSelection) return;
|
|
10369
|
+
const walkToTopmostGroup = (childId, children, activeEditingGroupId) => {
|
|
10370
|
+
let topmost = null;
|
|
10371
|
+
let currentId = childId;
|
|
10372
|
+
for (let i = 0; i < 32; i++) {
|
|
10373
|
+
const p = findParentGroup(children, currentId);
|
|
10374
|
+
if (!p) break;
|
|
10375
|
+
if (p.backgroundColor) break;
|
|
10376
|
+
if (activeEditingGroupId && p.id === activeEditingGroupId) break;
|
|
10377
|
+
topmost = p;
|
|
10378
|
+
currentId = p.id;
|
|
10379
|
+
}
|
|
10380
|
+
return topmost;
|
|
10381
|
+
};
|
|
10064
10382
|
const active = fabricCanvas.getActiveObject();
|
|
10065
10383
|
let ids = fabricCanvas.getActiveObjects().map((o) => getObjectId(o)).filter((id) => !!id && id !== "__background__");
|
|
10066
10384
|
if (ids.length === 1 && active && active instanceof fabric__namespace.Group && active.__docuforgeSectionGroup) {
|
|
@@ -10087,8 +10405,8 @@ const PageCanvas = react.forwardRef(
|
|
|
10087
10405
|
const state = useEditorStore.getState();
|
|
10088
10406
|
const currentPage2 = (_b = state.canvas.pages) == null ? void 0 : _b.find((p) => p.id === pageId);
|
|
10089
10407
|
const children = (currentPage2 == null ? void 0 : currentPage2.children) ?? [];
|
|
10090
|
-
const parent =
|
|
10091
|
-
const targetIsInCrop = !!(
|
|
10408
|
+
const parent = walkToTopmostGroup(clickedId, children, activeEditingGroupId);
|
|
10409
|
+
const targetIsInCrop = !!(active instanceof fabric__namespace.Group && isCropGroupInCropMode(active) || (active == null ? void 0 : active.group) instanceof fabric__namespace.Group && isCropGroupInCropMode(active.group));
|
|
10092
10410
|
if (parent && !targetIsInCrop && activeEditingGroupId !== parent.id && !(active && active instanceof fabric__namespace.Group && active.__docuforgeSectionGroup)) {
|
|
10093
10411
|
const memberIdSet = new Set(getAllElementIds(parent.children ?? []));
|
|
10094
10412
|
const memberObjs = fabricCanvas.getObjects().filter((o) => {
|
|
@@ -10113,9 +10431,75 @@ const PageCanvas = react.forwardRef(
|
|
|
10113
10431
|
selectElements(ids, false, false);
|
|
10114
10432
|
return;
|
|
10115
10433
|
}
|
|
10434
|
+
if (ids.length > 1 && !(active instanceof fabric__namespace.ActiveSelection && active.__pixldocsGroupSelection)) {
|
|
10435
|
+
const state = useEditorStore.getState();
|
|
10436
|
+
const currentPage2 = (_c = state.canvas.pages) == null ? void 0 : _c.find((p) => p.id === pageId);
|
|
10437
|
+
const children = (currentPage2 == null ? void 0 : currentPage2.children) ?? [];
|
|
10438
|
+
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
10439
|
+
const involvedGroupIds = /* @__PURE__ */ new Set();
|
|
10440
|
+
const standaloneIds = [];
|
|
10441
|
+
for (const id of ids) {
|
|
10442
|
+
const parent = walkToTopmostGroup(id, children, activeEditingGroupId);
|
|
10443
|
+
if (parent && activeEditingGroupId !== parent.id && !parent.backgroundColor) {
|
|
10444
|
+
involvedGroupIds.add(parent.id);
|
|
10445
|
+
} else {
|
|
10446
|
+
standaloneIds.push(id);
|
|
10447
|
+
}
|
|
10448
|
+
}
|
|
10449
|
+
if (involvedGroupIds.size > 0) {
|
|
10450
|
+
const wantIds = new Set(standaloneIds);
|
|
10451
|
+
const groupedMemberIds = /* @__PURE__ */ new Set();
|
|
10452
|
+
for (const gid of involvedGroupIds) {
|
|
10453
|
+
const g = findNodeById(children, gid);
|
|
10454
|
+
if (g && isGroup(g)) {
|
|
10455
|
+
for (const leafId of getAllElementIds(g.children ?? [])) {
|
|
10456
|
+
wantIds.add(leafId);
|
|
10457
|
+
groupedMemberIds.add(leafId);
|
|
10458
|
+
}
|
|
10459
|
+
}
|
|
10460
|
+
}
|
|
10461
|
+
const currentSet = new Set(ids);
|
|
10462
|
+
const needsExpand = wantIds.size !== currentSet.size || [...wantIds].some((id) => !currentSet.has(id));
|
|
10463
|
+
if (needsExpand) {
|
|
10464
|
+
const wantObjs = fabricCanvas.getObjects().filter((o) => {
|
|
10465
|
+
const oid = getObjectId(o);
|
|
10466
|
+
return !!oid && wantIds.has(oid);
|
|
10467
|
+
});
|
|
10468
|
+
if (wantObjs.length >= 2) {
|
|
10469
|
+
isSyncingSelectionToFabricRef.current = true;
|
|
10470
|
+
try {
|
|
10471
|
+
const sel = new fabric__namespace.ActiveSelection(wantObjs, { canvas: fabricCanvas });
|
|
10472
|
+
if (involvedGroupIds.size === 1 && standaloneIds.length === 0) {
|
|
10473
|
+
restoreGroupSelectionVisualState(sel, [...involvedGroupIds][0]);
|
|
10474
|
+
} else {
|
|
10475
|
+
markMixedLogicalSelection(sel, [...involvedGroupIds], groupedMemberIds);
|
|
10476
|
+
}
|
|
10477
|
+
fabricCanvas.setActiveObject(sel);
|
|
10478
|
+
fabricCanvas.requestRenderAll();
|
|
10479
|
+
} finally {
|
|
10480
|
+
isSyncingSelectionToFabricRef.current = false;
|
|
10481
|
+
}
|
|
10482
|
+
}
|
|
10483
|
+
} else {
|
|
10484
|
+
const currentActive = fabricCanvas.getActiveObject();
|
|
10485
|
+
if (currentActive instanceof fabric__namespace.ActiveSelection) {
|
|
10486
|
+
if (involvedGroupIds.size === 1 && standaloneIds.length === 0) {
|
|
10487
|
+
restoreGroupSelectionVisualState(currentActive, [...involvedGroupIds][0]);
|
|
10488
|
+
} else {
|
|
10489
|
+
markMixedLogicalSelection(currentActive, [...involvedGroupIds], groupedMemberIds);
|
|
10490
|
+
}
|
|
10491
|
+
currentActive.setCoords();
|
|
10492
|
+
fabricCanvas.requestRenderAll();
|
|
10493
|
+
}
|
|
10494
|
+
}
|
|
10495
|
+
const storeIds = [...involvedGroupIds, ...standaloneIds];
|
|
10496
|
+
selectElements(storeIds, false, false);
|
|
10497
|
+
return;
|
|
10498
|
+
}
|
|
10499
|
+
}
|
|
10116
10500
|
if (ids.length > 1) {
|
|
10117
10501
|
const state = useEditorStore.getState();
|
|
10118
|
-
const currentPage2 = (
|
|
10502
|
+
const currentPage2 = (_d = state.canvas.pages) == null ? void 0 : _d.find((p) => p.id === pageId);
|
|
10119
10503
|
const children = (currentPage2 == null ? void 0 : currentPage2.children) ?? [];
|
|
10120
10504
|
const currentSelectedIds = state.canvas.selectedIds ?? [];
|
|
10121
10505
|
for (const sid of currentSelectedIds) {
|
|
@@ -10143,6 +10527,20 @@ const PageCanvas = react.forwardRef(
|
|
|
10143
10527
|
} else {
|
|
10144
10528
|
m.hasBorders = true;
|
|
10145
10529
|
}
|
|
10530
|
+
const origControls = m.__pixldocsOrigHasControls;
|
|
10531
|
+
if (origControls !== void 0) {
|
|
10532
|
+
m.hasControls = origControls;
|
|
10533
|
+
delete m.__pixldocsOrigHasControls;
|
|
10534
|
+
} else {
|
|
10535
|
+
m.hasControls = true;
|
|
10536
|
+
}
|
|
10537
|
+
const origLockX = m.__pixldocsOrigLockScalingX;
|
|
10538
|
+
if (origLockX !== void 0) {
|
|
10539
|
+
m.lockScalingX = origLockX;
|
|
10540
|
+
m.lockScalingY = m.__pixldocsOrigLockScalingY;
|
|
10541
|
+
delete m.__pixldocsOrigLockScalingX;
|
|
10542
|
+
delete m.__pixldocsOrigLockScalingY;
|
|
10543
|
+
}
|
|
10146
10544
|
}
|
|
10147
10545
|
suppressGroupMemberBordersRef.current = [];
|
|
10148
10546
|
};
|
|
@@ -10150,6 +10548,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10150
10548
|
var _a2;
|
|
10151
10549
|
syncSelectionToStore();
|
|
10152
10550
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10551
|
+
if (activeObj instanceof fabric__namespace.ActiveSelection) applyWarpAwareSelectionBorders(activeObj);
|
|
10153
10552
|
if (activeObj) applyControlSizeForZoom(fabricCanvas, activeObj);
|
|
10154
10553
|
if (activeObj && !(activeObj instanceof fabric__namespace.ActiveSelection) && (((_a2 = activeObj._ct) == null ? void 0 : _a2.isCropGroup) || activeObj.__cropGroup)) {
|
|
10155
10554
|
installCanvaMaskControls(activeObj);
|
|
@@ -10158,10 +10557,11 @@ const PageCanvas = react.forwardRef(
|
|
|
10158
10557
|
fabricCanvas.on("selection:updated", () => {
|
|
10159
10558
|
var _a2;
|
|
10160
10559
|
const next = fabricCanvas.getActiveObject();
|
|
10161
|
-
const
|
|
10162
|
-
if (!
|
|
10560
|
+
const isLogicalGroupSel = next instanceof fabric__namespace.ActiveSelection && (next.__pixldocsGroupSelection || Array.isArray(next.__pixldocsLogicalGroupIds));
|
|
10561
|
+
if (!isLogicalGroupSel) restoreSuppressedGroupBorders();
|
|
10163
10562
|
syncSelectionToStore();
|
|
10164
10563
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10564
|
+
if (activeObj instanceof fabric__namespace.ActiveSelection) applyWarpAwareSelectionBorders(activeObj);
|
|
10165
10565
|
if (activeObj) applyControlSizeForZoom(fabricCanvas, activeObj);
|
|
10166
10566
|
if (activeObj && !(activeObj instanceof fabric__namespace.ActiveSelection) && (((_a2 = activeObj._ct) == null ? void 0 : _a2.isCropGroup) || activeObj.__cropGroup)) {
|
|
10167
10567
|
installCanvaMaskControls(activeObj);
|
|
@@ -10194,24 +10594,83 @@ const PageCanvas = react.forwardRef(
|
|
|
10194
10594
|
const stateNow = useEditorStore.getState();
|
|
10195
10595
|
const pageNow = (_b = stateNow.canvas.pages) == null ? void 0 : _b.find((p) => p.id === pageId);
|
|
10196
10596
|
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
10197
|
-
const
|
|
10198
|
-
|
|
10199
|
-
|
|
10597
|
+
const chain = [];
|
|
10598
|
+
{
|
|
10599
|
+
let currId = childId;
|
|
10600
|
+
for (let i = 0; i < 32; i++) {
|
|
10601
|
+
const p = findParentGroup(childrenNow, currId);
|
|
10602
|
+
if (!p) break;
|
|
10603
|
+
if (p.backgroundColor) break;
|
|
10604
|
+
chain.push(p);
|
|
10605
|
+
currId = p.id;
|
|
10606
|
+
}
|
|
10607
|
+
}
|
|
10608
|
+
if (chain.length === 0) return;
|
|
10609
|
+
const currentScopeId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
10610
|
+
let scopeIdx = chain.length;
|
|
10611
|
+
if (currentScopeId) {
|
|
10612
|
+
const idx = chain.findIndex((g) => g.id === currentScopeId);
|
|
10613
|
+
if (idx >= 0) scopeIdx = idx;
|
|
10614
|
+
}
|
|
10615
|
+
const entryIdx = scopeIdx - 1;
|
|
10616
|
+
if (entryIdx < 0) return;
|
|
10617
|
+
const newScopeGroup = chain[entryIdx];
|
|
10618
|
+
const selectionIdx = entryIdx - 1;
|
|
10619
|
+
const selectInnerObject = (obj) => {
|
|
10620
|
+
delete obj.__pixldocsGroupSelection;
|
|
10621
|
+
delete obj.__pixldocsLogicalGroupIds;
|
|
10622
|
+
obj.set({ selectable: true, evented: true, hasBorders: true, hasControls: true });
|
|
10623
|
+
fabricCanvas.setActiveObject(obj);
|
|
10624
|
+
obj.setCoords();
|
|
10625
|
+
};
|
|
10626
|
+
pendingGroupPromotionRef.current = null;
|
|
10200
10627
|
isSyncingSelectionToFabricRef.current = true;
|
|
10201
10628
|
try {
|
|
10629
|
+
skipSelectionClearOnDiscardRef.current = true;
|
|
10630
|
+
preserveEditingScopeOnSelectionClearRef.current = true;
|
|
10202
10631
|
fabricCanvas.discardActiveObject();
|
|
10203
|
-
|
|
10204
|
-
|
|
10632
|
+
skipSelectionClearOnDiscardRef.current = false;
|
|
10633
|
+
preserveEditingScopeOnSelectionClearRef.current = false;
|
|
10634
|
+
restoreSuppressedGroupBorders();
|
|
10635
|
+
fabricCanvas.__activeEditingGroupId = newScopeGroup.id;
|
|
10636
|
+
if (selectionIdx < 0) {
|
|
10637
|
+
selectInnerObject(hitChild);
|
|
10638
|
+
fabricCanvas.requestRenderAll();
|
|
10639
|
+
} else {
|
|
10640
|
+
const subgroup = chain[selectionIdx];
|
|
10641
|
+
const memberIds = new Set(getAllElementIds(subgroup.children ?? []));
|
|
10642
|
+
const memberObjs = fabricCanvas.getObjects().filter((o) => {
|
|
10643
|
+
const oid = getObjectId(o);
|
|
10644
|
+
return !!oid && memberIds.has(oid);
|
|
10645
|
+
});
|
|
10646
|
+
if (memberObjs.length > 1) {
|
|
10647
|
+
const selection = new fabric__namespace.ActiveSelection(memberObjs, { canvas: fabricCanvas });
|
|
10648
|
+
restoreGroupSelectionVisualState(selection, subgroup.id);
|
|
10649
|
+
fabricCanvas.setActiveObject(selection);
|
|
10650
|
+
selection.setCoords();
|
|
10651
|
+
} else if (memberObjs.length === 1) {
|
|
10652
|
+
const only = memberObjs[0];
|
|
10653
|
+
selectInnerObject(only);
|
|
10654
|
+
} else {
|
|
10655
|
+
selectInnerObject(hitChild);
|
|
10656
|
+
}
|
|
10657
|
+
fabricCanvas.requestRenderAll();
|
|
10658
|
+
}
|
|
10205
10659
|
} finally {
|
|
10660
|
+
skipSelectionClearOnDiscardRef.current = false;
|
|
10661
|
+
preserveEditingScopeOnSelectionClearRef.current = false;
|
|
10206
10662
|
isSyncingSelectionToFabricRef.current = false;
|
|
10207
10663
|
}
|
|
10208
|
-
|
|
10664
|
+
const selectedId = selectionIdx < 0 ? childId : chain[selectionIdx].id;
|
|
10665
|
+
selectElements([selectedId], false, false);
|
|
10209
10666
|
});
|
|
10210
10667
|
fabricCanvas.on("selection:cleared", () => {
|
|
10211
10668
|
if (!isActiveRef.current || isRebuildingRef.current || !allowSelection) return;
|
|
10212
10669
|
setGroupOverlayLiveBoundsRef.current(null);
|
|
10213
10670
|
groupBoundsResizingRef.current = false;
|
|
10214
|
-
|
|
10671
|
+
if (!preserveEditingScopeOnSelectionClearRef.current) {
|
|
10672
|
+
fabricCanvas.__activeEditingGroupId = null;
|
|
10673
|
+
}
|
|
10215
10674
|
const preservedGroupSelection = preserveActiveSelectionAfterTransformRef.current;
|
|
10216
10675
|
const shouldRestoreGroupSelection = !!((preservedGroupSelection == null ? void 0 : preservedGroupSelection.groupSelectionId) && (!preservedGroupSelection.expiresAt || preservedGroupSelection.expiresAt > Date.now()));
|
|
10217
10676
|
if (skipSelectionClearOnDiscardRef.current) {
|
|
@@ -10263,6 +10722,14 @@ const PageCanvas = react.forwardRef(
|
|
|
10263
10722
|
var _a2, _b;
|
|
10264
10723
|
const active = target instanceof fabric__namespace.ActiveSelection ? target : fabricCanvas.getActiveObject();
|
|
10265
10724
|
if (!(active instanceof fabric__namespace.ActiveSelection)) return;
|
|
10725
|
+
if (!activeSelectionMoveStartRef.current || activeSelectionMoveStartRef.current.selection !== active) {
|
|
10726
|
+
const rect2 = active.getBoundingRect();
|
|
10727
|
+
activeSelectionMoveStartRef.current = {
|
|
10728
|
+
selection: active,
|
|
10729
|
+
selectionLeft: rect2.left,
|
|
10730
|
+
selectionTop: rect2.top
|
|
10731
|
+
};
|
|
10732
|
+
}
|
|
10266
10733
|
const groupId = active.__pixldocsGroupSelection;
|
|
10267
10734
|
if (!groupId) return;
|
|
10268
10735
|
if (((_a2 = groupSelectionTransformStartRef.current) == null ? void 0 : _a2.groupId) === groupId && groupSelectionTransformStartRef.current.selection === active) return;
|
|
@@ -10281,16 +10748,123 @@ const PageCanvas = react.forwardRef(
|
|
|
10281
10748
|
};
|
|
10282
10749
|
};
|
|
10283
10750
|
const restoreGroupSelectionVisualState = (selection, groupId) => {
|
|
10284
|
-
selection
|
|
10285
|
-
|
|
10751
|
+
applyLogicalGroupSelectionVisualState(selection, groupId);
|
|
10752
|
+
};
|
|
10753
|
+
const suppressBordersForObjects = (members) => {
|
|
10754
|
+
var _a2;
|
|
10755
|
+
for (const prev of suppressGroupMemberBordersRef.current) {
|
|
10756
|
+
if (members.includes(prev)) continue;
|
|
10757
|
+
const orig = prev.__pixldocsOrigHasBorders;
|
|
10758
|
+
if (orig !== void 0) {
|
|
10759
|
+
prev.hasBorders = orig;
|
|
10760
|
+
delete prev.__pixldocsOrigHasBorders;
|
|
10761
|
+
} else {
|
|
10762
|
+
prev.hasBorders = true;
|
|
10763
|
+
}
|
|
10764
|
+
const origControls = prev.__pixldocsOrigHasControls;
|
|
10765
|
+
if (origControls !== void 0) {
|
|
10766
|
+
prev.hasControls = origControls;
|
|
10767
|
+
delete prev.__pixldocsOrigHasControls;
|
|
10768
|
+
} else {
|
|
10769
|
+
prev.hasControls = true;
|
|
10770
|
+
}
|
|
10771
|
+
const origLockX = prev.__pixldocsOrigLockScalingX;
|
|
10772
|
+
if (origLockX !== void 0) {
|
|
10773
|
+
prev.lockScalingX = origLockX;
|
|
10774
|
+
prev.lockScalingY = prev.__pixldocsOrigLockScalingY;
|
|
10775
|
+
delete prev.__pixldocsOrigLockScalingX;
|
|
10776
|
+
delete prev.__pixldocsOrigLockScalingY;
|
|
10777
|
+
}
|
|
10778
|
+
}
|
|
10286
10779
|
suppressGroupMemberBordersRef.current = members;
|
|
10287
10780
|
for (const m of members) {
|
|
10288
10781
|
if (m.__pixldocsOrigHasBorders === void 0) {
|
|
10289
10782
|
m.__pixldocsOrigHasBorders = m.hasBorders;
|
|
10290
10783
|
}
|
|
10784
|
+
if (m.__pixldocsOrigHasControls === void 0) {
|
|
10785
|
+
m.__pixldocsOrigHasControls = m.hasControls;
|
|
10786
|
+
}
|
|
10291
10787
|
m.hasBorders = false;
|
|
10788
|
+
m.hasControls = false;
|
|
10789
|
+
if (m.__cropGroup || ((_a2 = m._ct) == null ? void 0 : _a2.isCropGroup)) {
|
|
10790
|
+
if (m.__pixldocsOrigLockScalingX === void 0) {
|
|
10791
|
+
m.__pixldocsOrigLockScalingX = m.lockScalingX;
|
|
10792
|
+
m.__pixldocsOrigLockScalingY = m.lockScalingY;
|
|
10793
|
+
}
|
|
10794
|
+
m.lockScalingX = false;
|
|
10795
|
+
m.lockScalingY = false;
|
|
10796
|
+
}
|
|
10292
10797
|
}
|
|
10293
10798
|
};
|
|
10799
|
+
const isMultiSelectModifier = (event) => !!((event == null ? void 0 : event.shiftKey) || (event == null ? void 0 : event.metaKey) || (event == null ? void 0 : event.ctrlKey));
|
|
10800
|
+
const pickSelectableObjectAtPointer = (event) => {
|
|
10801
|
+
var _a2;
|
|
10802
|
+
try {
|
|
10803
|
+
const pointer = fabricCanvas.getViewportPoint(event);
|
|
10804
|
+
const objects = fabricCanvas.getObjects();
|
|
10805
|
+
for (let i = objects.length - 1; i >= 0; i--) {
|
|
10806
|
+
const obj = objects[i];
|
|
10807
|
+
const id = getObjectId(obj);
|
|
10808
|
+
if (!id || id === "__background__" || !obj.selectable || !obj.evented || obj.visible === false) continue;
|
|
10809
|
+
const controlHit = (_a2 = obj.findControl) == null ? void 0 : _a2.call(obj, pointer);
|
|
10810
|
+
if (controlHit) continue;
|
|
10811
|
+
if (typeof obj.containsPoint === "function" && obj.containsPoint(pointer)) return obj;
|
|
10812
|
+
}
|
|
10813
|
+
} catch {
|
|
10814
|
+
return null;
|
|
10815
|
+
}
|
|
10816
|
+
return null;
|
|
10817
|
+
};
|
|
10818
|
+
let pendingShiftMultiSelect = null;
|
|
10819
|
+
const applyShiftMultiSelect = (target, event, baselineActive = fabricCanvas.getActiveObject(), baselineObjects = fabricCanvas.getActiveObjects()) => {
|
|
10820
|
+
var _a2, _b, _c;
|
|
10821
|
+
if (!target || !target.selectable) return false;
|
|
10822
|
+
const active = baselineActive;
|
|
10823
|
+
if (!active || ((_a2 = active.getActiveControl) == null ? void 0 : _a2.call(active))) return false;
|
|
10824
|
+
if (active === target && !(active instanceof fabric__namespace.ActiveSelection)) return false;
|
|
10825
|
+
isSyncingSelectionToFabricRef.current = true;
|
|
10826
|
+
try {
|
|
10827
|
+
let nextObjects;
|
|
10828
|
+
if (active instanceof fabric__namespace.ActiveSelection) {
|
|
10829
|
+
const current = baselineObjects.length ? baselineObjects : active.getObjects();
|
|
10830
|
+
nextObjects = current.includes(target) ? current.filter((obj) => obj !== target) : [...current, target];
|
|
10831
|
+
} else {
|
|
10832
|
+
nextObjects = [active, target];
|
|
10833
|
+
}
|
|
10834
|
+
nextObjects = nextObjects.filter((obj, index, arr) => arr.indexOf(obj) === index && fabricCanvas.getObjects().includes(obj));
|
|
10835
|
+
if (nextObjects.length > 1) {
|
|
10836
|
+
const selection = new fabric__namespace.ActiveSelection(nextObjects, { canvas: fabricCanvas });
|
|
10837
|
+
applyWarpAwareSelectionBorders(selection);
|
|
10838
|
+
fabricCanvas.setActiveObject(selection);
|
|
10839
|
+
selection.setCoords();
|
|
10840
|
+
isSyncingSelectionToFabricRef.current = false;
|
|
10841
|
+
syncSelectionToStore();
|
|
10842
|
+
} else if (nextObjects.length === 1) {
|
|
10843
|
+
fabricCanvas.setActiveObject(nextObjects[0]);
|
|
10844
|
+
nextObjects[0].setCoords();
|
|
10845
|
+
const onlyId = getObjectId(nextObjects[0]);
|
|
10846
|
+
if (onlyId) selectElements([onlyId], false, false);
|
|
10847
|
+
}
|
|
10848
|
+
fabricCanvas.requestRenderAll();
|
|
10849
|
+
} finally {
|
|
10850
|
+
requestAnimationFrame(() => {
|
|
10851
|
+
isSyncingSelectionToFabricRef.current = false;
|
|
10852
|
+
});
|
|
10853
|
+
}
|
|
10854
|
+
(_b = event == null ? void 0 : event.preventDefault) == null ? void 0 : _b.call(event);
|
|
10855
|
+
(_c = event == null ? void 0 : event.stopPropagation) == null ? void 0 : _c.call(event);
|
|
10856
|
+
return true;
|
|
10857
|
+
};
|
|
10858
|
+
const markMixedLogicalSelection = (selection, groupIds, groupMemberIds) => {
|
|
10859
|
+
delete selection.__pixldocsGroupSelection;
|
|
10860
|
+
selection.__pixldocsLogicalGroupIds = groupIds;
|
|
10861
|
+
selection.hasBorders = true;
|
|
10862
|
+
const memberObjects = selection.getObjects().filter((obj) => {
|
|
10863
|
+
const id = getObjectId(obj);
|
|
10864
|
+
return !!id && groupMemberIds.has(id);
|
|
10865
|
+
});
|
|
10866
|
+
suppressBordersForObjects(memberObjects);
|
|
10867
|
+
};
|
|
10294
10868
|
const restorePreservedGroupSelectionSoon = (snapshot = preserveActiveSelectionAfterTransformRef.current) => {
|
|
10295
10869
|
if (!(snapshot == null ? void 0 : snapshot.groupSelectionId) || snapshot.memberIds.length < 2) return;
|
|
10296
10870
|
const groupId = snapshot.groupSelectionId;
|
|
@@ -10328,7 +10902,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10328
10902
|
return !!(((_a2 = o == null ? void 0 : o._ct) == null ? void 0 : _a2.isCropGroup) || (o == null ? void 0 : o.__cropGroup));
|
|
10329
10903
|
};
|
|
10330
10904
|
const promoteToCropGroup = (opt) => {
|
|
10331
|
-
var _a2, _b, _c;
|
|
10905
|
+
var _a2, _b, _c, _d, _e, _f;
|
|
10332
10906
|
const t = opt.target;
|
|
10333
10907
|
if (((_a2 = opt.e) == null ? void 0 : _a2.type) !== "mousedown" && ((_b = opt.e) == null ? void 0 : _b.type) !== "pointerdown" && ((_c = opt.e) == null ? void 0 : _c.type) !== "touchstart") {
|
|
10334
10908
|
if (t && isCropGroup2(t)) {
|
|
@@ -10338,6 +10912,9 @@ const PageCanvas = react.forwardRef(
|
|
|
10338
10912
|
}
|
|
10339
10913
|
return;
|
|
10340
10914
|
}
|
|
10915
|
+
if (((_d = opt.e) == null ? void 0 : _d.shiftKey) || ((_e = opt.e) == null ? void 0 : _e.metaKey) || ((_f = opt.e) == null ? void 0 : _f.ctrlKey)) {
|
|
10916
|
+
return;
|
|
10917
|
+
}
|
|
10341
10918
|
if (!t) {
|
|
10342
10919
|
const pointer = fabricCanvas.getPointer(opt.e);
|
|
10343
10920
|
const objects = fabricCanvas.getObjects();
|
|
@@ -10412,6 +10989,12 @@ const PageCanvas = react.forwardRef(
|
|
|
10412
10989
|
}
|
|
10413
10990
|
fabricCanvas.on("mouse:down", (opt) => {
|
|
10414
10991
|
var _a2, _b;
|
|
10992
|
+
if (pendingShiftMultiSelect) {
|
|
10993
|
+
const pending = pendingShiftMultiSelect;
|
|
10994
|
+
pendingShiftMultiSelect = null;
|
|
10995
|
+
applyShiftMultiSelect(pending.target, opt.e, pending.active, pending.activeObjects);
|
|
10996
|
+
return;
|
|
10997
|
+
}
|
|
10415
10998
|
const target = opt.target;
|
|
10416
10999
|
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) && (((_b = target.group._ct) == null ? void 0 : _b.isCropGroup) || target.group.__cropGroup) ? target.group : null;
|
|
10417
11000
|
if (cropGroup) {
|
|
@@ -10422,8 +11005,42 @@ const PageCanvas = react.forwardRef(
|
|
|
10422
11005
|
fabricCanvas.requestRenderAll();
|
|
10423
11006
|
}
|
|
10424
11007
|
});
|
|
11008
|
+
const groupFabricUnionBBox = (g) => {
|
|
11009
|
+
var _a2, _b;
|
|
11010
|
+
const memberIds = new Set(getAllElementIds(g.children ?? []));
|
|
11011
|
+
if (memberIds.size === 0) return null;
|
|
11012
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
11013
|
+
let found = false;
|
|
11014
|
+
for (const o of fabricCanvas.getObjects()) {
|
|
11015
|
+
const oid = getObjectId(o);
|
|
11016
|
+
if (!oid || !memberIds.has(oid)) continue;
|
|
11017
|
+
const br = ((_a2 = o.getBoundingRect) == null ? void 0 : _a2.call(o, true, true)) ?? ((_b = o.getBoundingRect) == null ? void 0 : _b.call(o));
|
|
11018
|
+
if (!br) continue;
|
|
11019
|
+
minX = Math.min(minX, br.left);
|
|
11020
|
+
minY = Math.min(minY, br.top);
|
|
11021
|
+
maxX = Math.max(maxX, br.left + br.width);
|
|
11022
|
+
maxY = Math.max(maxY, br.top + br.height);
|
|
11023
|
+
found = true;
|
|
11024
|
+
}
|
|
11025
|
+
if (!found) return null;
|
|
11026
|
+
return { left: minX, top: minY, right: maxX, bottom: maxY };
|
|
11027
|
+
};
|
|
11028
|
+
const pickGroupAtPointer = (px, py, children, activeEditingGroupId) => {
|
|
11029
|
+
let pick = null;
|
|
11030
|
+
for (const node of children) {
|
|
11031
|
+
if (!isGroup(node)) continue;
|
|
11032
|
+
if (node.backgroundColor) continue;
|
|
11033
|
+
if (activeEditingGroupId && node.id === activeEditingGroupId) continue;
|
|
11034
|
+
const b = groupFabricUnionBBox(node);
|
|
11035
|
+
if (!b) continue;
|
|
11036
|
+
if (px < b.left || py < b.top || px > b.right || py > b.bottom) continue;
|
|
11037
|
+
const area = Math.max(1, (b.right - b.left) * (b.bottom - b.top));
|
|
11038
|
+
if (!pick || area < pick.area) pick = { group: node, area };
|
|
11039
|
+
}
|
|
11040
|
+
return pick;
|
|
11041
|
+
};
|
|
10425
11042
|
fabricCanvas.on("mouse:down:before", (opt) => {
|
|
10426
|
-
var _a2, _b, _c, _d, _e;
|
|
11043
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
10427
11044
|
if (editLockRef.current) {
|
|
10428
11045
|
const active = fabricCanvas.getActiveObject();
|
|
10429
11046
|
if (active && (((_a2 = active._ct) == null ? void 0 : _a2.isCropGroup) || active.__cropGroup)) {
|
|
@@ -10439,13 +11056,154 @@ const PageCanvas = react.forwardRef(
|
|
|
10439
11056
|
syncLockedRef.current = true;
|
|
10440
11057
|
lockEdits();
|
|
10441
11058
|
}
|
|
11059
|
+
const target = opt.target;
|
|
11060
|
+
const targetId = target ? getObjectId(target) : null;
|
|
11061
|
+
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
11062
|
+
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
11063
|
+
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
11064
|
+
if (isMultiSelectModifier(opt.e)) {
|
|
11065
|
+
const manualTarget = target && !(target instanceof fabric__namespace.ActiveSelection) && targetId && targetId !== "__background__" ? target : pickSelectableObjectAtPointer(opt.e);
|
|
11066
|
+
if (manualTarget) {
|
|
11067
|
+
pendingShiftMultiSelect = {
|
|
11068
|
+
target: manualTarget,
|
|
11069
|
+
active: fabricCanvas.getActiveObject(),
|
|
11070
|
+
activeObjects: fabricCanvas.getActiveObjects().slice()
|
|
11071
|
+
};
|
|
11072
|
+
pendingGroupPromotionRef.current = null;
|
|
11073
|
+
return;
|
|
11074
|
+
}
|
|
11075
|
+
}
|
|
11076
|
+
const findTopmostPromotableGroup = (childId) => {
|
|
11077
|
+
let topmost = null;
|
|
11078
|
+
let currentId = childId;
|
|
11079
|
+
for (let i = 0; i < 32; i++) {
|
|
11080
|
+
const p = findParentGroup(childrenNow, currentId);
|
|
11081
|
+
if (!p) break;
|
|
11082
|
+
if (p.backgroundColor) break;
|
|
11083
|
+
if (activeEditingGroupId && p.id === activeEditingGroupId) break;
|
|
11084
|
+
topmost = p;
|
|
11085
|
+
currentId = p.id;
|
|
11086
|
+
}
|
|
11087
|
+
return topmost;
|
|
11088
|
+
};
|
|
11089
|
+
if (target && targetId && targetId !== "__background__") {
|
|
11090
|
+
const parent = findTopmostPromotableGroup(targetId);
|
|
11091
|
+
const targetIsInCrop = !!(target instanceof fabric__namespace.Group && isCropGroupInCropMode(target) || (target == null ? void 0 : target.group) instanceof fabric__namespace.Group && isCropGroupInCropMode(target.group));
|
|
11092
|
+
const activeNow = fabricCanvas.getActiveObject();
|
|
11093
|
+
const alreadyThisGroup = activeNow instanceof fabric__namespace.ActiveSelection && activeNow.__pixldocsGroupSelection === (parent == null ? void 0 : parent.id);
|
|
11094
|
+
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));
|
|
11095
|
+
if (parent && !parent.backgroundColor && !targetIsInCrop && activeEditingGroupId !== parent.id && !alreadyThisGroup && !isMultiSelectKey) {
|
|
11096
|
+
const memberIds = new Set(getAllElementIds(parent.children ?? []));
|
|
11097
|
+
const memberObjs = fabricCanvas.getObjects().filter((o) => {
|
|
11098
|
+
const oid = getObjectId(o);
|
|
11099
|
+
return !!oid && memberIds.has(oid);
|
|
11100
|
+
});
|
|
11101
|
+
if (memberObjs.length > 1) {
|
|
11102
|
+
const selection = new fabric__namespace.ActiveSelection(memberObjs, { canvas: fabricCanvas });
|
|
11103
|
+
restoreGroupSelectionVisualState(selection, parent.id);
|
|
11104
|
+
fabricCanvas.setActiveObject(selection);
|
|
11105
|
+
selection.setCoords();
|
|
11106
|
+
fabricCanvas._target = selection;
|
|
11107
|
+
opt.target = selection;
|
|
11108
|
+
pendingGroupPromotionRef.current = { groupId: parent.id, selection };
|
|
11109
|
+
} else if (memberObjs.length === 1) {
|
|
11110
|
+
const only = memberObjs[0];
|
|
11111
|
+
only.__pixldocsGroupSelection = parent.id;
|
|
11112
|
+
fabricCanvas.setActiveObject(only);
|
|
11113
|
+
only.setCoords();
|
|
11114
|
+
fabricCanvas._target = only;
|
|
11115
|
+
opt.target = only;
|
|
11116
|
+
pendingGroupPromotionRef.current = { groupId: parent.id, selection: only };
|
|
11117
|
+
}
|
|
11118
|
+
}
|
|
11119
|
+
} else if (!target || targetId === "__background__") {
|
|
11120
|
+
const isMultiSelectKey = !!(((_i = opt.e) == null ? void 0 : _i.shiftKey) || ((_j = opt.e) == null ? void 0 : _j.metaKey) || ((_k = opt.e) == null ? void 0 : _k.ctrlKey));
|
|
11121
|
+
if (isMultiSelectKey) return;
|
|
11122
|
+
try {
|
|
11123
|
+
const pointer = fabricCanvas.getPointer(opt.e);
|
|
11124
|
+
const px = pointer.x;
|
|
11125
|
+
const py = pointer.y;
|
|
11126
|
+
const pick = pickGroupAtPointer(px, py, childrenNow, activeEditingGroupId);
|
|
11127
|
+
if (pick) {
|
|
11128
|
+
const parent = pick.group;
|
|
11129
|
+
if (activeEditingGroupId !== parent.id) {
|
|
11130
|
+
const memberIds = new Set(getAllElementIds(parent.children ?? []));
|
|
11131
|
+
const memberObjs = fabricCanvas.getObjects().filter((o) => {
|
|
11132
|
+
const oid = getObjectId(o);
|
|
11133
|
+
return !!oid && memberIds.has(oid);
|
|
11134
|
+
});
|
|
11135
|
+
if (memberObjs.length > 1) {
|
|
11136
|
+
const selection = new fabric__namespace.ActiveSelection(memberObjs, { canvas: fabricCanvas });
|
|
11137
|
+
restoreGroupSelectionVisualState(selection, parent.id);
|
|
11138
|
+
fabricCanvas.setActiveObject(selection);
|
|
11139
|
+
selection.setCoords();
|
|
11140
|
+
fabricCanvas._target = selection;
|
|
11141
|
+
opt.target = selection;
|
|
11142
|
+
pendingGroupPromotionRef.current = { groupId: parent.id, selection };
|
|
11143
|
+
} else if (memberObjs.length === 1) {
|
|
11144
|
+
const only = memberObjs[0];
|
|
11145
|
+
only.__pixldocsGroupSelection = parent.id;
|
|
11146
|
+
fabricCanvas.setActiveObject(only);
|
|
11147
|
+
fabricCanvas._target = only;
|
|
11148
|
+
opt.target = only;
|
|
11149
|
+
pendingGroupPromotionRef.current = { groupId: parent.id, selection: only };
|
|
11150
|
+
}
|
|
11151
|
+
}
|
|
11152
|
+
}
|
|
11153
|
+
} catch {
|
|
11154
|
+
}
|
|
11155
|
+
}
|
|
10442
11156
|
promoteToCropGroup(opt);
|
|
10443
11157
|
});
|
|
10444
11158
|
fabricCanvas.on("mouse:move:before", promoteToCropGroup);
|
|
11159
|
+
fabricCanvas.on("after:render", () => {
|
|
11160
|
+
var _a2;
|
|
11161
|
+
try {
|
|
11162
|
+
const active = fabricCanvas.getActiveObject();
|
|
11163
|
+
if (!(active instanceof fabric__namespace.ActiveSelection)) return;
|
|
11164
|
+
const logicalIds = active.__pixldocsLogicalGroupIds;
|
|
11165
|
+
if (!logicalIds || logicalIds.length < 1) return;
|
|
11166
|
+
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
11167
|
+
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
11168
|
+
const ctx = ((_a2 = fabricCanvas.getContext) == null ? void 0 : _a2.call(fabricCanvas)) ?? fabricCanvas.contextContainer;
|
|
11169
|
+
if (!ctx) return;
|
|
11170
|
+
const vt = fabricCanvas.viewportTransform;
|
|
11171
|
+
ctx.save();
|
|
11172
|
+
if (vt) ctx.transform(vt[0], vt[1], vt[2], vt[3], vt[4], vt[5]);
|
|
11173
|
+
ctx.strokeStyle = SELECTION_PRIMARY;
|
|
11174
|
+
ctx.lineWidth = 1.25 / ((vt == null ? void 0 : vt[0]) || 1);
|
|
11175
|
+
ctx.setLineDash([]);
|
|
11176
|
+
for (const gid of logicalIds) {
|
|
11177
|
+
const node = findNodeById(childrenNow, gid);
|
|
11178
|
+
if (!node || !isGroup(node)) continue;
|
|
11179
|
+
const b = groupFabricUnionBBox(node);
|
|
11180
|
+
if (!b) continue;
|
|
11181
|
+
ctx.strokeRect(b.left, b.top, b.right - b.left, b.bottom - b.top);
|
|
11182
|
+
}
|
|
11183
|
+
ctx.restore();
|
|
11184
|
+
} catch {
|
|
11185
|
+
}
|
|
11186
|
+
});
|
|
11187
|
+
fabricCanvas.on("mouse:move", (opt) => {
|
|
11188
|
+
if (fabricCanvas._currentTransform) return;
|
|
11189
|
+
if (editLockRef.current) return;
|
|
11190
|
+
const t = opt.target;
|
|
11191
|
+
const tid = t ? getObjectId(t) : null;
|
|
11192
|
+
if (t && tid && tid !== "__background__") return;
|
|
11193
|
+
try {
|
|
11194
|
+
const pointer = fabricCanvas.getPointer(opt.e);
|
|
11195
|
+
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
11196
|
+
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
11197
|
+
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
11198
|
+
const pick = pickGroupAtPointer(pointer.x, pointer.y, childrenNow, activeEditingGroupId);
|
|
11199
|
+
fabricCanvas.defaultCursor = pick ? "move" : "default";
|
|
11200
|
+
} catch {
|
|
11201
|
+
fabricCanvas.defaultCursor = "default";
|
|
11202
|
+
}
|
|
11203
|
+
});
|
|
10445
11204
|
fabricCanvas.on("mouse:down", (ev) => {
|
|
10446
11205
|
if (fabricCanvas._currentTransform) {
|
|
10447
11206
|
lockEdits();
|
|
10448
|
-
didTransformRef.current = true;
|
|
10449
11207
|
}
|
|
10450
11208
|
const o = fabricCanvas.getActiveObject();
|
|
10451
11209
|
pendingTextEditOnUpRef.current = null;
|
|
@@ -10459,6 +11217,38 @@ const PageCanvas = react.forwardRef(
|
|
|
10459
11217
|
setRotationLabel(null);
|
|
10460
11218
|
setSizeLabel(null);
|
|
10461
11219
|
dragStarted = false;
|
|
11220
|
+
const pendingPromotion = pendingGroupPromotionRef.current;
|
|
11221
|
+
pendingGroupPromotionRef.current = null;
|
|
11222
|
+
if (pendingPromotion && !didTransformRef.current) {
|
|
11223
|
+
const activeNow = fabricCanvas.getActiveObject();
|
|
11224
|
+
if (activeNow !== pendingPromotion.selection) {
|
|
11225
|
+
isSyncingSelectionToFabricRef.current = true;
|
|
11226
|
+
try {
|
|
11227
|
+
fabricCanvas.setActiveObject(pendingPromotion.selection);
|
|
11228
|
+
pendingPromotion.selection.setCoords();
|
|
11229
|
+
fabricCanvas.requestRenderAll();
|
|
11230
|
+
} finally {
|
|
11231
|
+
requestAnimationFrame(() => {
|
|
11232
|
+
isSyncingSelectionToFabricRef.current = false;
|
|
11233
|
+
});
|
|
11234
|
+
}
|
|
11235
|
+
selectElements([pendingPromotion.groupId], false, false);
|
|
11236
|
+
}
|
|
11237
|
+
try {
|
|
11238
|
+
const sel = pendingPromotion.selection;
|
|
11239
|
+
if (sel instanceof fabric__namespace.ActiveSelection) {
|
|
11240
|
+
restoreGroupSelectionVisualState(sel, pendingPromotion.groupId);
|
|
11241
|
+
sel.hasBorders = true;
|
|
11242
|
+
sel.setCoords();
|
|
11243
|
+
applyWarpAwareSelectionBorders(sel);
|
|
11244
|
+
} else {
|
|
11245
|
+
sel.__pixldocsGroupSelection = pendingPromotion.groupId;
|
|
11246
|
+
sel.setCoords();
|
|
11247
|
+
}
|
|
11248
|
+
fabricCanvas.requestRenderAll();
|
|
11249
|
+
} catch {
|
|
11250
|
+
}
|
|
11251
|
+
}
|
|
10462
11252
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10463
11253
|
if (activeObj && (activeObj.__cropGroup || ((_a2 = activeObj._ct) == null ? void 0 : _a2.isCropGroup))) {
|
|
10464
11254
|
activeObj.__lockScaleDuringCrop = false;
|
|
@@ -10500,6 +11290,34 @@ const PageCanvas = react.forwardRef(
|
|
|
10500
11290
|
if (!isActiveRef.current) return;
|
|
10501
11291
|
markTransforming(e.target);
|
|
10502
11292
|
};
|
|
11293
|
+
const getObjectFrameBoundsInSelection = (selection, obj, frameWidth, frameHeight) => {
|
|
11294
|
+
const w = Math.max(1, frameWidth ?? obj.width ?? 1);
|
|
11295
|
+
const h = Math.max(1, frameHeight ?? obj.height ?? 1);
|
|
11296
|
+
const originX = obj.originX ?? "left";
|
|
11297
|
+
const originY = obj.originY ?? "top";
|
|
11298
|
+
const localLeft = originX === "center" ? -w / 2 : originX === "right" ? -w : 0;
|
|
11299
|
+
const localTop = originY === "center" ? -h / 2 : originY === "bottom" ? -h : 0;
|
|
11300
|
+
const matrix = fabric__namespace.util.multiplyTransformMatrices(
|
|
11301
|
+
selection.calcTransformMatrix(),
|
|
11302
|
+
obj.calcOwnMatrix()
|
|
11303
|
+
);
|
|
11304
|
+
const points = [
|
|
11305
|
+
new fabric__namespace.Point(localLeft, localTop),
|
|
11306
|
+
new fabric__namespace.Point(localLeft + w, localTop),
|
|
11307
|
+
new fabric__namespace.Point(localLeft + w, localTop + h),
|
|
11308
|
+
new fabric__namespace.Point(localLeft, localTop + h)
|
|
11309
|
+
].map((point) => fabric__namespace.util.transformPoint(point, matrix));
|
|
11310
|
+
const xs = points.map((p) => p.x);
|
|
11311
|
+
const ys = points.map((p) => p.y);
|
|
11312
|
+
const left = Math.min(...xs);
|
|
11313
|
+
const top = Math.min(...ys);
|
|
11314
|
+
return {
|
|
11315
|
+
left,
|
|
11316
|
+
top,
|
|
11317
|
+
width: Math.max(1, Math.max(...xs) - left),
|
|
11318
|
+
height: Math.max(1, Math.max(...ys) - top)
|
|
11319
|
+
};
|
|
11320
|
+
};
|
|
10503
11321
|
fabricCanvas.on("object:added", (e) => {
|
|
10504
11322
|
var _a2;
|
|
10505
11323
|
const obj = e.target;
|
|
@@ -10619,11 +11437,18 @@ const PageCanvas = react.forwardRef(
|
|
|
10619
11437
|
}
|
|
10620
11438
|
if (obj instanceof fabric__namespace.Textbox) {
|
|
10621
11439
|
const sy = obj.scaleY ?? 1;
|
|
10622
|
-
|
|
11440
|
+
const sx = obj.scaleX ?? 1;
|
|
11441
|
+
const isUniformCornerScale = Math.abs(sx - sy) < 1e-3 && Math.abs(sx - 1) > 1e-3;
|
|
11442
|
+
if (isUniformCornerScale) {
|
|
11443
|
+
obj.setCoords();
|
|
11444
|
+
obj.dirty = true;
|
|
11445
|
+
} else if (Math.abs(sy - 1) > 1e-3) {
|
|
10623
11446
|
const center = obj.getCenterPoint();
|
|
10624
|
-
const
|
|
11447
|
+
const newVisualH = (obj.height ?? 0) * Math.abs(sy);
|
|
11448
|
+
const targetScaleY = Math.abs(sx - 1) > 1e-3 ? Math.abs(sx) : 1;
|
|
11449
|
+
const newMinH = Math.max(0, newVisualH / targetScaleY);
|
|
10625
11450
|
obj.minBoxHeight = newMinH;
|
|
10626
|
-
obj.scaleY =
|
|
11451
|
+
obj.scaleY = targetScaleY;
|
|
10627
11452
|
try {
|
|
10628
11453
|
obj.initDimensions();
|
|
10629
11454
|
} catch {
|
|
@@ -10745,7 +11570,7 @@ const PageCanvas = react.forwardRef(
|
|
|
10745
11570
|
});
|
|
10746
11571
|
let cropGroupSaveTimer = null;
|
|
10747
11572
|
fabricCanvas.on("object:modified", (e) => {
|
|
10748
|
-
var _a2, _b, _c, _d, _e, _f;
|
|
11573
|
+
var _a2, _b, _c, _d, _e, _f, _g;
|
|
10749
11574
|
try {
|
|
10750
11575
|
dragStarted = false;
|
|
10751
11576
|
setGuides([]);
|
|
@@ -10966,14 +11791,14 @@ const PageCanvas = react.forwardRef(
|
|
|
10966
11791
|
}
|
|
10967
11792
|
if (active && active instanceof fabric__namespace.Group && !(active instanceof fabric__namespace.ActiveSelection) && getObjectId(active)) {
|
|
10968
11793
|
const groupId = getObjectId(active);
|
|
10969
|
-
const
|
|
11794
|
+
const pageChildren3 = ((_e = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _e.children) ?? [];
|
|
10970
11795
|
const w = (active.width ?? 0) * (active.scaleX ?? 1);
|
|
10971
11796
|
const h = (active.height ?? 0) * (active.scaleY ?? 1);
|
|
10972
11797
|
const centerX = active.left ?? 0;
|
|
10973
11798
|
const centerY = active.top ?? 0;
|
|
10974
11799
|
const groupLeft = active.originX === "center" ? centerX - w / 2 : centerX;
|
|
10975
11800
|
const groupTop = active.originY === "center" ? centerY - h / 2 : centerY;
|
|
10976
|
-
const storePos = absoluteToStorePosition(groupLeft, groupTop, groupId,
|
|
11801
|
+
const storePos = absoluteToStorePosition(groupLeft, groupTop, groupId, pageChildren3);
|
|
10977
11802
|
useEditorStore.getState().updateNode(groupId, { left: storePos.left, top: storePos.top }, { recordHistory: false, skipLayoutRecalc: true });
|
|
10978
11803
|
commitHistory();
|
|
10979
11804
|
unlockEditsSoon();
|
|
@@ -10988,6 +11813,14 @@ const PageCanvas = react.forwardRef(
|
|
|
10988
11813
|
}
|
|
10989
11814
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10990
11815
|
let activeObjects = fabricCanvas.getActiveObjects();
|
|
11816
|
+
const activeSelectionMoveStart = activeObj instanceof fabric__namespace.ActiveSelection && ((_f = activeSelectionMoveStartRef.current) == null ? void 0 : _f.selection) === activeObj ? activeSelectionMoveStartRef.current : null;
|
|
11817
|
+
const activeSelectionDelta = activeObj instanceof fabric__namespace.ActiveSelection && activeSelectionMoveStart ? (() => {
|
|
11818
|
+
const rect = activeObj.getBoundingRect();
|
|
11819
|
+
return {
|
|
11820
|
+
x: rect.left - activeSelectionMoveStart.selectionLeft,
|
|
11821
|
+
y: rect.top - activeSelectionMoveStart.selectionTop
|
|
11822
|
+
};
|
|
11823
|
+
})() : null;
|
|
10991
11824
|
if (activeObjects.length === 0 && modifiedTarget && getObjectId(modifiedTarget)) {
|
|
10992
11825
|
activeObjects = [modifiedTarget];
|
|
10993
11826
|
}
|
|
@@ -11009,8 +11842,53 @@ const PageCanvas = react.forwardRef(
|
|
|
11009
11842
|
const currentPage2 = getCurrentPageStore();
|
|
11010
11843
|
const selectedElementIds = activeObjects.map((obj) => getObjectId(obj)).filter((id) => !!id && id !== "__background__");
|
|
11011
11844
|
const anyCropGroup = activeObjects.some((o) => o.__cropGroup);
|
|
11845
|
+
const pageChildren2 = currentPage2.children ?? [];
|
|
11846
|
+
const selectedLogicalGroupIds = (useEditorStore.getState().canvas.selectedIds ?? []).filter((id) => {
|
|
11847
|
+
const node = findNodeById(pageChildren2, id);
|
|
11848
|
+
return !!(node && isGroup(node));
|
|
11849
|
+
});
|
|
11850
|
+
const activeSelectionHadTransform = activeObj instanceof fabric__namespace.ActiveSelection && (Math.abs((activeObj.scaleX ?? 1) - 1) > 0.01 || Math.abs((activeObj.scaleY ?? 1) - 1) > 0.01 || Math.abs((activeObj.angle ?? 0) % 360) > 0.01);
|
|
11851
|
+
if (!anyCropGroup && activeSelectionDelta && !activeSelectionHadTransform && selectedLogicalGroupIds.length > 0) {
|
|
11852
|
+
const selectedStoreIds = useEditorStore.getState().canvas.selectedIds ?? [];
|
|
11853
|
+
const groupMemberIds = /* @__PURE__ */ new Set();
|
|
11854
|
+
selectedLogicalGroupIds.forEach((gid) => {
|
|
11855
|
+
const groupNode = findNodeById(pageChildren2, gid);
|
|
11856
|
+
if (groupNode && isGroup(groupNode)) {
|
|
11857
|
+
getAllElementIds(groupNode.children ?? []).forEach((id) => groupMemberIds.add(id));
|
|
11858
|
+
}
|
|
11859
|
+
});
|
|
11860
|
+
const logicalStandaloneIds = selectedStoreIds.filter((id) => {
|
|
11861
|
+
if (selectedLogicalGroupIds.includes(id)) return false;
|
|
11862
|
+
if (groupMemberIds.has(id)) return false;
|
|
11863
|
+
return !!findNodeById(pageChildren2, id);
|
|
11864
|
+
});
|
|
11865
|
+
if (logicalStandaloneIds.length > 0) {
|
|
11866
|
+
const { updateNode: updateNodeStore, commitHistory: commitHistoryStore } = useEditorStore.getState();
|
|
11867
|
+
[...selectedLogicalGroupIds, ...logicalStandaloneIds].forEach((id) => {
|
|
11868
|
+
const node = findNodeById(pageChildren2, id);
|
|
11869
|
+
if (!node) return;
|
|
11870
|
+
const abs = getAbsoluteBounds(node, pageChildren2, pageBoundsOptions);
|
|
11871
|
+
const nextAbsLeft = abs.left + activeSelectionDelta.x;
|
|
11872
|
+
const nextAbsTop = abs.top + activeSelectionDelta.y;
|
|
11873
|
+
const storePos = absoluteToStorePosition(nextAbsLeft, nextAbsTop, id, pageChildren2);
|
|
11874
|
+
updateNodeStore(id, { left: storePos.left, top: storePos.top }, { recordHistory: false, skipLayoutRecalc: true });
|
|
11875
|
+
});
|
|
11876
|
+
commitHistoryStore();
|
|
11877
|
+
activeObjects.forEach((obj) => {
|
|
11878
|
+
const objId = getObjectId(obj);
|
|
11879
|
+
if (objId && objId !== "__background__") {
|
|
11880
|
+
justModifiedIdsRef.current.add(objId);
|
|
11881
|
+
modifiedIdsThisRound.add(objId);
|
|
11882
|
+
}
|
|
11883
|
+
});
|
|
11884
|
+
setTimeout(() => modifiedIdsThisRound.forEach((id) => justModifiedIdsRef.current.delete(id)), 150);
|
|
11885
|
+
activeSelectionMoveStartRef.current = null;
|
|
11886
|
+
groupSelectionTransformStartRef.current = null;
|
|
11887
|
+
unlockEditsSoon();
|
|
11888
|
+
return;
|
|
11889
|
+
}
|
|
11890
|
+
}
|
|
11012
11891
|
if (selectedElementIds.length > 0 && !anyCropGroup) {
|
|
11013
|
-
const pageChildren2 = currentPage2.children ?? [];
|
|
11014
11892
|
const firstObj = activeObjects[0];
|
|
11015
11893
|
const firstId = getObjectId(firstObj);
|
|
11016
11894
|
const parentGroups = selectedElementIds.map((id) => findParentGroup(pageChildren2, id)).filter((g) => g !== null);
|
|
@@ -11105,6 +11983,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11105
11983
|
}
|
|
11106
11984
|
}
|
|
11107
11985
|
}
|
|
11986
|
+
const pendingCropGroupFrameBakes = [];
|
|
11108
11987
|
for (const obj of activeObjects) {
|
|
11109
11988
|
const objId = getObjectId(obj);
|
|
11110
11989
|
if (!objId || objId === "__background__") continue;
|
|
@@ -11158,10 +12037,16 @@ const PageCanvas = react.forwardRef(
|
|
|
11158
12037
|
}
|
|
11159
12038
|
if (obj instanceof fabric__namespace.Group && obj.__cropGroup) {
|
|
11160
12039
|
const ct = obj.__cropData;
|
|
11161
|
-
|
|
11162
|
-
|
|
11163
|
-
|
|
11164
|
-
|
|
12040
|
+
if (isActiveSelection && activeObj instanceof fabric__namespace.ActiveSelection) {
|
|
12041
|
+
const frameBounds = getObjectFrameBoundsInSelection(activeObj, obj, ct == null ? void 0 : ct.frameW, ct == null ? void 0 : ct.frameH);
|
|
12042
|
+
absoluteLeft = frameBounds.left;
|
|
12043
|
+
absoluteTop = frameBounds.top;
|
|
12044
|
+
} else {
|
|
12045
|
+
const w = ((ct == null ? void 0 : ct.frameW) ?? obj.width ?? 0) * Math.abs(obj.scaleX ?? 1);
|
|
12046
|
+
const h = ((ct == null ? void 0 : ct.frameH) ?? obj.height ?? 0) * Math.abs(obj.scaleY ?? 1);
|
|
12047
|
+
absoluteLeft = (absoluteLeft ?? 0) - w / 2;
|
|
12048
|
+
absoluteTop = (absoluteTop ?? 0) - h / 2;
|
|
12049
|
+
}
|
|
11165
12050
|
} else if (obj instanceof fabric__namespace.FabricImage && (obj.originX === "center" || obj.originY === "center")) {
|
|
11166
12051
|
const w = (obj.width ?? 0) * (obj.scaleX ?? 1);
|
|
11167
12052
|
const h = (obj.height ?? 0) * (obj.scaleY ?? 1);
|
|
@@ -11178,17 +12063,49 @@ const PageCanvas = react.forwardRef(
|
|
|
11178
12063
|
if (obj instanceof fabric__namespace.Group && obj.__cropGroup) {
|
|
11179
12064
|
const ct = obj.__cropData;
|
|
11180
12065
|
if (ct) {
|
|
11181
|
-
|
|
11182
|
-
|
|
12066
|
+
const sourceFrameW = Math.max(1, ct.frameW ?? obj.width ?? 1);
|
|
12067
|
+
const sourceFrameH = Math.max(1, ct.frameH ?? obj.height ?? 1);
|
|
12068
|
+
const appliedScaleX = Math.abs(isActiveSelection && activeObj ? activeObj.scaleX ?? 1 : obj.scaleX ?? 1);
|
|
12069
|
+
const appliedScaleY = Math.abs(isActiveSelection && activeObj ? activeObj.scaleY ?? 1 : obj.scaleY ?? 1);
|
|
12070
|
+
finalWidth = Math.max(1, sourceFrameW * appliedScaleX);
|
|
12071
|
+
finalHeight = Math.max(1, sourceFrameH * appliedScaleY);
|
|
11183
12072
|
finalScaleX = 1;
|
|
11184
12073
|
finalScaleY = 1;
|
|
11185
|
-
|
|
11186
|
-
|
|
12074
|
+
if (isActiveSelection && activeObj instanceof fabric__namespace.ActiveSelection) {
|
|
12075
|
+
const frameBounds = getObjectFrameBoundsInSelection(activeObj, obj, sourceFrameW, sourceFrameH);
|
|
12076
|
+
absoluteLeft = frameBounds.left;
|
|
12077
|
+
absoluteTop = frameBounds.top;
|
|
12078
|
+
} else {
|
|
12079
|
+
absoluteLeft = (decomposed.translateX ?? absoluteLeft) - finalWidth / 2;
|
|
12080
|
+
absoluteTop = (decomposed.translateY ?? absoluteTop) - finalHeight / 2;
|
|
12081
|
+
}
|
|
12082
|
+
finalAbsoluteMatrix = fabric__namespace.util.composeMatrix({
|
|
12083
|
+
translateX: absoluteLeft + finalWidth / 2,
|
|
12084
|
+
translateY: absoluteTop + finalHeight / 2,
|
|
12085
|
+
angle: decomposed.angle ?? (obj.angle ?? 0),
|
|
12086
|
+
scaleX: 1,
|
|
12087
|
+
scaleY: 1,
|
|
12088
|
+
skewX: 0,
|
|
12089
|
+
skewY: 0
|
|
12090
|
+
});
|
|
12091
|
+
if (isActiveSelection && activeObj instanceof fabric__namespace.ActiveSelection) {
|
|
12092
|
+
pendingCropGroupFrameBakes.push({
|
|
12093
|
+
obj,
|
|
12094
|
+
width: finalWidth,
|
|
12095
|
+
height: finalHeight,
|
|
12096
|
+
left: absoluteLeft,
|
|
12097
|
+
top: absoluteTop,
|
|
12098
|
+
angle: decomposed.angle ?? (obj.angle ?? 0)
|
|
12099
|
+
});
|
|
12100
|
+
} else {
|
|
12101
|
+
ct.frameW = finalWidth;
|
|
12102
|
+
ct.frameH = finalHeight;
|
|
12103
|
+
obj.set({ width: finalWidth, height: finalHeight, scaleX: 1, scaleY: 1 });
|
|
11187
12104
|
updateCoverLayout(obj);
|
|
11188
|
-
|
|
12105
|
+
}
|
|
12106
|
+
obj.__lastResizeHandle = null;
|
|
12107
|
+
if (!isActiveSelection) {
|
|
11189
12108
|
fabricCanvas.setActiveObject(obj);
|
|
11190
|
-
} else {
|
|
11191
|
-
obj.__lastResizeHandle = null;
|
|
11192
12109
|
}
|
|
11193
12110
|
}
|
|
11194
12111
|
} else if (obj instanceof fabric__namespace.FabricImage) {
|
|
@@ -11278,6 +12195,10 @@ const PageCanvas = react.forwardRef(
|
|
|
11278
12195
|
if (obj.textPath) {
|
|
11279
12196
|
elementUpdate.textPath = obj.textPath;
|
|
11280
12197
|
}
|
|
12198
|
+
const bakedFs = obj.fontSize;
|
|
12199
|
+
if (typeof bakedFs === "number" && bakedFs > 0) {
|
|
12200
|
+
elementUpdate.fontSize = bakedFs;
|
|
12201
|
+
}
|
|
11281
12202
|
}
|
|
11282
12203
|
if (sourceElement && sourceElement.opacity !== void 0) {
|
|
11283
12204
|
elementUpdate.opacity = sourceElement.opacity;
|
|
@@ -11285,7 +12206,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11285
12206
|
updateElement(objId, elementUpdate, { recordHistory: false, skipLayoutRecalc: true });
|
|
11286
12207
|
obj.setCoords();
|
|
11287
12208
|
}
|
|
11288
|
-
const pageChildrenForReflow = ((
|
|
12209
|
+
const pageChildrenForReflow = ((_g = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _g.children) ?? [];
|
|
11289
12210
|
const stackGroupsToReflow = /* @__PURE__ */ new Set();
|
|
11290
12211
|
for (const id of modifiedIdsThisRound) {
|
|
11291
12212
|
const parent = findParentGroup(pageChildrenForReflow, id);
|
|
@@ -11309,6 +12230,25 @@ const PageCanvas = react.forwardRef(
|
|
|
11309
12230
|
} finally {
|
|
11310
12231
|
skipActiveSelectionBakeOnClearRef.current = false;
|
|
11311
12232
|
}
|
|
12233
|
+
for (const bake of pendingCropGroupFrameBakes) {
|
|
12234
|
+
const ct = bake.obj.__cropData;
|
|
12235
|
+
if (!ct) continue;
|
|
12236
|
+
ct.frameW = bake.width;
|
|
12237
|
+
ct.frameH = bake.height;
|
|
12238
|
+
bake.obj.set({
|
|
12239
|
+
left: bake.left + bake.width / 2,
|
|
12240
|
+
top: bake.top + bake.height / 2,
|
|
12241
|
+
width: bake.width,
|
|
12242
|
+
height: bake.height,
|
|
12243
|
+
scaleX: 1,
|
|
12244
|
+
scaleY: 1,
|
|
12245
|
+
angle: bake.angle,
|
|
12246
|
+
originX: "center",
|
|
12247
|
+
originY: "center"
|
|
12248
|
+
});
|
|
12249
|
+
updateCoverLayout(bake.obj);
|
|
12250
|
+
bake.obj.setCoords();
|
|
12251
|
+
}
|
|
11312
12252
|
if (membersToReselect.length > 1) {
|
|
11313
12253
|
const newSel = new fabric__namespace.ActiveSelection(membersToReselect, { canvas: fabricCanvas });
|
|
11314
12254
|
if (wasGroupSel) restoreGroupSelectionVisualState(newSel, wasGroupSel);
|
|
@@ -11327,6 +12267,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11327
12267
|
fabricCanvas.requestRenderAll();
|
|
11328
12268
|
}
|
|
11329
12269
|
groupSelectionTransformStartRef.current = null;
|
|
12270
|
+
activeSelectionMoveStartRef.current = null;
|
|
11330
12271
|
setTimeout(() => modifiedIdsThisRound.forEach((id) => justModifiedIdsRef.current.delete(id)), 150);
|
|
11331
12272
|
commitHistory();
|
|
11332
12273
|
unlockEditsSoon();
|
|
@@ -11355,6 +12296,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11355
12296
|
}
|
|
11356
12297
|
});
|
|
11357
12298
|
fabricCanvas.on("mouse:dblclick", (e) => {
|
|
12299
|
+
var _a2, _b;
|
|
11358
12300
|
if (!isActiveRef.current || !allowEditing) return;
|
|
11359
12301
|
let target = e.target;
|
|
11360
12302
|
if (!target) {
|
|
@@ -11363,7 +12305,10 @@ const PageCanvas = react.forwardRef(
|
|
|
11363
12305
|
}
|
|
11364
12306
|
if (target && target instanceof fabric__namespace.Group && target.__cropGroup) {
|
|
11365
12307
|
const ct = target.__cropData;
|
|
11366
|
-
|
|
12308
|
+
const innerImg = ct == null ? void 0 : ct._img;
|
|
12309
|
+
const innerSrc = ((_a2 = innerImg == null ? void 0 : innerImg.getSrc) == null ? void 0 : _a2.call(innerImg)) || ((_b = innerImg == null ? void 0 : innerImg._originalElement) == null ? void 0 : _b.src) || (innerImg == null ? void 0 : innerImg.src) || "";
|
|
12310
|
+
const isPlaceholder = !innerSrc || innerSrc === EMPTY_IMAGE_PLACEHOLDER_DATA_URL;
|
|
12311
|
+
if (innerImg && !isPlaceholder && !isCropGroupInCropMode(target)) {
|
|
11367
12312
|
enterCropMode(target);
|
|
11368
12313
|
return;
|
|
11369
12314
|
}
|
|
@@ -11597,14 +12542,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11597
12542
|
try {
|
|
11598
12543
|
const newSel = new fabric__namespace.ActiveSelection(freshMembers, { canvas: fc });
|
|
11599
12544
|
if (activeSelectionSnapshot.groupSelectionId) {
|
|
11600
|
-
newSel
|
|
11601
|
-
suppressGroupMemberBordersRef.current = freshMembers;
|
|
11602
|
-
for (const m of freshMembers) {
|
|
11603
|
-
if (m.__pixldocsOrigHasBorders === void 0) {
|
|
11604
|
-
m.__pixldocsOrigHasBorders = m.hasBorders;
|
|
11605
|
-
}
|
|
11606
|
-
m.hasBorders = false;
|
|
11607
|
-
}
|
|
12545
|
+
applyLogicalGroupSelectionVisualState(newSel, activeSelectionSnapshot.groupSelectionId);
|
|
11608
12546
|
}
|
|
11609
12547
|
fc.setActiveObject(newSel);
|
|
11610
12548
|
newSel.setCoords();
|
|
@@ -11989,6 +12927,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11989
12927
|
continue;
|
|
11990
12928
|
}
|
|
11991
12929
|
if (existingObj instanceof fabric__namespace.Group && existingObj.__cropGroup) {
|
|
12930
|
+
updateFabricObject(existingObj, element, wasJustModified);
|
|
11992
12931
|
existingObj.set({
|
|
11993
12932
|
flipX: element.flipX ?? false,
|
|
11994
12933
|
flipY: element.flipY ?? false,
|
|
@@ -11996,6 +12935,7 @@ const PageCanvas = react.forwardRef(
|
|
|
11996
12935
|
});
|
|
11997
12936
|
existingObj.setCoords();
|
|
11998
12937
|
fc.requestRenderAll();
|
|
12938
|
+
if (wasJustModified) justModifiedIdsRef.current.delete(element.id);
|
|
11999
12939
|
continue;
|
|
12000
12940
|
}
|
|
12001
12941
|
if (existingObj instanceof fabric__namespace.Textbox && wasJustModified && !syncTriggeredByPanelRef.current) {
|
|
@@ -12262,18 +13202,17 @@ const PageCanvas = react.forwardRef(
|
|
|
12262
13202
|
}
|
|
12263
13203
|
if (!shouldSkipUpdates2) {
|
|
12264
13204
|
const dfsIds = [];
|
|
12265
|
-
const visit = (nodes
|
|
12266
|
-
const
|
|
12267
|
-
for (const n of list) {
|
|
13205
|
+
const visit = (nodes) => {
|
|
13206
|
+
for (const n of nodes) {
|
|
12268
13207
|
if (isElement(n)) dfsIds.push(n.id);
|
|
12269
13208
|
else if (isGroup(n)) {
|
|
12270
13209
|
const g = n;
|
|
12271
13210
|
if (sectionGroupIds.has(g.id)) dfsIds.push(g.id);
|
|
12272
|
-
visit(g.children ?? []
|
|
13211
|
+
visit(g.children ?? []);
|
|
12273
13212
|
}
|
|
12274
13213
|
}
|
|
12275
13214
|
};
|
|
12276
|
-
visit(pageTree
|
|
13215
|
+
visit(pageTree);
|
|
12277
13216
|
const allFabricObjects = fc.getObjects();
|
|
12278
13217
|
allFabricObjects.sort((a, b) => {
|
|
12279
13218
|
const aIndex = dfsIds.indexOf(getObjectId(a) || "");
|
|
@@ -12335,14 +13274,7 @@ const PageCanvas = react.forwardRef(
|
|
|
12335
13274
|
try {
|
|
12336
13275
|
const newSel = new fabric__namespace.ActiveSelection(freshMembers, { canvas: fc });
|
|
12337
13276
|
if (activeSelectionSnapshot.groupSelectionId) {
|
|
12338
|
-
newSel
|
|
12339
|
-
suppressGroupMemberBordersRef.current = freshMembers;
|
|
12340
|
-
for (const m of freshMembers) {
|
|
12341
|
-
if (m.__pixldocsOrigHasBorders === void 0) {
|
|
12342
|
-
m.__pixldocsOrigHasBorders = m.hasBorders;
|
|
12343
|
-
}
|
|
12344
|
-
m.hasBorders = false;
|
|
12345
|
-
}
|
|
13277
|
+
applyLogicalGroupSelectionVisualState(newSel, activeSelectionSnapshot.groupSelectionId);
|
|
12346
13278
|
}
|
|
12347
13279
|
fc.setActiveObject(newSel);
|
|
12348
13280
|
newSel.setCoords();
|
|
@@ -12534,12 +13466,24 @@ const PageCanvas = react.forwardRef(
|
|
|
12534
13466
|
isSyncingSelectionToFabricRef.current = true;
|
|
12535
13467
|
const selectedSet = new Set(selectedIds);
|
|
12536
13468
|
const pageChildrenForSelection = ((_a2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
|
|
12537
|
-
const
|
|
13469
|
+
const selectedGroupIds = selectedIds.filter((id) => {
|
|
12538
13470
|
const node = findNodeById(pageChildrenForSelection, id);
|
|
12539
13471
|
return !!(node && isGroup(node));
|
|
12540
13472
|
});
|
|
12541
|
-
const
|
|
12542
|
-
const
|
|
13473
|
+
const selectedGroupSelectionId = selectedGroupIds[0];
|
|
13474
|
+
const selectedGroupMemberIdsAll = /* @__PURE__ */ new Set();
|
|
13475
|
+
for (const gid of selectedGroupIds) {
|
|
13476
|
+
const groupNode = findNodeById(pageChildrenForSelection, gid);
|
|
13477
|
+
if (groupNode && isGroup(groupNode)) {
|
|
13478
|
+
getAllElementIds(groupNode.children ?? []).forEach((id) => selectedGroupMemberIdsAll.add(id));
|
|
13479
|
+
}
|
|
13480
|
+
}
|
|
13481
|
+
const standaloneSelectedIds = selectedIds.filter((id) => {
|
|
13482
|
+
if (selectedGroupIds.includes(id)) return false;
|
|
13483
|
+
if (selectedGroupMemberIdsAll.has(id)) return false;
|
|
13484
|
+
return !!findNodeById(pageChildrenForSelection, id);
|
|
13485
|
+
});
|
|
13486
|
+
const isPureSingleGroupSelection = selectedGroupIds.length === 1 && standaloneSelectedIds.length === 0;
|
|
12543
13487
|
const toSelect = [];
|
|
12544
13488
|
for (const obj of fc.getObjects()) {
|
|
12545
13489
|
const id = getObjectId(obj);
|
|
@@ -12548,17 +13492,29 @@ const PageCanvas = react.forwardRef(
|
|
|
12548
13492
|
toSelect.push(obj);
|
|
12549
13493
|
continue;
|
|
12550
13494
|
}
|
|
12551
|
-
if (id &&
|
|
13495
|
+
if (id && selectedGroupMemberIdsAll.has(id)) {
|
|
12552
13496
|
toSelect.push(obj);
|
|
12553
13497
|
continue;
|
|
12554
13498
|
}
|
|
12555
13499
|
if (obj instanceof fabric__namespace.Group && obj.__docuforgeSectionGroup) {
|
|
12556
13500
|
for (const child of obj.getObjects()) {
|
|
12557
13501
|
const childId = getObjectId(child);
|
|
12558
|
-
if (childId && (selectedSet.has(childId) ||
|
|
13502
|
+
if (childId && (selectedSet.has(childId) || selectedGroupMemberIdsAll.has(childId))) toSelect.push(child);
|
|
12559
13503
|
}
|
|
12560
13504
|
}
|
|
12561
13505
|
}
|
|
13506
|
+
const restoreSuppressedBordersForSelectionSync = () => {
|
|
13507
|
+
const suppressed = suppressGroupMemberBordersRef.current;
|
|
13508
|
+
for (const member of suppressed) {
|
|
13509
|
+
const origBorders = member.__pixldocsOrigHasBorders;
|
|
13510
|
+
const origControls = member.__pixldocsOrigHasControls;
|
|
13511
|
+
member.hasBorders = origBorders !== void 0 ? origBorders : true;
|
|
13512
|
+
member.hasControls = origControls !== void 0 ? origControls : true;
|
|
13513
|
+
delete member.__pixldocsOrigHasBorders;
|
|
13514
|
+
delete member.__pixldocsOrigHasControls;
|
|
13515
|
+
}
|
|
13516
|
+
suppressGroupMemberBordersRef.current = [];
|
|
13517
|
+
};
|
|
12562
13518
|
if (toSelect.length === 0) {
|
|
12563
13519
|
if (!syncLockedRef.current && !editLockRef.current) {
|
|
12564
13520
|
fc.discardActiveObject();
|
|
@@ -12569,6 +13525,12 @@ const PageCanvas = react.forwardRef(
|
|
|
12569
13525
|
if (objId) {
|
|
12570
13526
|
justModifiedIdsRef.current.add(objId);
|
|
12571
13527
|
}
|
|
13528
|
+
if (!selectedGroupSelectionId) {
|
|
13529
|
+
restoreSuppressedBordersForSelectionSync();
|
|
13530
|
+
delete obj.__pixldocsGroupSelection;
|
|
13531
|
+
delete obj.__pixldocsLogicalGroupIds;
|
|
13532
|
+
obj.set({ selectable: true, evented: true, hasBorders: true, hasControls: true });
|
|
13533
|
+
}
|
|
12572
13534
|
fc.setActiveObject(obj);
|
|
12573
13535
|
obj.setCoords();
|
|
12574
13536
|
} else {
|
|
@@ -12577,13 +13539,39 @@ const PageCanvas = react.forwardRef(
|
|
|
12577
13539
|
const sameSelection = active instanceof fabric__namespace.ActiveSelection && active.getObjects().length === toSelect.length && toSelect.every((obj) => active.getObjects().includes(obj));
|
|
12578
13540
|
if (sameSelection && isFlatGroupSelection) {
|
|
12579
13541
|
if (selectedGroupSelectionId && active instanceof fabric__namespace.ActiveSelection) {
|
|
12580
|
-
|
|
12581
|
-
|
|
12582
|
-
|
|
13542
|
+
if (isPureSingleGroupSelection) {
|
|
13543
|
+
active.__pixldocsGroupSelection = selectedGroupSelectionId;
|
|
13544
|
+
delete active.__pixldocsLogicalGroupIds;
|
|
13545
|
+
suppressGroupMemberBordersRef.current = active.getObjects();
|
|
13546
|
+
} else {
|
|
13547
|
+
delete active.__pixldocsGroupSelection;
|
|
13548
|
+
active.__pixldocsLogicalGroupIds = selectedGroupIds;
|
|
13549
|
+
active.hasBorders = true;
|
|
13550
|
+
suppressGroupMemberBordersRef.current = active.getObjects().filter((m) => {
|
|
13551
|
+
const id = getObjectId(m);
|
|
13552
|
+
return !!id && selectedGroupMemberIdsAll.has(id);
|
|
13553
|
+
});
|
|
13554
|
+
}
|
|
13555
|
+
suppressGroupMemberBordersRef.current.forEach((m) => {
|
|
13556
|
+
var _a3;
|
|
12583
13557
|
if (m.__pixldocsOrigHasBorders === void 0) m.__pixldocsOrigHasBorders = m.hasBorders;
|
|
13558
|
+
if (m.__pixldocsOrigHasControls === void 0) m.__pixldocsOrigHasControls = m.hasControls;
|
|
12584
13559
|
m.hasBorders = false;
|
|
13560
|
+
m.hasControls = false;
|
|
13561
|
+
if (m.__cropGroup || ((_a3 = m._ct) == null ? void 0 : _a3.isCropGroup)) {
|
|
13562
|
+
if (m.__pixldocsOrigLockScalingX === void 0) {
|
|
13563
|
+
m.__pixldocsOrigLockScalingX = m.lockScalingX;
|
|
13564
|
+
m.__pixldocsOrigLockScalingY = m.lockScalingY;
|
|
13565
|
+
}
|
|
13566
|
+
m.lockScalingX = false;
|
|
13567
|
+
m.lockScalingY = false;
|
|
13568
|
+
}
|
|
12585
13569
|
});
|
|
12586
|
-
|
|
13570
|
+
if (isPureSingleGroupSelection) {
|
|
13571
|
+
active.hasBorders = true;
|
|
13572
|
+
active.setCoords();
|
|
13573
|
+
applyWarpAwareSelectionBorders(active);
|
|
13574
|
+
}
|
|
12587
13575
|
}
|
|
12588
13576
|
fc.requestRenderAll();
|
|
12589
13577
|
} else {
|
|
@@ -12593,13 +13581,33 @@ const PageCanvas = react.forwardRef(
|
|
|
12593
13581
|
});
|
|
12594
13582
|
const selection = new fabric__namespace.ActiveSelection(toSelect, { canvas: fc });
|
|
12595
13583
|
if (selectedGroupSelectionId) {
|
|
12596
|
-
|
|
12597
|
-
|
|
12598
|
-
|
|
13584
|
+
if (isPureSingleGroupSelection) {
|
|
13585
|
+
selection.__pixldocsGroupSelection = selectedGroupSelectionId;
|
|
13586
|
+
suppressGroupMemberBordersRef.current = toSelect;
|
|
13587
|
+
} else {
|
|
13588
|
+
selection.__pixldocsLogicalGroupIds = selectedGroupIds;
|
|
13589
|
+
selection.hasBorders = true;
|
|
13590
|
+
suppressGroupMemberBordersRef.current = toSelect.filter((m) => {
|
|
13591
|
+
const id = getObjectId(m);
|
|
13592
|
+
return !!id && selectedGroupMemberIdsAll.has(id);
|
|
13593
|
+
});
|
|
13594
|
+
}
|
|
13595
|
+
suppressGroupMemberBordersRef.current.forEach((m) => {
|
|
13596
|
+
var _a3;
|
|
12599
13597
|
if (m.__pixldocsOrigHasBorders === void 0) m.__pixldocsOrigHasBorders = m.hasBorders;
|
|
13598
|
+
if (m.__pixldocsOrigHasControls === void 0) m.__pixldocsOrigHasControls = m.hasControls;
|
|
12600
13599
|
m.hasBorders = false;
|
|
13600
|
+
m.hasControls = false;
|
|
13601
|
+
if (m.__cropGroup || ((_a3 = m._ct) == null ? void 0 : _a3.isCropGroup)) {
|
|
13602
|
+
if (m.__pixldocsOrigLockScalingX === void 0) {
|
|
13603
|
+
m.__pixldocsOrigLockScalingX = m.lockScalingX;
|
|
13604
|
+
m.__pixldocsOrigLockScalingY = m.lockScalingY;
|
|
13605
|
+
}
|
|
13606
|
+
m.lockScalingX = false;
|
|
13607
|
+
m.lockScalingY = false;
|
|
13608
|
+
}
|
|
12601
13609
|
});
|
|
12602
|
-
applyWarpAwareSelectionBorders(selection);
|
|
13610
|
+
if (isPureSingleGroupSelection) applyWarpAwareSelectionBorders(selection);
|
|
12603
13611
|
}
|
|
12604
13612
|
fc.setActiveObject(selection);
|
|
12605
13613
|
if (!isFlatGroupSelection) {
|
|
@@ -12905,7 +13913,7 @@ const PageCanvas = react.forwardRef(
|
|
|
12905
13913
|
const angleTextPathActive = isTextbox && ((_b = element.textPath) == null ? void 0 : _b.preset) === "rise";
|
|
12906
13914
|
const appliedSkewY = angleTextPathActive ? 0 : element.skewY ?? 0;
|
|
12907
13915
|
let posIfNotSkipped = skipPositionUpdate ? {} : { left: fabricPos.left, top: fabricPos.top };
|
|
12908
|
-
if (!skipPositionUpdate && obj instanceof fabric__namespace.FabricImage && obj.originX === "center") {
|
|
13916
|
+
if (!skipPositionUpdate && (obj instanceof fabric__namespace.FabricImage && obj.originX === "center" || obj instanceof fabric__namespace.Group && obj.__cropGroup)) {
|
|
12909
13917
|
const vW = rW * effectiveScaleX;
|
|
12910
13918
|
const vH = rH * effectiveScaleY;
|
|
12911
13919
|
posIfNotSkipped = { left: fabricPos.left + vW / 2, top: fabricPos.top + vH / 2 };
|
|
@@ -13084,7 +14092,23 @@ const PageCanvas = react.forwardRef(
|
|
|
13084
14092
|
objectCaching: false,
|
|
13085
14093
|
noScaleCache: true,
|
|
13086
14094
|
splitByGrapheme,
|
|
13087
|
-
text
|
|
14095
|
+
text,
|
|
14096
|
+
// Text outline (stroke). Only apply when BOTH a stroke color and
|
|
14097
|
+
// positive width are explicitly set — otherwise fabric defaults
|
|
14098
|
+
// stroke to black and renders an unwanted outline on existing
|
|
14099
|
+
// text elements that carry a stray strokeWidth.
|
|
14100
|
+
...(() => {
|
|
14101
|
+
const s = element.stroke;
|
|
14102
|
+
const w = Number(element.strokeWidth) || 0;
|
|
14103
|
+
const has = !!s && w > 0;
|
|
14104
|
+
return has ? {
|
|
14105
|
+
stroke: s,
|
|
14106
|
+
strokeWidth: w,
|
|
14107
|
+
paintFirst: element.paintFirst || "fill",
|
|
14108
|
+
strokeUniform: true,
|
|
14109
|
+
strokeLineJoin: "round"
|
|
14110
|
+
} : { stroke: void 0, strokeWidth: 0 };
|
|
14111
|
+
})()
|
|
13088
14112
|
});
|
|
13089
14113
|
const valign = element.verticalAlign || "top";
|
|
13090
14114
|
const minBoxH = Math.max(0, Number(element.minBoxHeight) || 0);
|
|
@@ -13740,7 +14764,10 @@ const PageCanvas = react.forwardRef(
|
|
|
13740
14764
|
let panX = element.cropPanX ?? 0.5;
|
|
13741
14765
|
let panY = element.cropPanY ?? 0.5;
|
|
13742
14766
|
let zoom2 = element.cropZoom ?? 1;
|
|
13743
|
-
|
|
14767
|
+
const elementHasExplicitCrop = element.cropPanX != null || element.cropPanY != null || element.cropZoom != null;
|
|
14768
|
+
const existingGroupSource = existingCropGroup ? String(existingCropGroup.__imageSrc || "") : "";
|
|
14769
|
+
const canPreserveLiveCrop = Boolean(existingCropGroup) && (elementHasExplicitCrop || existingGroupSource === imageUrl);
|
|
14770
|
+
if (canPreserveLiveCrop && existingCropGroup) {
|
|
13744
14771
|
const existingImg = (_j = existingCropGroup.__cropData) == null ? void 0 : _j._img;
|
|
13745
14772
|
if (existingImg) {
|
|
13746
14773
|
panX = ((_k = existingImg._ct) == null ? void 0 : _k.panX) ?? existingImg.__panX ?? panX;
|
|
@@ -15081,6 +16108,19 @@ function setInTree(nodes, elementId, targetProperty, value) {
|
|
|
15081
16108
|
} else if (targetProperty === "text" && node.type === "text" && typeof value === "string") {
|
|
15082
16109
|
const textVal = value === "" ? " " : value;
|
|
15083
16110
|
node[targetProperty] = applyTextCase(textVal, node.textCase);
|
|
16111
|
+
} else if ((targetProperty === "src" || targetProperty === "imageUrl") && node.type === "image") {
|
|
16112
|
+
const previousSrc = String(node.src || node.imageUrl || "");
|
|
16113
|
+
const nextSrc = String(value ?? "");
|
|
16114
|
+
const srcChanged = nextSrc !== "" && nextSrc !== previousSrc;
|
|
16115
|
+
node.src = value;
|
|
16116
|
+
node.imageUrl = value;
|
|
16117
|
+
if (srcChanged) {
|
|
16118
|
+
delete node.imageNaturalWidth;
|
|
16119
|
+
delete node.imageNaturalHeight;
|
|
16120
|
+
delete node.cropPanX;
|
|
16121
|
+
delete node.cropPanY;
|
|
16122
|
+
delete node.cropZoom;
|
|
16123
|
+
}
|
|
15084
16124
|
} else {
|
|
15085
16125
|
node[targetProperty] = value;
|
|
15086
16126
|
}
|
|
@@ -15090,10 +16130,6 @@ function setInTree(nodes, elementId, targetProperty, value) {
|
|
|
15090
16130
|
delete node.height;
|
|
15091
16131
|
}
|
|
15092
16132
|
}
|
|
15093
|
-
if ((targetProperty === "src" || targetProperty === "imageUrl") && node.type === "image") {
|
|
15094
|
-
delete node.imageNaturalWidth;
|
|
15095
|
-
delete node.imageNaturalHeight;
|
|
15096
|
-
}
|
|
15097
16133
|
return true;
|
|
15098
16134
|
}
|
|
15099
16135
|
if (node.children && Array.isArray(node.children)) {
|
|
@@ -19881,10 +20917,11 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
19881
20917
|
for (const obj of objs) {
|
|
19882
20918
|
const isGroupLike = obj instanceof fabric__namespace.Group || (obj == null ? void 0 : obj.type) === "group" || Array.isArray(obj == null ? void 0 : obj._objects);
|
|
19883
20919
|
const isFadedCropGroup = isGroupLike && (Boolean(obj.__edgeFadeRenderConfig) || Boolean(obj.__edgeFadeKey) || Boolean(obj.__edgeFadeInputKey));
|
|
19884
|
-
|
|
20920
|
+
const hasSvgMaskClip = isGroupLike && obj.__cropGroup && obj.clipPath && (obj.clipPath.__svgMask === true || obj.clipPath.__svgMaskUrl || obj.clipPath.__svgMaskType || obj.__svgMaskUrl || obj.__svgMaskType);
|
|
20921
|
+
if (!isFadedCropGroup && !hasSvgMaskClip) continue;
|
|
19885
20922
|
try {
|
|
19886
20923
|
const baked = obj.toCanvasElement({
|
|
19887
|
-
multiplier: 2,
|
|
20924
|
+
multiplier: hasSvgMaskClip ? 4 : 2,
|
|
19888
20925
|
enableRetinaScaling: false
|
|
19889
20926
|
});
|
|
19890
20927
|
const rect = obj.getBoundingRect();
|
|
@@ -19957,9 +20994,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
19957
20994
|
}
|
|
19958
20995
|
return svgString;
|
|
19959
20996
|
}
|
|
19960
|
-
const resolvedPackageVersion = "0.5.
|
|
20997
|
+
const resolvedPackageVersion = "0.5.226";
|
|
19961
20998
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
19962
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
20999
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.226";
|
|
19963
21000
|
const roundParityValue = (value) => {
|
|
19964
21001
|
if (typeof value !== "number") return value;
|
|
19965
21002
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -20703,7 +21740,7 @@ class PixldocsRenderer {
|
|
|
20703
21740
|
await this.waitForCanvasScene(container, cloned, i);
|
|
20704
21741
|
}
|
|
20705
21742
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
20706
|
-
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
21743
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-C18SGeJb.cjs"));
|
|
20707
21744
|
const prepared = preparePagesForExport(
|
|
20708
21745
|
cloned.pages,
|
|
20709
21746
|
canvasWidth,
|
|
@@ -23023,7 +24060,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
23023
24060
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
23024
24061
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
23025
24062
|
try {
|
|
23026
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
24063
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-C18SGeJb.cjs"));
|
|
23027
24064
|
try {
|
|
23028
24065
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
23029
24066
|
} catch {
|
|
@@ -23419,4 +24456,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
23419
24456
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
23420
24457
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
23421
24458
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
23422
|
-
//# sourceMappingURL=index-
|
|
24459
|
+
//# sourceMappingURL=index-CXOoVCq1.cjs.map
|