@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
|
@@ -3,7 +3,7 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
|
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
var _a;
|
|
5
5
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
6
|
-
import { forwardRef, useRef, useState, useMemo, useEffect,
|
|
6
|
+
import { forwardRef, useRef, useState, useCallback, useMemo, useEffect, useImperativeHandle, createElement } from "react";
|
|
7
7
|
import { flushSync } from "react-dom";
|
|
8
8
|
import { toast } from "sonner";
|
|
9
9
|
import { create } from "zustand";
|
|
@@ -436,6 +436,148 @@ function fallbackEstimateHeight(element) {
|
|
|
436
436
|
function clearMeasurementCache() {
|
|
437
437
|
heightCache.clear();
|
|
438
438
|
}
|
|
439
|
+
function computeAutoShrinkFontSize(element) {
|
|
440
|
+
const baseFontSize = element.fontSize || 16;
|
|
441
|
+
if (element.overflowPolicy !== "auto-shrink") return baseFontSize;
|
|
442
|
+
const text = element.text || element.content || "";
|
|
443
|
+
if (!text) return baseFontSize;
|
|
444
|
+
const width = element.width || 200;
|
|
445
|
+
const height = element.height;
|
|
446
|
+
if (!height) return baseFontSize;
|
|
447
|
+
let fontSize = baseFontSize;
|
|
448
|
+
try {
|
|
449
|
+
while (fontSize > 1) {
|
|
450
|
+
const testTb = new fabric.Textbox(text, {
|
|
451
|
+
width,
|
|
452
|
+
fontSize,
|
|
453
|
+
fontFamily: element.fontFamily || "Open Sans",
|
|
454
|
+
fontWeight: element.fontWeight || 400,
|
|
455
|
+
fontStyle: element.fontStyle || "normal",
|
|
456
|
+
lineHeight: element.lineHeight || 1.2,
|
|
457
|
+
charSpacing: element.charSpacing || 0,
|
|
458
|
+
splitByGrapheme: false
|
|
459
|
+
});
|
|
460
|
+
testTb.initDimensions();
|
|
461
|
+
const textHeight = testTb.height || 0;
|
|
462
|
+
const fitsHeight = textHeight <= height;
|
|
463
|
+
const lineWidths = testTb.__lineWidths;
|
|
464
|
+
const maxLineWidth = lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : 0;
|
|
465
|
+
const fitsWidth = maxLineWidth <= width + 1;
|
|
466
|
+
if (fitsHeight && fitsWidth) break;
|
|
467
|
+
fontSize--;
|
|
468
|
+
}
|
|
469
|
+
} catch (e) {
|
|
470
|
+
console.warn("[autoShrink] Failed to compute shrunk font size:", e);
|
|
471
|
+
return baseFontSize;
|
|
472
|
+
}
|
|
473
|
+
return fontSize;
|
|
474
|
+
}
|
|
475
|
+
function measureTextGlyphHeightForStackHug(el) {
|
|
476
|
+
const text = el.text || " ";
|
|
477
|
+
const width = Math.max(1, typeof el.width === "number" ? el.width : 200);
|
|
478
|
+
let fontSize = el.fontSize || 16;
|
|
479
|
+
const lineHeight = el.lineHeight || 1.2;
|
|
480
|
+
const charSpacing = el.charSpacing || 0;
|
|
481
|
+
const fontFamily = el.fontFamily || "Open Sans";
|
|
482
|
+
const fontWeight = el.fontWeight || 400;
|
|
483
|
+
const fontStyle = el.fontStyle || "normal";
|
|
484
|
+
const isAutoShrink = el.overflowPolicy === "auto-shrink";
|
|
485
|
+
const splitByGrapheme = isAutoShrink ? false : el.splitByGrapheme ?? el.wordWrap === "break-word";
|
|
486
|
+
if (isAutoShrink) {
|
|
487
|
+
const minBoxH = Math.max(0, Number(el.minBoxHeight) || 0);
|
|
488
|
+
const heightBound = Math.max(typeof el.height === "number" ? el.height : 0, minBoxH);
|
|
489
|
+
while (fontSize > 1) {
|
|
490
|
+
const testTb = new fabric.Textbox(text, {
|
|
491
|
+
width,
|
|
492
|
+
fontSize,
|
|
493
|
+
fontFamily,
|
|
494
|
+
fontWeight,
|
|
495
|
+
fontStyle,
|
|
496
|
+
lineHeight,
|
|
497
|
+
charSpacing,
|
|
498
|
+
splitByGrapheme: false
|
|
499
|
+
});
|
|
500
|
+
testTb.initDimensions();
|
|
501
|
+
const textHeight = testTb.height || 0;
|
|
502
|
+
const lineWidths = getCanvasMeasuredTextboxLineWidths(testTb);
|
|
503
|
+
const maxLineWidth = lineWidths.length > 0 ? Math.max(...lineWidths) : 0;
|
|
504
|
+
if ((heightBound <= 0 || textHeight <= heightBound) && maxLineWidth <= width + 1) break;
|
|
505
|
+
fontSize--;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
const textbox = new fabric.Textbox(text, {
|
|
509
|
+
width,
|
|
510
|
+
fontSize,
|
|
511
|
+
fontFamily,
|
|
512
|
+
fontWeight,
|
|
513
|
+
fontStyle,
|
|
514
|
+
lineHeight,
|
|
515
|
+
charSpacing,
|
|
516
|
+
splitByGrapheme
|
|
517
|
+
});
|
|
518
|
+
textbox.initDimensions();
|
|
519
|
+
return Math.max(1, (textbox.height || 20) * (el.scaleY || 1));
|
|
520
|
+
}
|
|
521
|
+
function getStackChildLayoutSize(parent, child, pageChildren, options) {
|
|
522
|
+
const b = getNodeBounds(child, pageChildren);
|
|
523
|
+
if (!parent.hugContent) return { width: b.width, height: b.height };
|
|
524
|
+
if (!isElement(child)) return { width: b.width, height: b.height };
|
|
525
|
+
const el = child;
|
|
526
|
+
if (el.type !== "text") return { width: b.width, height: b.height };
|
|
527
|
+
const isHorizontal = parent.layoutMode === "horizontal-stack";
|
|
528
|
+
if (isHorizontal) {
|
|
529
|
+
try {
|
|
530
|
+
const isAutoShrink = el.overflowPolicy === "auto-shrink";
|
|
531
|
+
const effectiveFontSize = isAutoShrink ? computeAutoShrinkFontSize(el) : el.fontSize || 16;
|
|
532
|
+
const probeWidth = isAutoShrink && typeof el.width === "number" ? el.width : 1e4;
|
|
533
|
+
const probe = new fabric.Textbox(el.text || " ", {
|
|
534
|
+
width: probeWidth,
|
|
535
|
+
fontSize: effectiveFontSize,
|
|
536
|
+
fontFamily: el.fontFamily || "Open Sans",
|
|
537
|
+
fontWeight: el.fontWeight || 400,
|
|
538
|
+
fontStyle: el.fontStyle || "normal",
|
|
539
|
+
lineHeight: el.lineHeight || 1.2,
|
|
540
|
+
charSpacing: el.charSpacing || 0,
|
|
541
|
+
splitByGrapheme: el.splitByGrapheme ?? el.wordWrap === "break-word"
|
|
542
|
+
});
|
|
543
|
+
probe.initDimensions();
|
|
544
|
+
const lineWidths = getCanvasMeasuredTextboxLineWidths(probe);
|
|
545
|
+
const maxLine = lineWidths.length > 0 ? Math.max(...lineWidths) : typeof el.width === "number" ? el.width : b.width;
|
|
546
|
+
const measuredW = Math.ceil(maxLine) + 2;
|
|
547
|
+
const w = Math.max(1, measuredW * (el.scaleX || 1));
|
|
548
|
+
return { width: w, height: b.height };
|
|
549
|
+
} catch {
|
|
550
|
+
return { width: b.width, height: b.height };
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
try {
|
|
554
|
+
const measuredH = measureTextGlyphHeightForStackHug(el);
|
|
555
|
+
const h = Math.max(1, measuredH);
|
|
556
|
+
return { width: b.width, height: h };
|
|
557
|
+
} catch {
|
|
558
|
+
return { width: b.width, height: b.height };
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
function getVerticalHugTextAdjust(parent, child) {
|
|
562
|
+
if (!parent.hugContent) return null;
|
|
563
|
+
if (parent.layoutMode !== "vertical-stack" && parent.layoutMode !== "stack") return null;
|
|
564
|
+
if (!isElement(child)) return null;
|
|
565
|
+
const el = child;
|
|
566
|
+
if (el.type !== "text") return null;
|
|
567
|
+
try {
|
|
568
|
+
const glyphHeight = measureTextGlyphHeightForStackHug(el);
|
|
569
|
+
const minBoxHeight = Math.max(0, Number(el.minBoxHeight) || 0);
|
|
570
|
+
const boxHeight = Math.max(typeof el.height === "number" ? el.height : glyphHeight, minBoxHeight);
|
|
571
|
+
const vAlign = el.verticalAlign ?? "top";
|
|
572
|
+
const extra = Math.max(0, boxHeight - glyphHeight);
|
|
573
|
+
let topOffset = 0;
|
|
574
|
+
if (vAlign === "middle" || vAlign === "center") topOffset = extra / 2;
|
|
575
|
+
else if (vAlign === "bottom") topOffset = extra;
|
|
576
|
+
return { topOffset, glyphHeight };
|
|
577
|
+
} catch {
|
|
578
|
+
return null;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
439
581
|
function simpleWidth(node) {
|
|
440
582
|
if (isElement(node)) {
|
|
441
583
|
const w = node.width;
|
|
@@ -476,23 +618,33 @@ function resolveStackGroupEffectivePositions(group, pageChildren, options) {
|
|
|
476
618
|
const out = /* @__PURE__ */ new Map();
|
|
477
619
|
const sizes = /* @__PURE__ */ new Map();
|
|
478
620
|
for (const c of kids) {
|
|
479
|
-
|
|
480
|
-
sizes.set(c.id, { width: b.width, height: b.height });
|
|
621
|
+
sizes.set(c.id, getStackChildLayoutSize(group, c, pageChildren));
|
|
481
622
|
}
|
|
482
623
|
if (isVertical) {
|
|
483
624
|
let prevBottom = padTop;
|
|
484
625
|
let firstSeen = false;
|
|
626
|
+
const placedIds = [];
|
|
485
627
|
for (let i = 0; i < kids.length; i++) {
|
|
486
628
|
const child = kids[i];
|
|
487
629
|
const storedTop = getNodeTop(child);
|
|
488
630
|
const storedLeft = getNodeLeft(child);
|
|
489
631
|
const mTop = child.marginTop ?? 0;
|
|
490
632
|
const mLeft = child.marginLeft ?? 0;
|
|
491
|
-
const
|
|
633
|
+
const hugAdjust = getVerticalHugTextAdjust(group, child);
|
|
634
|
+
const hugTopOffset = hugAdjust ? hugAdjust.topOffset : 0;
|
|
635
|
+
const visualTop = !firstSeen ? padTop + storedTop + mTop : prevBottom + gap + storedTop + mTop;
|
|
636
|
+
const effectiveTop = firstSeen ? visualTop : visualTop - hugTopOffset;
|
|
637
|
+
if (firstSeen && hugTopOffset > 0 && placedIds.length > 0) {
|
|
638
|
+
for (const placedId of placedIds) {
|
|
639
|
+
const placed = out.get(placedId);
|
|
640
|
+
if (placed) out.set(placedId, { ...placed, top: placed.top + hugTopOffset });
|
|
641
|
+
}
|
|
642
|
+
}
|
|
492
643
|
firstSeen = true;
|
|
493
644
|
out.set(child.id, { top: effectiveTop, left: padLeft + storedLeft + mLeft });
|
|
494
|
-
const h = sizes.get(child.id).height;
|
|
495
|
-
prevBottom = effectiveTop + h + (child.marginBottom ?? 0);
|
|
645
|
+
const h = hugAdjust ? hugAdjust.glyphHeight : sizes.get(child.id).height;
|
|
646
|
+
prevBottom = effectiveTop + hugTopOffset + h + (child.marginBottom ?? 0);
|
|
647
|
+
placedIds.push(child.id);
|
|
496
648
|
}
|
|
497
649
|
} else {
|
|
498
650
|
let prevRight = padLeft;
|
|
@@ -513,7 +665,20 @@ function resolveStackGroupEffectivePositions(group, pageChildren, options) {
|
|
|
513
665
|
const containerW = typeof group.width === "number" ? group.width : void 0;
|
|
514
666
|
const containerH = typeof group.height === "number" ? group.height : void 0;
|
|
515
667
|
const mainContainer = isVertical ? containerH : containerW;
|
|
516
|
-
|
|
668
|
+
let crossContainer = isVertical ? containerW : containerH;
|
|
669
|
+
if (kids.length > 0) {
|
|
670
|
+
let maxCross = 0;
|
|
671
|
+
for (const c of kids) {
|
|
672
|
+
const sz = sizes.get(c.id);
|
|
673
|
+
if (!sz) continue;
|
|
674
|
+
const cross = isVertical ? sz.width : sz.height;
|
|
675
|
+
if (cross > maxCross) maxCross = cross;
|
|
676
|
+
}
|
|
677
|
+
const crossPad0 = isVertical ? padLeft : padTop;
|
|
678
|
+
const crossPadEnd = isVertical ? padRight : padBottom;
|
|
679
|
+
const computed = maxCross + crossPad0 + crossPadEnd;
|
|
680
|
+
crossContainer = crossContainer != null ? Math.max(crossContainer, computed) : computed;
|
|
681
|
+
}
|
|
517
682
|
if (align !== "start" && crossContainer != null && kids.length > 0) {
|
|
518
683
|
const crossPad0 = isVertical ? padLeft : padTop;
|
|
519
684
|
const crossPadEnd = isVertical ? padRight : padBottom;
|
|
@@ -591,7 +756,8 @@ function resolveStackGroupEffectivePositions(group, pageChildren, options) {
|
|
|
591
756
|
if (!pos) continue;
|
|
592
757
|
const startMain = cursor + marginStart;
|
|
593
758
|
if (isVertical) {
|
|
594
|
-
|
|
759
|
+
const hugAdjust = getVerticalHugTextAdjust(group, child);
|
|
760
|
+
out.set(child.id, { top: startMain - ((hugAdjust == null ? void 0 : hugAdjust.topOffset) ?? 0), left: pos.left });
|
|
595
761
|
} else {
|
|
596
762
|
out.set(child.id, { top: pos.top, left: startMain });
|
|
597
763
|
}
|
|
@@ -613,13 +779,16 @@ function groupBoundsFromChildren(group, pageChildren, options) {
|
|
|
613
779
|
const positions = isStack ? resolveStackGroupEffectivePositions(group, pageChildren) : null;
|
|
614
780
|
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
615
781
|
for (const child of kids) {
|
|
616
|
-
const
|
|
782
|
+
const sz = isStack ? getStackChildLayoutSize(group, child, pageChildren) : (() => {
|
|
783
|
+
const b = getNodeBounds(child, pageChildren);
|
|
784
|
+
return { width: b.width, height: b.height };
|
|
785
|
+
})();
|
|
617
786
|
const cl = positions ? ((_a2 = positions.get(child.id)) == null ? void 0 : _a2.left) ?? getNodeLeft(child) : getNodeLeft(child);
|
|
618
787
|
const ct = positions ? ((_b = positions.get(child.id)) == null ? void 0 : _b.top) ?? getNodeTop(child) : getNodeTop(child);
|
|
619
788
|
minX = Math.min(minX, cl);
|
|
620
789
|
minY = Math.min(minY, ct);
|
|
621
|
-
maxX = Math.max(maxX, cl +
|
|
622
|
-
maxY = Math.max(maxY, ct +
|
|
790
|
+
maxX = Math.max(maxX, cl + sz.width);
|
|
791
|
+
maxY = Math.max(maxY, ct + sz.height);
|
|
623
792
|
}
|
|
624
793
|
if (isStack) {
|
|
625
794
|
const padRight = group.paddingRight ?? 0;
|
|
@@ -1040,6 +1209,7 @@ const useEditorStore = create((set, get) => ({
|
|
|
1040
1209
|
showDynamicLabels: false,
|
|
1041
1210
|
showSections: false,
|
|
1042
1211
|
hoveredGroupId: null,
|
|
1212
|
+
revealedLayerId: null,
|
|
1043
1213
|
history: [cloneCanvas(initialCanvas)],
|
|
1044
1214
|
historyIndex: 0,
|
|
1045
1215
|
lastCommittedSignature: canvasSignature(initialCanvas),
|
|
@@ -1579,7 +1749,16 @@ const useEditorStore = create((set, get) => ({
|
|
|
1579
1749
|
let nextChildren = currentPage.children;
|
|
1580
1750
|
const newNodes = [];
|
|
1581
1751
|
const duplicateAtPageLevel = [];
|
|
1582
|
-
|
|
1752
|
+
const idSet = new Set(ids);
|
|
1753
|
+
const filteredIds = ids.filter((id) => {
|
|
1754
|
+
let p = findParentGroup(currentPage.children, id);
|
|
1755
|
+
while (p) {
|
|
1756
|
+
if (idSet.has(p.id)) return false;
|
|
1757
|
+
p = findParentGroup(currentPage.children, p.id);
|
|
1758
|
+
}
|
|
1759
|
+
return true;
|
|
1760
|
+
});
|
|
1761
|
+
for (const id of filteredIds) {
|
|
1583
1762
|
const node = findNodeById(nextChildren, id);
|
|
1584
1763
|
if (!node) continue;
|
|
1585
1764
|
const parent = findParentGroup(nextChildren, id);
|
|
@@ -1596,19 +1775,9 @@ const useEditorStore = create((set, get) => ({
|
|
|
1596
1775
|
}
|
|
1597
1776
|
const pageLevelIds = new Set(duplicateAtPageLevel);
|
|
1598
1777
|
if (pageLevelIds.size > 0) {
|
|
1599
|
-
const
|
|
1600
|
-
const PAGE_GAP = 16;
|
|
1601
|
-
let maxBottom = PAGE_MARGIN;
|
|
1602
|
-
for (const node of currentPage.children) {
|
|
1603
|
-
const b = getNodeBounds(node, currentPage.children);
|
|
1604
|
-
if (b.bottom > maxBottom) maxBottom = b.bottom;
|
|
1605
|
-
}
|
|
1606
|
-
const pageLevelClones = newNodes.filter((n) => pageLevelIds.has(n.id));
|
|
1607
|
-
const bbox = getBoundingBoxOfRoots(pageLevelClones);
|
|
1608
|
-
const shiftX = PAGE_MARGIN - bbox.left;
|
|
1609
|
-
const shiftY = maxBottom + PAGE_GAP - bbox.top;
|
|
1778
|
+
const DUPLICATE_NUDGE = 16;
|
|
1610
1779
|
nextChildren = nextChildren.map(
|
|
1611
|
-
(node) => pageLevelIds.has(node.id) ? shiftNodeBy(node,
|
|
1780
|
+
(node) => pageLevelIds.has(node.id) ? shiftNodeBy(node, DUPLICATE_NUDGE, DUPLICATE_NUDGE) : node
|
|
1612
1781
|
);
|
|
1613
1782
|
}
|
|
1614
1783
|
let nextCanvas = updateCurrentPageChildren(state.canvas, () => nextChildren);
|
|
@@ -2025,12 +2194,19 @@ const useEditorStore = create((set, get) => ({
|
|
|
2025
2194
|
if (firstNodeIndex >= 0) {
|
|
2026
2195
|
insertIndex = firstNodeIndex;
|
|
2027
2196
|
}
|
|
2197
|
+
} else if (!commonParent && topLevelIds.length > 0) {
|
|
2198
|
+
const firstNodeIndex = currentPage.children.findIndex((child) => child.id === topLevelIds[0]);
|
|
2199
|
+
if (firstNodeIndex >= 0) {
|
|
2200
|
+
insertIndex = firstNodeIndex;
|
|
2201
|
+
}
|
|
2028
2202
|
}
|
|
2029
|
-
const
|
|
2203
|
+
const orderSource = commonParent ? commonParent.children : currentPage.children;
|
|
2204
|
+
const orderIndex = /* @__PURE__ */ new Map();
|
|
2205
|
+
orderSource.forEach((n, i) => orderIndex.set(n.id, i));
|
|
2030
2206
|
nodesToGroup.sort((a, b) => {
|
|
2031
|
-
const
|
|
2032
|
-
const
|
|
2033
|
-
return
|
|
2207
|
+
const ai = orderIndex.has(a.id) ? orderIndex.get(a.id) : Number.MAX_SAFE_INTEGER;
|
|
2208
|
+
const bi = orderIndex.has(b.id) ? orderIndex.get(b.id) : Number.MAX_SAFE_INTEGER;
|
|
2209
|
+
return ai - bi;
|
|
2034
2210
|
});
|
|
2035
2211
|
const pageChildren = currentPage.children;
|
|
2036
2212
|
let groupLeft = Infinity, groupTop = Infinity;
|
|
@@ -2121,8 +2297,7 @@ const useEditorStore = create((set, get) => ({
|
|
|
2121
2297
|
const dt = target.top - cur.top;
|
|
2122
2298
|
return updateNodeInTree(t, nodeId, { left: dl, top: dt });
|
|
2123
2299
|
};
|
|
2124
|
-
const
|
|
2125
|
-
const promotionOrder = insertReversed ? group.children.map((_, i) => group.children.length - 1 - i) : group.children.map((_, i) => i);
|
|
2300
|
+
const promotionOrder = group.children.map((_, i) => i);
|
|
2126
2301
|
for (let slot = 0; slot < promotionOrder.length; slot++) {
|
|
2127
2302
|
const i = promotionOrder[slot];
|
|
2128
2303
|
const child = group.children[i];
|
|
@@ -2166,6 +2341,18 @@ const useEditorStore = create((set, get) => ({
|
|
|
2166
2341
|
}
|
|
2167
2342
|
return { collapsedGroups: newCollapsedSet };
|
|
2168
2343
|
}),
|
|
2344
|
+
revealLayerNode: (id) => set((state) => {
|
|
2345
|
+
if (!id) return { revealedLayerId: null };
|
|
2346
|
+
const currentPage = getCurrentPageFromCanvas(state.canvas);
|
|
2347
|
+
const next = new Set(state.collapsedGroups);
|
|
2348
|
+
let parent = findParentGroup(currentPage.children, id);
|
|
2349
|
+
let guard = 0;
|
|
2350
|
+
while (parent && guard++ < 32) {
|
|
2351
|
+
next.delete(parent.id);
|
|
2352
|
+
parent = findParentGroup(currentPage.children, parent.id);
|
|
2353
|
+
}
|
|
2354
|
+
return { collapsedGroups: next, revealedLayerId: id };
|
|
2355
|
+
}),
|
|
2169
2356
|
// Convenience aliases
|
|
2170
2357
|
groupElements: (ids, name) => get().groupNodes(ids, name),
|
|
2171
2358
|
ungroupElements: (groupId) => get().ungroupNodes(groupId),
|
|
@@ -2612,7 +2799,7 @@ const useEditorStore = create((set, get) => ({
|
|
|
2612
2799
|
boundFormDefId: config.boundFormDefId,
|
|
2613
2800
|
boundFormDefName: config.boundFormDefName,
|
|
2614
2801
|
themeConfig: config.themeConfig ?? void 0,
|
|
2615
|
-
pdfTextMode: config.pdfTextMode ?? "
|
|
2802
|
+
pdfTextMode: config.pdfTextMode ?? "auto"
|
|
2616
2803
|
};
|
|
2617
2804
|
const committed = commitFromState(state, nextCanvas);
|
|
2618
2805
|
const out = {
|
|
@@ -4218,6 +4405,9 @@ async function loadSvgAsGroup(url) {
|
|
|
4218
4405
|
obj.fill = "#000";
|
|
4219
4406
|
obj.stroke = null;
|
|
4220
4407
|
obj.strokeWidth = 0;
|
|
4408
|
+
obj.objectCaching = false;
|
|
4409
|
+
obj.statefullCache = false;
|
|
4410
|
+
obj.noScaleCache = true;
|
|
4221
4411
|
}
|
|
4222
4412
|
const group = new fabric.Group(objects, {
|
|
4223
4413
|
originX: "center",
|
|
@@ -4225,8 +4415,14 @@ async function loadSvgAsGroup(url) {
|
|
|
4225
4415
|
selectable: false,
|
|
4226
4416
|
evented: false,
|
|
4227
4417
|
hasControls: false,
|
|
4228
|
-
hasBorders: false
|
|
4418
|
+
hasBorders: false,
|
|
4419
|
+
// Do NOT cache the mask group — Fabric would otherwise bake it to a
|
|
4420
|
+
// bitmap at the group's natural size, so the clipPath edges look soft
|
|
4421
|
+
// / pixelated whenever the host image is scaled up on the canvas.
|
|
4422
|
+
objectCaching: false
|
|
4229
4423
|
});
|
|
4424
|
+
group.statefullCache = false;
|
|
4425
|
+
group.noScaleCache = true;
|
|
4230
4426
|
const viewBoxW = Number(options.width) || group.width || 1;
|
|
4231
4427
|
const viewBoxH = Number(options.height) || group.height || 1;
|
|
4232
4428
|
return { group, viewBoxW, viewBoxH };
|
|
@@ -4244,8 +4440,18 @@ function fitMaskGroupToFrame(maskGroup, frameW, frameH) {
|
|
|
4244
4440
|
selectable: false,
|
|
4245
4441
|
evented: false,
|
|
4246
4442
|
hasControls: false,
|
|
4247
|
-
hasBorders: false
|
|
4443
|
+
hasBorders: false,
|
|
4444
|
+
objectCaching: false
|
|
4248
4445
|
});
|
|
4446
|
+
const stack = [maskGroup];
|
|
4447
|
+
while (stack.length) {
|
|
4448
|
+
const node = stack.pop();
|
|
4449
|
+
node.objectCaching = false;
|
|
4450
|
+
node.statefullCache = false;
|
|
4451
|
+
node.noScaleCache = true;
|
|
4452
|
+
const kids = node._objects;
|
|
4453
|
+
if (kids && kids.length) stack.push(...kids);
|
|
4454
|
+
}
|
|
4249
4455
|
maskGroup.absolutePositioned = false;
|
|
4250
4456
|
maskGroup.excludeFromExport = true;
|
|
4251
4457
|
maskGroup.inverted = false;
|
|
@@ -4368,7 +4574,7 @@ async function buildLuminanceAlphaCanvas(svgUrl, frameW, frameH) {
|
|
|
4368
4574
|
const b = px[i + 2];
|
|
4369
4575
|
const a = px[i + 3];
|
|
4370
4576
|
const lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
4371
|
-
const alpha = lum / 255 * a;
|
|
4577
|
+
const alpha = (255 - lum) / 255 * a;
|
|
4372
4578
|
px[i] = 255;
|
|
4373
4579
|
px[i + 1] = 255;
|
|
4374
4580
|
px[i + 2] = 255;
|
|
@@ -5932,10 +6138,6 @@ const shouldShowOriginalTextBounds = () => {
|
|
|
5932
6138
|
return false;
|
|
5933
6139
|
}
|
|
5934
6140
|
};
|
|
5935
|
-
const hasActiveTextPathDescendant = (obj) => {
|
|
5936
|
-
const kids = (obj == null ? void 0 : obj._objects) || [];
|
|
5937
|
-
return kids.some((child) => hasActiveTextPath(child) || hasActiveTextPathDescendant(child));
|
|
5938
|
-
};
|
|
5939
6141
|
function applyWarpFillStyle(ctx, obj) {
|
|
5940
6142
|
const filler = obj.fill;
|
|
5941
6143
|
if (filler && typeof filler === "object" && Array.isArray(filler.colorStops) && filler.coords) {
|
|
@@ -6128,6 +6330,79 @@ function applyTextPathControls(textbox) {
|
|
|
6128
6330
|
obj.controls = { ...defaultControls };
|
|
6129
6331
|
const halfWOf = (t) => (t.width || 0) / 2;
|
|
6130
6332
|
const halfHOf = (t) => (t.height || 0) / 2;
|
|
6333
|
+
{
|
|
6334
|
+
const cornerLayout = {
|
|
6335
|
+
tl: { sx: -1, sy: -1 },
|
|
6336
|
+
tr: { sx: 1, sy: -1 },
|
|
6337
|
+
br: { sx: 1, sy: 1 },
|
|
6338
|
+
bl: { sx: -1, sy: 1 },
|
|
6339
|
+
mt: { sx: 0, sy: -1 },
|
|
6340
|
+
mb: { sx: 0, sy: 1 },
|
|
6341
|
+
ml: { sx: -1, sy: 0 },
|
|
6342
|
+
mr: { sx: 1, sy: 0 }
|
|
6343
|
+
};
|
|
6344
|
+
for (const key of Object.keys(cornerLayout)) {
|
|
6345
|
+
const existing = obj.controls[key];
|
|
6346
|
+
if (!existing) continue;
|
|
6347
|
+
const { sx, sy } = cornerLayout[key];
|
|
6348
|
+
const customPosition = (_d2, finalMatrix, target) => {
|
|
6349
|
+
const t = target;
|
|
6350
|
+
const bounds = getTextPathHitBounds(t);
|
|
6351
|
+
if (!bounds) {
|
|
6352
|
+
return existing.positionHandler.call(existing, _d2, finalMatrix, target);
|
|
6353
|
+
}
|
|
6354
|
+
const cx = (bounds.minX + bounds.maxX) / 2;
|
|
6355
|
+
const cy = (bounds.minY + bounds.maxY) / 2;
|
|
6356
|
+
const x = sx < 0 ? bounds.minX : sx > 0 ? bounds.maxX : cx;
|
|
6357
|
+
const y = sy < 0 ? bounds.minY : sy > 0 ? bounds.maxY : cy;
|
|
6358
|
+
return scaleLocalToScreen(t, new fabric.Point(x, y)).transform(finalMatrix);
|
|
6359
|
+
};
|
|
6360
|
+
obj.controls[key] = new fabric.Control({
|
|
6361
|
+
x: existing.x,
|
|
6362
|
+
y: existing.y,
|
|
6363
|
+
offsetX: existing.offsetX,
|
|
6364
|
+
offsetY: existing.offsetY,
|
|
6365
|
+
cursorStyle: existing.cursorStyle,
|
|
6366
|
+
cursorStyleHandler: existing.cursorStyleHandler,
|
|
6367
|
+
actionName: existing.actionName,
|
|
6368
|
+
actionHandler: existing.actionHandler,
|
|
6369
|
+
mouseDownHandler: existing.mouseDownHandler,
|
|
6370
|
+
mouseUpHandler: existing.mouseUpHandler,
|
|
6371
|
+
getActionName: existing.getActionName,
|
|
6372
|
+
render: existing.render,
|
|
6373
|
+
sizeX: existing.sizeX,
|
|
6374
|
+
sizeY: existing.sizeY,
|
|
6375
|
+
touchSizeX: existing.touchSizeX,
|
|
6376
|
+
touchSizeY: existing.touchSizeY,
|
|
6377
|
+
withConnection: existing.withConnection,
|
|
6378
|
+
positionHandler: customPosition
|
|
6379
|
+
});
|
|
6380
|
+
}
|
|
6381
|
+
const mtrExisting = obj.controls.mtr;
|
|
6382
|
+
if (mtrExisting) {
|
|
6383
|
+
const customMtrPosition = (_d2, finalMatrix, target) => {
|
|
6384
|
+
const t = target;
|
|
6385
|
+
const bounds = getTextPathHitBounds(t);
|
|
6386
|
+
if (!bounds) return mtrExisting.positionHandler.call(mtrExisting, _d2, finalMatrix, target);
|
|
6387
|
+
const cx = (bounds.minX + bounds.maxX) / 2;
|
|
6388
|
+
const offset = mtrExisting.offsetY ?? -40;
|
|
6389
|
+
return scaleLocalToScreen(t, new fabric.Point(cx, bounds.minY)).transform(finalMatrix).add(new fabric.Point(0, offset));
|
|
6390
|
+
};
|
|
6391
|
+
obj.controls.mtr = new fabric.Control({
|
|
6392
|
+
x: mtrExisting.x,
|
|
6393
|
+
y: mtrExisting.y,
|
|
6394
|
+
offsetX: mtrExisting.offsetX,
|
|
6395
|
+
offsetY: mtrExisting.offsetY,
|
|
6396
|
+
cursorStyle: mtrExisting.cursorStyle,
|
|
6397
|
+
cursorStyleHandler: mtrExisting.cursorStyleHandler,
|
|
6398
|
+
actionName: mtrExisting.actionName,
|
|
6399
|
+
actionHandler: mtrExisting.actionHandler,
|
|
6400
|
+
render: mtrExisting.render,
|
|
6401
|
+
withConnection: mtrExisting.withConnection,
|
|
6402
|
+
positionHandler: customMtrPosition
|
|
6403
|
+
});
|
|
6404
|
+
}
|
|
6405
|
+
}
|
|
6131
6406
|
const renderPivot = (ctx, left, top) => {
|
|
6132
6407
|
ctx.save();
|
|
6133
6408
|
ctx.translate(left, top);
|
|
@@ -6749,10 +7024,11 @@ if (typeof TextboxProto._renderControls === "function" && !TextboxProto.__pixldo
|
|
|
6749
7024
|
if (!hostCanvas) return;
|
|
6750
7025
|
const hoverBounds = getTextPathHitBounds(this);
|
|
6751
7026
|
const active = (_d = hostCanvas.getActiveObject) == null ? void 0 : _d.call(hostCanvas);
|
|
6752
|
-
const
|
|
6753
|
-
if (hoverBounds && (this.__pdTextPathHovered ||
|
|
7027
|
+
const isDirectlyActive = active === this;
|
|
7028
|
+
if (hoverBounds && (this.__pdTextPathHovered || isDirectlyActive)) {
|
|
6754
7029
|
drawTextPathBounds(ctx, this, hoverBounds, hostCanvas);
|
|
6755
7030
|
}
|
|
7031
|
+
if (!isDirectlyActive) return;
|
|
6756
7032
|
const resolved = resolveTextPath(this.textPath, this.width || 0, this.fontSize || 16);
|
|
6757
7033
|
const path = resolved ? measurePath(resolved.d) : null;
|
|
6758
7034
|
if (!path) return;
|
|
@@ -6866,13 +7142,6 @@ if (typeof TextboxProto._renderControls === "function" && !TextboxProto.__pixldo
|
|
|
6866
7142
|
if (!showOrig) {
|
|
6867
7143
|
this.hasBorders = false;
|
|
6868
7144
|
this.borderColor = "rgba(0,0,0,0)";
|
|
6869
|
-
const filtered = {};
|
|
6870
|
-
for (const key of Object.keys(prevControls || {})) {
|
|
6871
|
-
if (key === "mtr" || key === "tpPivot" || key.startsWith("cr") || key.startsWith("rs") || key.startsWith("bz")) {
|
|
6872
|
-
filtered[key] = prevControls[key];
|
|
6873
|
-
}
|
|
6874
|
-
}
|
|
6875
|
-
this.controls = filtered;
|
|
6876
7145
|
}
|
|
6877
7146
|
try {
|
|
6878
7147
|
drawWarpGuides.call(this, ctx);
|
|
@@ -6983,26 +7252,7 @@ if (GroupProto && typeof GroupProto._renderControls === "function" && !GroupProt
|
|
|
6983
7252
|
const host = this.canvas;
|
|
6984
7253
|
const active = (_a2 = host == null ? void 0 : host.getActiveObject) == null ? void 0 : _a2.call(host);
|
|
6985
7254
|
const isActiveOrInActive = !!host && (active === this || !!active && typeof active.contains === "function" && active.contains(this, true));
|
|
6986
|
-
|
|
6987
|
-
const prevBorders = this.hasBorders;
|
|
6988
|
-
const prevControls = this.hasControls;
|
|
6989
|
-
const prevBorderColor = this.borderColor;
|
|
6990
|
-
if (hideWarpChildBounds) {
|
|
6991
|
-
this.hasBorders = false;
|
|
6992
|
-
this.hasControls = false;
|
|
6993
|
-
this.borderColor = "rgba(0,0,0,0)";
|
|
6994
|
-
styleOverride = { ...styleOverride || {}, hasBorders: false, hasControls: false, borderColor: "rgba(0,0,0,0)" };
|
|
6995
|
-
childrenOverride = { ...childrenOverride || {}, hasBorders: false, borderColor: "rgba(0,0,0,0)" };
|
|
6996
|
-
}
|
|
6997
|
-
try {
|
|
6998
|
-
GroupProto.__pixldocsOrigRenderControls.call(this, ctx, styleOverride, childrenOverride);
|
|
6999
|
-
} finally {
|
|
7000
|
-
if (hideWarpChildBounds) {
|
|
7001
|
-
this.hasBorders = prevBorders;
|
|
7002
|
-
this.hasControls = prevControls;
|
|
7003
|
-
this.borderColor = prevBorderColor;
|
|
7004
|
-
}
|
|
7005
|
-
}
|
|
7255
|
+
GroupProto.__pixldocsOrigRenderControls.call(this, ctx, styleOverride, childrenOverride);
|
|
7006
7256
|
if (!host || !isActiveOrInActive) return;
|
|
7007
7257
|
const drawForDescendants = (parent) => {
|
|
7008
7258
|
const kids = (parent == null ? void 0 : parent._objects) || [];
|
|
@@ -7027,17 +7277,12 @@ if (!TextboxProtoHit.__pixldocsOrigGetCoords && typeof TextboxProtoHit.getCoords
|
|
|
7027
7277
|
const bounds = getTextPathHitBounds(this);
|
|
7028
7278
|
if (!bounds) return TextboxProtoHit.__pixldocsOrigGetCoords.call(this);
|
|
7029
7279
|
const matrix = this.calcTransformMatrix();
|
|
7030
|
-
|
|
7280
|
+
return [
|
|
7031
7281
|
new fabric.Point(bounds.minX, bounds.minY),
|
|
7032
7282
|
new fabric.Point(bounds.maxX, bounds.minY),
|
|
7033
7283
|
new fabric.Point(bounds.maxX, bounds.maxY),
|
|
7034
7284
|
new fabric.Point(bounds.minX, bounds.maxY)
|
|
7035
7285
|
].map((p) => fabric.util.transformPoint(p, matrix));
|
|
7036
|
-
if (this.group) {
|
|
7037
|
-
const groupMatrix = this.group.calcTransformMatrix();
|
|
7038
|
-
return coords.map((p) => fabric.util.transformPoint(p, groupMatrix));
|
|
7039
|
-
}
|
|
7040
|
-
return coords;
|
|
7041
7286
|
};
|
|
7042
7287
|
}
|
|
7043
7288
|
if (!TextboxProtoHit.__pixldocsOrigContainsPoint && typeof TextboxProtoHit.containsPoint === "function") {
|
|
@@ -8546,7 +8791,7 @@ function createShape(element) {
|
|
|
8546
8791
|
}
|
|
8547
8792
|
}
|
|
8548
8793
|
function createText(element) {
|
|
8549
|
-
var _a2, _b, _c;
|
|
8794
|
+
var _a2, _b, _c, _d, _e;
|
|
8550
8795
|
const overflowPolicy = element.overflowPolicy || "grow-and-push";
|
|
8551
8796
|
let text = element.text || "Text";
|
|
8552
8797
|
let fontSize = element.fontSize || 16;
|
|
@@ -8694,6 +8939,23 @@ function createText(element) {
|
|
|
8694
8939
|
objectCaching: false,
|
|
8695
8940
|
noScaleCache: true,
|
|
8696
8941
|
splitByGrapheme,
|
|
8942
|
+
// Outline (stroke) support for text — kept in sync with PageCanvas
|
|
8943
|
+
// sync path. Only apply when BOTH a stroke color and positive width are
|
|
8944
|
+
// explicitly set; otherwise fabric defaults stroke to black and renders
|
|
8945
|
+
// an unwanted outline on existing text elements that carry a stray
|
|
8946
|
+
// strokeWidth (e.g. from PDF imports).
|
|
8947
|
+
...(() => {
|
|
8948
|
+
const s = element.stroke;
|
|
8949
|
+
const w = Number(element.strokeWidth) || 0;
|
|
8950
|
+
const has = !!s && w > 0;
|
|
8951
|
+
return has ? {
|
|
8952
|
+
stroke: s,
|
|
8953
|
+
strokeWidth: w,
|
|
8954
|
+
paintFirst: element.paintFirst || "fill",
|
|
8955
|
+
strokeUniform: true,
|
|
8956
|
+
strokeLineJoin: "round"
|
|
8957
|
+
} : { stroke: void 0, strokeWidth: 0 };
|
|
8958
|
+
})(),
|
|
8697
8959
|
// When inline markdown formatting is enabled, the displayed text is the
|
|
8698
8960
|
// PARSED plain text (markdown source lives separately on the element).
|
|
8699
8961
|
// Allowing canvas inline editing would let the user edit that plain text
|
|
@@ -8743,6 +9005,21 @@ function createText(element) {
|
|
|
8743
9005
|
});
|
|
8744
9006
|
} catch {
|
|
8745
9007
|
}
|
|
9008
|
+
try {
|
|
9009
|
+
const baseCtrls = (_d = (_c = fabric.Object) == null ? void 0 : _c.prototype) == null ? void 0 : _d.controls;
|
|
9010
|
+
if (baseCtrls) {
|
|
9011
|
+
textbox.controls = {
|
|
9012
|
+
...textbox.controls || {},
|
|
9013
|
+
tl: baseCtrls.tl,
|
|
9014
|
+
tr: baseCtrls.tr,
|
|
9015
|
+
bl: baseCtrls.bl,
|
|
9016
|
+
br: baseCtrls.br,
|
|
9017
|
+
mt: baseCtrls.mt,
|
|
9018
|
+
mb: baseCtrls.mb
|
|
9019
|
+
};
|
|
9020
|
+
}
|
|
9021
|
+
} catch {
|
|
9022
|
+
}
|
|
8746
9023
|
const scaleXAfterSet = textbox.scaleX ?? 1;
|
|
8747
9024
|
const scaleYAfterSet = textbox.scaleY ?? 1;
|
|
8748
9025
|
if (Math.abs(widthAfterSet - targetWidth) > 0.01 || Math.abs(scaleXAfterSet - targetScaleX) > 0.01 || Math.abs(scaleYAfterSet - targetScaleY) > 0.01) {
|
|
@@ -8773,7 +9050,7 @@ function createText(element) {
|
|
|
8773
9050
|
finalFontSize: fontSize,
|
|
8774
9051
|
textboxWidth: textbox.width,
|
|
8775
9052
|
textboxHeight: textbox.height,
|
|
8776
|
-
lineCount: ((
|
|
9053
|
+
lineCount: ((_e = textbox.textLines) == null ? void 0 : _e.length) || 0,
|
|
8777
9054
|
lines: (textbox.textLines || []).map((line) => Array.isArray(line) ? line.join("") : String(line ?? "")),
|
|
8778
9055
|
widthMetrics: getTextboxWidthFitMetrics(textbox, targetWidth)
|
|
8779
9056
|
}));
|
|
@@ -9332,16 +9609,7 @@ function renderSmartElementToDataUri(type, props, width, height) {
|
|
|
9332
9609
|
if (!svg) return null;
|
|
9333
9610
|
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
9334
9611
|
}
|
|
9335
|
-
const KEY_SHOW_ORIG_TEXT_BOUNDS = "pixldocs:showOriginalTextBounds";
|
|
9336
9612
|
const EVT_SHOW_ORIG_TEXT_BOUNDS = "pixldocs:showOriginalTextBoundsChanged";
|
|
9337
|
-
function getShowOriginalTextBounds() {
|
|
9338
|
-
if (typeof window === "undefined") return false;
|
|
9339
|
-
try {
|
|
9340
|
-
return window.localStorage.getItem(KEY_SHOW_ORIG_TEXT_BOUNDS) === "1";
|
|
9341
|
-
} catch {
|
|
9342
|
-
return false;
|
|
9343
|
-
}
|
|
9344
|
-
}
|
|
9345
9613
|
function subscribeShowOriginalTextBounds(cb) {
|
|
9346
9614
|
const handler = (e) => cb(!!e.detail);
|
|
9347
9615
|
window.addEventListener(EVT_SHOW_ORIG_TEXT_BOUNDS, handler);
|
|
@@ -9495,31 +9763,12 @@ try {
|
|
|
9495
9763
|
console.warn("[PageCanvas] Failed to apply global selection defaults:", e);
|
|
9496
9764
|
}
|
|
9497
9765
|
function applyWarpAwareSelectionBorders(selection) {
|
|
9498
|
-
if (
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
}
|
|
9502
|
-
return;
|
|
9503
|
-
}
|
|
9504
|
-
const hasWarpedTextObject = (obj) => {
|
|
9505
|
-
if (obj instanceof fabric.Textbox) {
|
|
9506
|
-
const tp = obj.textPath;
|
|
9507
|
-
return !!(tp && tp.preset && tp.preset !== "none");
|
|
9508
|
-
}
|
|
9509
|
-
const children = obj._objects;
|
|
9510
|
-
return Array.isArray(children) && children.some((child) => hasWarpedTextObject(child));
|
|
9511
|
-
};
|
|
9512
|
-
const hasWarpedText = selection.getObjects().some((obj) => {
|
|
9513
|
-
if (!hasWarpedTextObject(obj)) return false;
|
|
9514
|
-
const tp = obj.textPath;
|
|
9515
|
-
return !tp || tp.preset !== "none";
|
|
9516
|
-
});
|
|
9517
|
-
if (hasWarpedText) {
|
|
9518
|
-
if (selection.__pixldocsOrigASHasBorders === void 0) {
|
|
9519
|
-
selection.__pixldocsOrigASHasBorders = selection.hasBorders;
|
|
9520
|
-
}
|
|
9521
|
-
selection.hasBorders = false;
|
|
9766
|
+
if (selection.__pixldocsOrigASHasBorders !== void 0) {
|
|
9767
|
+
selection.hasBorders = selection.__pixldocsOrigASHasBorders;
|
|
9768
|
+
delete selection.__pixldocsOrigASHasBorders;
|
|
9522
9769
|
}
|
|
9770
|
+
selection.hasBorders = true;
|
|
9771
|
+
selection.hasControls = true;
|
|
9523
9772
|
}
|
|
9524
9773
|
const PageCanvas = forwardRef(
|
|
9525
9774
|
({
|
|
@@ -9585,7 +9834,46 @@ const PageCanvas = forwardRef(
|
|
|
9585
9834
|
const [sizeLabel, setSizeLabel] = useState(null);
|
|
9586
9835
|
const [ready, setReady] = useState(false);
|
|
9587
9836
|
const [unlockRequestId, setUnlockRequestId] = useState(0);
|
|
9588
|
-
|
|
9837
|
+
const applyLogicalGroupSelectionVisualState = useCallback((selection, groupId) => {
|
|
9838
|
+
var _a2;
|
|
9839
|
+
selection.__pixldocsGroupSelection = groupId;
|
|
9840
|
+
delete selection.__pixldocsLogicalGroupIds;
|
|
9841
|
+
selection.hasBorders = true;
|
|
9842
|
+
const members = selection.getObjects();
|
|
9843
|
+
for (const prev of suppressGroupMemberBordersRef.current) {
|
|
9844
|
+
if (members.includes(prev)) continue;
|
|
9845
|
+
const origBorders = prev.__pixldocsOrigHasBorders;
|
|
9846
|
+
const origControls = prev.__pixldocsOrigHasControls;
|
|
9847
|
+
const origLockX = prev.__pixldocsOrigLockScalingX;
|
|
9848
|
+
if (origBorders !== void 0) prev.hasBorders = origBorders;
|
|
9849
|
+
if (origControls !== void 0) prev.hasControls = origControls;
|
|
9850
|
+
if (origLockX !== void 0) {
|
|
9851
|
+
prev.lockScalingX = origLockX;
|
|
9852
|
+
prev.lockScalingY = prev.__pixldocsOrigLockScalingY;
|
|
9853
|
+
}
|
|
9854
|
+
delete prev.__pixldocsOrigHasBorders;
|
|
9855
|
+
delete prev.__pixldocsOrigHasControls;
|
|
9856
|
+
delete prev.__pixldocsOrigLockScalingX;
|
|
9857
|
+
delete prev.__pixldocsOrigLockScalingY;
|
|
9858
|
+
}
|
|
9859
|
+
suppressGroupMemberBordersRef.current = members;
|
|
9860
|
+
for (const m of members) {
|
|
9861
|
+
if (m.__pixldocsOrigHasBorders === void 0) m.__pixldocsOrigHasBorders = m.hasBorders;
|
|
9862
|
+
if (m.__pixldocsOrigHasControls === void 0) m.__pixldocsOrigHasControls = m.hasControls;
|
|
9863
|
+
m.hasBorders = false;
|
|
9864
|
+
m.hasControls = false;
|
|
9865
|
+
if (m.__cropGroup || ((_a2 = m._ct) == null ? void 0 : _a2.isCropGroup)) {
|
|
9866
|
+
if (m.__pixldocsOrigLockScalingX === void 0) {
|
|
9867
|
+
m.__pixldocsOrigLockScalingX = m.lockScalingX;
|
|
9868
|
+
m.__pixldocsOrigLockScalingY = m.lockScalingY;
|
|
9869
|
+
}
|
|
9870
|
+
m.lockScalingX = false;
|
|
9871
|
+
m.lockScalingY = false;
|
|
9872
|
+
}
|
|
9873
|
+
}
|
|
9874
|
+
applyWarpAwareSelectionBorders(selection);
|
|
9875
|
+
}, []);
|
|
9876
|
+
const pageBoundsOptions = useMemo(
|
|
9589
9877
|
() => ({ pageContentWidth: canvasWidth, pageContentHeight: canvasHeight }),
|
|
9590
9878
|
[canvasWidth, canvasHeight]
|
|
9591
9879
|
);
|
|
@@ -9595,7 +9883,9 @@ const PageCanvas = forwardRef(
|
|
|
9595
9883
|
const setGroupOverlayLiveBoundsRef = useRef(setGroupOverlayLiveBounds);
|
|
9596
9884
|
const skipSelectionClearOnDiscardRef = useRef(false);
|
|
9597
9885
|
const skipActiveSelectionBakeOnClearRef = useRef(false);
|
|
9886
|
+
const preserveEditingScopeOnSelectionClearRef = useRef(false);
|
|
9598
9887
|
const preserveActiveSelectionAfterTransformRef = useRef(null);
|
|
9888
|
+
const pendingGroupPromotionRef = useRef(null);
|
|
9599
9889
|
const imageReloadRequestSeqRef = useRef(/* @__PURE__ */ new Map());
|
|
9600
9890
|
useRef(null);
|
|
9601
9891
|
const groupBoundsResizingRef = useRef(false);
|
|
@@ -9615,6 +9905,7 @@ const PageCanvas = forwardRef(
|
|
|
9615
9905
|
const lastResizeScaleTargetRef = useRef(null);
|
|
9616
9906
|
const preserveSelectionAfterTransformIdRef = useRef(null);
|
|
9617
9907
|
const groupSelectionTransformStartRef = useRef(null);
|
|
9908
|
+
const activeSelectionMoveStartRef = useRef(null);
|
|
9618
9909
|
setGroupOverlayLiveBoundsRef.current = setGroupOverlayLiveBounds;
|
|
9619
9910
|
const {
|
|
9620
9911
|
selectElements,
|
|
@@ -9635,7 +9926,11 @@ const PageCanvas = forwardRef(
|
|
|
9635
9926
|
if (!currentPage || ids.length === 0) return null;
|
|
9636
9927
|
for (const id of ids) {
|
|
9637
9928
|
const node = findNodeById(children, id);
|
|
9638
|
-
if (node && isGroup(node))
|
|
9929
|
+
if (node && isGroup(node)) {
|
|
9930
|
+
const memberIds2 = new Set(getAllElementIds(node.children ?? []));
|
|
9931
|
+
const pureGroupOnly = ids.every((selectedId) => selectedId === node.id || memberIds2.has(selectedId));
|
|
9932
|
+
return pureGroupOnly ? node : null;
|
|
9933
|
+
}
|
|
9639
9934
|
}
|
|
9640
9935
|
const firstId = ids[0];
|
|
9641
9936
|
const parent = findParentGroup(children, firstId);
|
|
@@ -9989,6 +10284,16 @@ const PageCanvas = forwardRef(
|
|
|
9989
10284
|
fabricCanvas.__isUserTransforming = false;
|
|
9990
10285
|
fabricCanvas.on("mouse:down", () => {
|
|
9991
10286
|
groupSelectionTransformStartRef.current = null;
|
|
10287
|
+
activeSelectionMoveStartRef.current = null;
|
|
10288
|
+
const active = fabricCanvas.getActiveObject();
|
|
10289
|
+
if (active instanceof fabric.ActiveSelection) {
|
|
10290
|
+
const rect = active.getBoundingRect();
|
|
10291
|
+
activeSelectionMoveStartRef.current = {
|
|
10292
|
+
selection: active,
|
|
10293
|
+
selectionLeft: rect.left,
|
|
10294
|
+
selectionTop: rect.top
|
|
10295
|
+
};
|
|
10296
|
+
}
|
|
9992
10297
|
if (fabricCanvas._currentTransform) {
|
|
9993
10298
|
fabricCanvas.__isUserTransforming = true;
|
|
9994
10299
|
}
|
|
@@ -10041,8 +10346,21 @@ const PageCanvas = forwardRef(
|
|
|
10041
10346
|
didTransformRef.current = true;
|
|
10042
10347
|
});
|
|
10043
10348
|
const syncSelectionToStore = () => {
|
|
10044
|
-
var _a2, _b, _c, _d
|
|
10349
|
+
var _a2, _b, _c, _d;
|
|
10045
10350
|
if (!isActiveRef.current || isRebuildingRef.current || isSyncingSelectionToFabricRef.current || !allowSelection) return;
|
|
10351
|
+
const walkToTopmostGroup = (childId, children, activeEditingGroupId) => {
|
|
10352
|
+
let topmost = null;
|
|
10353
|
+
let currentId = childId;
|
|
10354
|
+
for (let i = 0; i < 32; i++) {
|
|
10355
|
+
const p = findParentGroup(children, currentId);
|
|
10356
|
+
if (!p) break;
|
|
10357
|
+
if (p.backgroundColor) break;
|
|
10358
|
+
if (activeEditingGroupId && p.id === activeEditingGroupId) break;
|
|
10359
|
+
topmost = p;
|
|
10360
|
+
currentId = p.id;
|
|
10361
|
+
}
|
|
10362
|
+
return topmost;
|
|
10363
|
+
};
|
|
10046
10364
|
const active = fabricCanvas.getActiveObject();
|
|
10047
10365
|
let ids = fabricCanvas.getActiveObjects().map((o) => getObjectId(o)).filter((id) => !!id && id !== "__background__");
|
|
10048
10366
|
if (ids.length === 1 && active && active instanceof fabric.Group && active.__docuforgeSectionGroup) {
|
|
@@ -10069,8 +10387,8 @@ const PageCanvas = forwardRef(
|
|
|
10069
10387
|
const state = useEditorStore.getState();
|
|
10070
10388
|
const currentPage2 = (_b = state.canvas.pages) == null ? void 0 : _b.find((p) => p.id === pageId);
|
|
10071
10389
|
const children = (currentPage2 == null ? void 0 : currentPage2.children) ?? [];
|
|
10072
|
-
const parent =
|
|
10073
|
-
const targetIsInCrop = !!(
|
|
10390
|
+
const parent = walkToTopmostGroup(clickedId, children, activeEditingGroupId);
|
|
10391
|
+
const targetIsInCrop = !!(active instanceof fabric.Group && isCropGroupInCropMode(active) || (active == null ? void 0 : active.group) instanceof fabric.Group && isCropGroupInCropMode(active.group));
|
|
10074
10392
|
if (parent && !targetIsInCrop && activeEditingGroupId !== parent.id && !(active && active instanceof fabric.Group && active.__docuforgeSectionGroup)) {
|
|
10075
10393
|
const memberIdSet = new Set(getAllElementIds(parent.children ?? []));
|
|
10076
10394
|
const memberObjs = fabricCanvas.getObjects().filter((o) => {
|
|
@@ -10095,9 +10413,75 @@ const PageCanvas = forwardRef(
|
|
|
10095
10413
|
selectElements(ids, false, false);
|
|
10096
10414
|
return;
|
|
10097
10415
|
}
|
|
10416
|
+
if (ids.length > 1 && !(active instanceof fabric.ActiveSelection && active.__pixldocsGroupSelection)) {
|
|
10417
|
+
const state = useEditorStore.getState();
|
|
10418
|
+
const currentPage2 = (_c = state.canvas.pages) == null ? void 0 : _c.find((p) => p.id === pageId);
|
|
10419
|
+
const children = (currentPage2 == null ? void 0 : currentPage2.children) ?? [];
|
|
10420
|
+
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
10421
|
+
const involvedGroupIds = /* @__PURE__ */ new Set();
|
|
10422
|
+
const standaloneIds = [];
|
|
10423
|
+
for (const id of ids) {
|
|
10424
|
+
const parent = walkToTopmostGroup(id, children, activeEditingGroupId);
|
|
10425
|
+
if (parent && activeEditingGroupId !== parent.id && !parent.backgroundColor) {
|
|
10426
|
+
involvedGroupIds.add(parent.id);
|
|
10427
|
+
} else {
|
|
10428
|
+
standaloneIds.push(id);
|
|
10429
|
+
}
|
|
10430
|
+
}
|
|
10431
|
+
if (involvedGroupIds.size > 0) {
|
|
10432
|
+
const wantIds = new Set(standaloneIds);
|
|
10433
|
+
const groupedMemberIds = /* @__PURE__ */ new Set();
|
|
10434
|
+
for (const gid of involvedGroupIds) {
|
|
10435
|
+
const g = findNodeById(children, gid);
|
|
10436
|
+
if (g && isGroup(g)) {
|
|
10437
|
+
for (const leafId of getAllElementIds(g.children ?? [])) {
|
|
10438
|
+
wantIds.add(leafId);
|
|
10439
|
+
groupedMemberIds.add(leafId);
|
|
10440
|
+
}
|
|
10441
|
+
}
|
|
10442
|
+
}
|
|
10443
|
+
const currentSet = new Set(ids);
|
|
10444
|
+
const needsExpand = wantIds.size !== currentSet.size || [...wantIds].some((id) => !currentSet.has(id));
|
|
10445
|
+
if (needsExpand) {
|
|
10446
|
+
const wantObjs = fabricCanvas.getObjects().filter((o) => {
|
|
10447
|
+
const oid = getObjectId(o);
|
|
10448
|
+
return !!oid && wantIds.has(oid);
|
|
10449
|
+
});
|
|
10450
|
+
if (wantObjs.length >= 2) {
|
|
10451
|
+
isSyncingSelectionToFabricRef.current = true;
|
|
10452
|
+
try {
|
|
10453
|
+
const sel = new fabric.ActiveSelection(wantObjs, { canvas: fabricCanvas });
|
|
10454
|
+
if (involvedGroupIds.size === 1 && standaloneIds.length === 0) {
|
|
10455
|
+
restoreGroupSelectionVisualState(sel, [...involvedGroupIds][0]);
|
|
10456
|
+
} else {
|
|
10457
|
+
markMixedLogicalSelection(sel, [...involvedGroupIds], groupedMemberIds);
|
|
10458
|
+
}
|
|
10459
|
+
fabricCanvas.setActiveObject(sel);
|
|
10460
|
+
fabricCanvas.requestRenderAll();
|
|
10461
|
+
} finally {
|
|
10462
|
+
isSyncingSelectionToFabricRef.current = false;
|
|
10463
|
+
}
|
|
10464
|
+
}
|
|
10465
|
+
} else {
|
|
10466
|
+
const currentActive = fabricCanvas.getActiveObject();
|
|
10467
|
+
if (currentActive instanceof fabric.ActiveSelection) {
|
|
10468
|
+
if (involvedGroupIds.size === 1 && standaloneIds.length === 0) {
|
|
10469
|
+
restoreGroupSelectionVisualState(currentActive, [...involvedGroupIds][0]);
|
|
10470
|
+
} else {
|
|
10471
|
+
markMixedLogicalSelection(currentActive, [...involvedGroupIds], groupedMemberIds);
|
|
10472
|
+
}
|
|
10473
|
+
currentActive.setCoords();
|
|
10474
|
+
fabricCanvas.requestRenderAll();
|
|
10475
|
+
}
|
|
10476
|
+
}
|
|
10477
|
+
const storeIds = [...involvedGroupIds, ...standaloneIds];
|
|
10478
|
+
selectElements(storeIds, false, false);
|
|
10479
|
+
return;
|
|
10480
|
+
}
|
|
10481
|
+
}
|
|
10098
10482
|
if (ids.length > 1) {
|
|
10099
10483
|
const state = useEditorStore.getState();
|
|
10100
|
-
const currentPage2 = (
|
|
10484
|
+
const currentPage2 = (_d = state.canvas.pages) == null ? void 0 : _d.find((p) => p.id === pageId);
|
|
10101
10485
|
const children = (currentPage2 == null ? void 0 : currentPage2.children) ?? [];
|
|
10102
10486
|
const currentSelectedIds = state.canvas.selectedIds ?? [];
|
|
10103
10487
|
for (const sid of currentSelectedIds) {
|
|
@@ -10125,6 +10509,20 @@ const PageCanvas = forwardRef(
|
|
|
10125
10509
|
} else {
|
|
10126
10510
|
m.hasBorders = true;
|
|
10127
10511
|
}
|
|
10512
|
+
const origControls = m.__pixldocsOrigHasControls;
|
|
10513
|
+
if (origControls !== void 0) {
|
|
10514
|
+
m.hasControls = origControls;
|
|
10515
|
+
delete m.__pixldocsOrigHasControls;
|
|
10516
|
+
} else {
|
|
10517
|
+
m.hasControls = true;
|
|
10518
|
+
}
|
|
10519
|
+
const origLockX = m.__pixldocsOrigLockScalingX;
|
|
10520
|
+
if (origLockX !== void 0) {
|
|
10521
|
+
m.lockScalingX = origLockX;
|
|
10522
|
+
m.lockScalingY = m.__pixldocsOrigLockScalingY;
|
|
10523
|
+
delete m.__pixldocsOrigLockScalingX;
|
|
10524
|
+
delete m.__pixldocsOrigLockScalingY;
|
|
10525
|
+
}
|
|
10128
10526
|
}
|
|
10129
10527
|
suppressGroupMemberBordersRef.current = [];
|
|
10130
10528
|
};
|
|
@@ -10132,6 +10530,7 @@ const PageCanvas = forwardRef(
|
|
|
10132
10530
|
var _a2;
|
|
10133
10531
|
syncSelectionToStore();
|
|
10134
10532
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10533
|
+
if (activeObj instanceof fabric.ActiveSelection) applyWarpAwareSelectionBorders(activeObj);
|
|
10135
10534
|
if (activeObj) applyControlSizeForZoom(fabricCanvas, activeObj);
|
|
10136
10535
|
if (activeObj && !(activeObj instanceof fabric.ActiveSelection) && (((_a2 = activeObj._ct) == null ? void 0 : _a2.isCropGroup) || activeObj.__cropGroup)) {
|
|
10137
10536
|
installCanvaMaskControls(activeObj);
|
|
@@ -10140,10 +10539,11 @@ const PageCanvas = forwardRef(
|
|
|
10140
10539
|
fabricCanvas.on("selection:updated", () => {
|
|
10141
10540
|
var _a2;
|
|
10142
10541
|
const next = fabricCanvas.getActiveObject();
|
|
10143
|
-
const
|
|
10144
|
-
if (!
|
|
10542
|
+
const isLogicalGroupSel = next instanceof fabric.ActiveSelection && (next.__pixldocsGroupSelection || Array.isArray(next.__pixldocsLogicalGroupIds));
|
|
10543
|
+
if (!isLogicalGroupSel) restoreSuppressedGroupBorders();
|
|
10145
10544
|
syncSelectionToStore();
|
|
10146
10545
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10546
|
+
if (activeObj instanceof fabric.ActiveSelection) applyWarpAwareSelectionBorders(activeObj);
|
|
10147
10547
|
if (activeObj) applyControlSizeForZoom(fabricCanvas, activeObj);
|
|
10148
10548
|
if (activeObj && !(activeObj instanceof fabric.ActiveSelection) && (((_a2 = activeObj._ct) == null ? void 0 : _a2.isCropGroup) || activeObj.__cropGroup)) {
|
|
10149
10549
|
installCanvaMaskControls(activeObj);
|
|
@@ -10176,24 +10576,83 @@ const PageCanvas = forwardRef(
|
|
|
10176
10576
|
const stateNow = useEditorStore.getState();
|
|
10177
10577
|
const pageNow = (_b = stateNow.canvas.pages) == null ? void 0 : _b.find((p) => p.id === pageId);
|
|
10178
10578
|
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
10179
|
-
const
|
|
10180
|
-
|
|
10181
|
-
|
|
10579
|
+
const chain = [];
|
|
10580
|
+
{
|
|
10581
|
+
let currId = childId;
|
|
10582
|
+
for (let i = 0; i < 32; i++) {
|
|
10583
|
+
const p = findParentGroup(childrenNow, currId);
|
|
10584
|
+
if (!p) break;
|
|
10585
|
+
if (p.backgroundColor) break;
|
|
10586
|
+
chain.push(p);
|
|
10587
|
+
currId = p.id;
|
|
10588
|
+
}
|
|
10589
|
+
}
|
|
10590
|
+
if (chain.length === 0) return;
|
|
10591
|
+
const currentScopeId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
10592
|
+
let scopeIdx = chain.length;
|
|
10593
|
+
if (currentScopeId) {
|
|
10594
|
+
const idx = chain.findIndex((g) => g.id === currentScopeId);
|
|
10595
|
+
if (idx >= 0) scopeIdx = idx;
|
|
10596
|
+
}
|
|
10597
|
+
const entryIdx = scopeIdx - 1;
|
|
10598
|
+
if (entryIdx < 0) return;
|
|
10599
|
+
const newScopeGroup = chain[entryIdx];
|
|
10600
|
+
const selectionIdx = entryIdx - 1;
|
|
10601
|
+
const selectInnerObject = (obj) => {
|
|
10602
|
+
delete obj.__pixldocsGroupSelection;
|
|
10603
|
+
delete obj.__pixldocsLogicalGroupIds;
|
|
10604
|
+
obj.set({ selectable: true, evented: true, hasBorders: true, hasControls: true });
|
|
10605
|
+
fabricCanvas.setActiveObject(obj);
|
|
10606
|
+
obj.setCoords();
|
|
10607
|
+
};
|
|
10608
|
+
pendingGroupPromotionRef.current = null;
|
|
10182
10609
|
isSyncingSelectionToFabricRef.current = true;
|
|
10183
10610
|
try {
|
|
10611
|
+
skipSelectionClearOnDiscardRef.current = true;
|
|
10612
|
+
preserveEditingScopeOnSelectionClearRef.current = true;
|
|
10184
10613
|
fabricCanvas.discardActiveObject();
|
|
10185
|
-
|
|
10186
|
-
|
|
10614
|
+
skipSelectionClearOnDiscardRef.current = false;
|
|
10615
|
+
preserveEditingScopeOnSelectionClearRef.current = false;
|
|
10616
|
+
restoreSuppressedGroupBorders();
|
|
10617
|
+
fabricCanvas.__activeEditingGroupId = newScopeGroup.id;
|
|
10618
|
+
if (selectionIdx < 0) {
|
|
10619
|
+
selectInnerObject(hitChild);
|
|
10620
|
+
fabricCanvas.requestRenderAll();
|
|
10621
|
+
} else {
|
|
10622
|
+
const subgroup = chain[selectionIdx];
|
|
10623
|
+
const memberIds = new Set(getAllElementIds(subgroup.children ?? []));
|
|
10624
|
+
const memberObjs = fabricCanvas.getObjects().filter((o) => {
|
|
10625
|
+
const oid = getObjectId(o);
|
|
10626
|
+
return !!oid && memberIds.has(oid);
|
|
10627
|
+
});
|
|
10628
|
+
if (memberObjs.length > 1) {
|
|
10629
|
+
const selection = new fabric.ActiveSelection(memberObjs, { canvas: fabricCanvas });
|
|
10630
|
+
restoreGroupSelectionVisualState(selection, subgroup.id);
|
|
10631
|
+
fabricCanvas.setActiveObject(selection);
|
|
10632
|
+
selection.setCoords();
|
|
10633
|
+
} else if (memberObjs.length === 1) {
|
|
10634
|
+
const only = memberObjs[0];
|
|
10635
|
+
selectInnerObject(only);
|
|
10636
|
+
} else {
|
|
10637
|
+
selectInnerObject(hitChild);
|
|
10638
|
+
}
|
|
10639
|
+
fabricCanvas.requestRenderAll();
|
|
10640
|
+
}
|
|
10187
10641
|
} finally {
|
|
10642
|
+
skipSelectionClearOnDiscardRef.current = false;
|
|
10643
|
+
preserveEditingScopeOnSelectionClearRef.current = false;
|
|
10188
10644
|
isSyncingSelectionToFabricRef.current = false;
|
|
10189
10645
|
}
|
|
10190
|
-
|
|
10646
|
+
const selectedId = selectionIdx < 0 ? childId : chain[selectionIdx].id;
|
|
10647
|
+
selectElements([selectedId], false, false);
|
|
10191
10648
|
});
|
|
10192
10649
|
fabricCanvas.on("selection:cleared", () => {
|
|
10193
10650
|
if (!isActiveRef.current || isRebuildingRef.current || !allowSelection) return;
|
|
10194
10651
|
setGroupOverlayLiveBoundsRef.current(null);
|
|
10195
10652
|
groupBoundsResizingRef.current = false;
|
|
10196
|
-
|
|
10653
|
+
if (!preserveEditingScopeOnSelectionClearRef.current) {
|
|
10654
|
+
fabricCanvas.__activeEditingGroupId = null;
|
|
10655
|
+
}
|
|
10197
10656
|
const preservedGroupSelection = preserveActiveSelectionAfterTransformRef.current;
|
|
10198
10657
|
const shouldRestoreGroupSelection = !!((preservedGroupSelection == null ? void 0 : preservedGroupSelection.groupSelectionId) && (!preservedGroupSelection.expiresAt || preservedGroupSelection.expiresAt > Date.now()));
|
|
10199
10658
|
if (skipSelectionClearOnDiscardRef.current) {
|
|
@@ -10245,6 +10704,14 @@ const PageCanvas = forwardRef(
|
|
|
10245
10704
|
var _a2, _b;
|
|
10246
10705
|
const active = target instanceof fabric.ActiveSelection ? target : fabricCanvas.getActiveObject();
|
|
10247
10706
|
if (!(active instanceof fabric.ActiveSelection)) return;
|
|
10707
|
+
if (!activeSelectionMoveStartRef.current || activeSelectionMoveStartRef.current.selection !== active) {
|
|
10708
|
+
const rect2 = active.getBoundingRect();
|
|
10709
|
+
activeSelectionMoveStartRef.current = {
|
|
10710
|
+
selection: active,
|
|
10711
|
+
selectionLeft: rect2.left,
|
|
10712
|
+
selectionTop: rect2.top
|
|
10713
|
+
};
|
|
10714
|
+
}
|
|
10248
10715
|
const groupId = active.__pixldocsGroupSelection;
|
|
10249
10716
|
if (!groupId) return;
|
|
10250
10717
|
if (((_a2 = groupSelectionTransformStartRef.current) == null ? void 0 : _a2.groupId) === groupId && groupSelectionTransformStartRef.current.selection === active) return;
|
|
@@ -10263,16 +10730,123 @@ const PageCanvas = forwardRef(
|
|
|
10263
10730
|
};
|
|
10264
10731
|
};
|
|
10265
10732
|
const restoreGroupSelectionVisualState = (selection, groupId) => {
|
|
10266
|
-
selection
|
|
10267
|
-
|
|
10733
|
+
applyLogicalGroupSelectionVisualState(selection, groupId);
|
|
10734
|
+
};
|
|
10735
|
+
const suppressBordersForObjects = (members) => {
|
|
10736
|
+
var _a2;
|
|
10737
|
+
for (const prev of suppressGroupMemberBordersRef.current) {
|
|
10738
|
+
if (members.includes(prev)) continue;
|
|
10739
|
+
const orig = prev.__pixldocsOrigHasBorders;
|
|
10740
|
+
if (orig !== void 0) {
|
|
10741
|
+
prev.hasBorders = orig;
|
|
10742
|
+
delete prev.__pixldocsOrigHasBorders;
|
|
10743
|
+
} else {
|
|
10744
|
+
prev.hasBorders = true;
|
|
10745
|
+
}
|
|
10746
|
+
const origControls = prev.__pixldocsOrigHasControls;
|
|
10747
|
+
if (origControls !== void 0) {
|
|
10748
|
+
prev.hasControls = origControls;
|
|
10749
|
+
delete prev.__pixldocsOrigHasControls;
|
|
10750
|
+
} else {
|
|
10751
|
+
prev.hasControls = true;
|
|
10752
|
+
}
|
|
10753
|
+
const origLockX = prev.__pixldocsOrigLockScalingX;
|
|
10754
|
+
if (origLockX !== void 0) {
|
|
10755
|
+
prev.lockScalingX = origLockX;
|
|
10756
|
+
prev.lockScalingY = prev.__pixldocsOrigLockScalingY;
|
|
10757
|
+
delete prev.__pixldocsOrigLockScalingX;
|
|
10758
|
+
delete prev.__pixldocsOrigLockScalingY;
|
|
10759
|
+
}
|
|
10760
|
+
}
|
|
10268
10761
|
suppressGroupMemberBordersRef.current = members;
|
|
10269
10762
|
for (const m of members) {
|
|
10270
10763
|
if (m.__pixldocsOrigHasBorders === void 0) {
|
|
10271
10764
|
m.__pixldocsOrigHasBorders = m.hasBorders;
|
|
10272
10765
|
}
|
|
10766
|
+
if (m.__pixldocsOrigHasControls === void 0) {
|
|
10767
|
+
m.__pixldocsOrigHasControls = m.hasControls;
|
|
10768
|
+
}
|
|
10273
10769
|
m.hasBorders = false;
|
|
10770
|
+
m.hasControls = false;
|
|
10771
|
+
if (m.__cropGroup || ((_a2 = m._ct) == null ? void 0 : _a2.isCropGroup)) {
|
|
10772
|
+
if (m.__pixldocsOrigLockScalingX === void 0) {
|
|
10773
|
+
m.__pixldocsOrigLockScalingX = m.lockScalingX;
|
|
10774
|
+
m.__pixldocsOrigLockScalingY = m.lockScalingY;
|
|
10775
|
+
}
|
|
10776
|
+
m.lockScalingX = false;
|
|
10777
|
+
m.lockScalingY = false;
|
|
10778
|
+
}
|
|
10274
10779
|
}
|
|
10275
10780
|
};
|
|
10781
|
+
const isMultiSelectModifier = (event) => !!((event == null ? void 0 : event.shiftKey) || (event == null ? void 0 : event.metaKey) || (event == null ? void 0 : event.ctrlKey));
|
|
10782
|
+
const pickSelectableObjectAtPointer = (event) => {
|
|
10783
|
+
var _a2;
|
|
10784
|
+
try {
|
|
10785
|
+
const pointer = fabricCanvas.getViewportPoint(event);
|
|
10786
|
+
const objects = fabricCanvas.getObjects();
|
|
10787
|
+
for (let i = objects.length - 1; i >= 0; i--) {
|
|
10788
|
+
const obj = objects[i];
|
|
10789
|
+
const id = getObjectId(obj);
|
|
10790
|
+
if (!id || id === "__background__" || !obj.selectable || !obj.evented || obj.visible === false) continue;
|
|
10791
|
+
const controlHit = (_a2 = obj.findControl) == null ? void 0 : _a2.call(obj, pointer);
|
|
10792
|
+
if (controlHit) continue;
|
|
10793
|
+
if (typeof obj.containsPoint === "function" && obj.containsPoint(pointer)) return obj;
|
|
10794
|
+
}
|
|
10795
|
+
} catch {
|
|
10796
|
+
return null;
|
|
10797
|
+
}
|
|
10798
|
+
return null;
|
|
10799
|
+
};
|
|
10800
|
+
let pendingShiftMultiSelect = null;
|
|
10801
|
+
const applyShiftMultiSelect = (target, event, baselineActive = fabricCanvas.getActiveObject(), baselineObjects = fabricCanvas.getActiveObjects()) => {
|
|
10802
|
+
var _a2, _b, _c;
|
|
10803
|
+
if (!target || !target.selectable) return false;
|
|
10804
|
+
const active = baselineActive;
|
|
10805
|
+
if (!active || ((_a2 = active.getActiveControl) == null ? void 0 : _a2.call(active))) return false;
|
|
10806
|
+
if (active === target && !(active instanceof fabric.ActiveSelection)) return false;
|
|
10807
|
+
isSyncingSelectionToFabricRef.current = true;
|
|
10808
|
+
try {
|
|
10809
|
+
let nextObjects;
|
|
10810
|
+
if (active instanceof fabric.ActiveSelection) {
|
|
10811
|
+
const current = baselineObjects.length ? baselineObjects : active.getObjects();
|
|
10812
|
+
nextObjects = current.includes(target) ? current.filter((obj) => obj !== target) : [...current, target];
|
|
10813
|
+
} else {
|
|
10814
|
+
nextObjects = [active, target];
|
|
10815
|
+
}
|
|
10816
|
+
nextObjects = nextObjects.filter((obj, index, arr) => arr.indexOf(obj) === index && fabricCanvas.getObjects().includes(obj));
|
|
10817
|
+
if (nextObjects.length > 1) {
|
|
10818
|
+
const selection = new fabric.ActiveSelection(nextObjects, { canvas: fabricCanvas });
|
|
10819
|
+
applyWarpAwareSelectionBorders(selection);
|
|
10820
|
+
fabricCanvas.setActiveObject(selection);
|
|
10821
|
+
selection.setCoords();
|
|
10822
|
+
isSyncingSelectionToFabricRef.current = false;
|
|
10823
|
+
syncSelectionToStore();
|
|
10824
|
+
} else if (nextObjects.length === 1) {
|
|
10825
|
+
fabricCanvas.setActiveObject(nextObjects[0]);
|
|
10826
|
+
nextObjects[0].setCoords();
|
|
10827
|
+
const onlyId = getObjectId(nextObjects[0]);
|
|
10828
|
+
if (onlyId) selectElements([onlyId], false, false);
|
|
10829
|
+
}
|
|
10830
|
+
fabricCanvas.requestRenderAll();
|
|
10831
|
+
} finally {
|
|
10832
|
+
requestAnimationFrame(() => {
|
|
10833
|
+
isSyncingSelectionToFabricRef.current = false;
|
|
10834
|
+
});
|
|
10835
|
+
}
|
|
10836
|
+
(_b = event == null ? void 0 : event.preventDefault) == null ? void 0 : _b.call(event);
|
|
10837
|
+
(_c = event == null ? void 0 : event.stopPropagation) == null ? void 0 : _c.call(event);
|
|
10838
|
+
return true;
|
|
10839
|
+
};
|
|
10840
|
+
const markMixedLogicalSelection = (selection, groupIds, groupMemberIds) => {
|
|
10841
|
+
delete selection.__pixldocsGroupSelection;
|
|
10842
|
+
selection.__pixldocsLogicalGroupIds = groupIds;
|
|
10843
|
+
selection.hasBorders = true;
|
|
10844
|
+
const memberObjects = selection.getObjects().filter((obj) => {
|
|
10845
|
+
const id = getObjectId(obj);
|
|
10846
|
+
return !!id && groupMemberIds.has(id);
|
|
10847
|
+
});
|
|
10848
|
+
suppressBordersForObjects(memberObjects);
|
|
10849
|
+
};
|
|
10276
10850
|
const restorePreservedGroupSelectionSoon = (snapshot = preserveActiveSelectionAfterTransformRef.current) => {
|
|
10277
10851
|
if (!(snapshot == null ? void 0 : snapshot.groupSelectionId) || snapshot.memberIds.length < 2) return;
|
|
10278
10852
|
const groupId = snapshot.groupSelectionId;
|
|
@@ -10310,7 +10884,7 @@ const PageCanvas = forwardRef(
|
|
|
10310
10884
|
return !!(((_a2 = o == null ? void 0 : o._ct) == null ? void 0 : _a2.isCropGroup) || (o == null ? void 0 : o.__cropGroup));
|
|
10311
10885
|
};
|
|
10312
10886
|
const promoteToCropGroup = (opt) => {
|
|
10313
|
-
var _a2, _b, _c;
|
|
10887
|
+
var _a2, _b, _c, _d, _e, _f;
|
|
10314
10888
|
const t = opt.target;
|
|
10315
10889
|
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") {
|
|
10316
10890
|
if (t && isCropGroup2(t)) {
|
|
@@ -10320,6 +10894,9 @@ const PageCanvas = forwardRef(
|
|
|
10320
10894
|
}
|
|
10321
10895
|
return;
|
|
10322
10896
|
}
|
|
10897
|
+
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)) {
|
|
10898
|
+
return;
|
|
10899
|
+
}
|
|
10323
10900
|
if (!t) {
|
|
10324
10901
|
const pointer = fabricCanvas.getPointer(opt.e);
|
|
10325
10902
|
const objects = fabricCanvas.getObjects();
|
|
@@ -10394,6 +10971,12 @@ const PageCanvas = forwardRef(
|
|
|
10394
10971
|
}
|
|
10395
10972
|
fabricCanvas.on("mouse:down", (opt) => {
|
|
10396
10973
|
var _a2, _b;
|
|
10974
|
+
if (pendingShiftMultiSelect) {
|
|
10975
|
+
const pending = pendingShiftMultiSelect;
|
|
10976
|
+
pendingShiftMultiSelect = null;
|
|
10977
|
+
applyShiftMultiSelect(pending.target, opt.e, pending.active, pending.activeObjects);
|
|
10978
|
+
return;
|
|
10979
|
+
}
|
|
10397
10980
|
const target = opt.target;
|
|
10398
10981
|
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;
|
|
10399
10982
|
if (cropGroup) {
|
|
@@ -10404,8 +10987,42 @@ const PageCanvas = forwardRef(
|
|
|
10404
10987
|
fabricCanvas.requestRenderAll();
|
|
10405
10988
|
}
|
|
10406
10989
|
});
|
|
10990
|
+
const groupFabricUnionBBox = (g) => {
|
|
10991
|
+
var _a2, _b;
|
|
10992
|
+
const memberIds = new Set(getAllElementIds(g.children ?? []));
|
|
10993
|
+
if (memberIds.size === 0) return null;
|
|
10994
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
10995
|
+
let found = false;
|
|
10996
|
+
for (const o of fabricCanvas.getObjects()) {
|
|
10997
|
+
const oid = getObjectId(o);
|
|
10998
|
+
if (!oid || !memberIds.has(oid)) continue;
|
|
10999
|
+
const br = ((_a2 = o.getBoundingRect) == null ? void 0 : _a2.call(o, true, true)) ?? ((_b = o.getBoundingRect) == null ? void 0 : _b.call(o));
|
|
11000
|
+
if (!br) continue;
|
|
11001
|
+
minX = Math.min(minX, br.left);
|
|
11002
|
+
minY = Math.min(minY, br.top);
|
|
11003
|
+
maxX = Math.max(maxX, br.left + br.width);
|
|
11004
|
+
maxY = Math.max(maxY, br.top + br.height);
|
|
11005
|
+
found = true;
|
|
11006
|
+
}
|
|
11007
|
+
if (!found) return null;
|
|
11008
|
+
return { left: minX, top: minY, right: maxX, bottom: maxY };
|
|
11009
|
+
};
|
|
11010
|
+
const pickGroupAtPointer = (px, py, children, activeEditingGroupId) => {
|
|
11011
|
+
let pick = null;
|
|
11012
|
+
for (const node of children) {
|
|
11013
|
+
if (!isGroup(node)) continue;
|
|
11014
|
+
if (node.backgroundColor) continue;
|
|
11015
|
+
if (activeEditingGroupId && node.id === activeEditingGroupId) continue;
|
|
11016
|
+
const b = groupFabricUnionBBox(node);
|
|
11017
|
+
if (!b) continue;
|
|
11018
|
+
if (px < b.left || py < b.top || px > b.right || py > b.bottom) continue;
|
|
11019
|
+
const area = Math.max(1, (b.right - b.left) * (b.bottom - b.top));
|
|
11020
|
+
if (!pick || area < pick.area) pick = { group: node, area };
|
|
11021
|
+
}
|
|
11022
|
+
return pick;
|
|
11023
|
+
};
|
|
10407
11024
|
fabricCanvas.on("mouse:down:before", (opt) => {
|
|
10408
|
-
var _a2, _b, _c, _d, _e;
|
|
11025
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
10409
11026
|
if (editLockRef.current) {
|
|
10410
11027
|
const active = fabricCanvas.getActiveObject();
|
|
10411
11028
|
if (active && (((_a2 = active._ct) == null ? void 0 : _a2.isCropGroup) || active.__cropGroup)) {
|
|
@@ -10421,13 +11038,154 @@ const PageCanvas = forwardRef(
|
|
|
10421
11038
|
syncLockedRef.current = true;
|
|
10422
11039
|
lockEdits();
|
|
10423
11040
|
}
|
|
11041
|
+
const target = opt.target;
|
|
11042
|
+
const targetId = target ? getObjectId(target) : null;
|
|
11043
|
+
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
11044
|
+
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
11045
|
+
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
11046
|
+
if (isMultiSelectModifier(opt.e)) {
|
|
11047
|
+
const manualTarget = target && !(target instanceof fabric.ActiveSelection) && targetId && targetId !== "__background__" ? target : pickSelectableObjectAtPointer(opt.e);
|
|
11048
|
+
if (manualTarget) {
|
|
11049
|
+
pendingShiftMultiSelect = {
|
|
11050
|
+
target: manualTarget,
|
|
11051
|
+
active: fabricCanvas.getActiveObject(),
|
|
11052
|
+
activeObjects: fabricCanvas.getActiveObjects().slice()
|
|
11053
|
+
};
|
|
11054
|
+
pendingGroupPromotionRef.current = null;
|
|
11055
|
+
return;
|
|
11056
|
+
}
|
|
11057
|
+
}
|
|
11058
|
+
const findTopmostPromotableGroup = (childId) => {
|
|
11059
|
+
let topmost = null;
|
|
11060
|
+
let currentId = childId;
|
|
11061
|
+
for (let i = 0; i < 32; i++) {
|
|
11062
|
+
const p = findParentGroup(childrenNow, currentId);
|
|
11063
|
+
if (!p) break;
|
|
11064
|
+
if (p.backgroundColor) break;
|
|
11065
|
+
if (activeEditingGroupId && p.id === activeEditingGroupId) break;
|
|
11066
|
+
topmost = p;
|
|
11067
|
+
currentId = p.id;
|
|
11068
|
+
}
|
|
11069
|
+
return topmost;
|
|
11070
|
+
};
|
|
11071
|
+
if (target && targetId && targetId !== "__background__") {
|
|
11072
|
+
const parent = findTopmostPromotableGroup(targetId);
|
|
11073
|
+
const targetIsInCrop = !!(target instanceof fabric.Group && isCropGroupInCropMode(target) || (target == null ? void 0 : target.group) instanceof fabric.Group && isCropGroupInCropMode(target.group));
|
|
11074
|
+
const activeNow = fabricCanvas.getActiveObject();
|
|
11075
|
+
const alreadyThisGroup = activeNow instanceof fabric.ActiveSelection && activeNow.__pixldocsGroupSelection === (parent == null ? void 0 : parent.id);
|
|
11076
|
+
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));
|
|
11077
|
+
if (parent && !parent.backgroundColor && !targetIsInCrop && activeEditingGroupId !== parent.id && !alreadyThisGroup && !isMultiSelectKey) {
|
|
11078
|
+
const memberIds = new Set(getAllElementIds(parent.children ?? []));
|
|
11079
|
+
const memberObjs = fabricCanvas.getObjects().filter((o) => {
|
|
11080
|
+
const oid = getObjectId(o);
|
|
11081
|
+
return !!oid && memberIds.has(oid);
|
|
11082
|
+
});
|
|
11083
|
+
if (memberObjs.length > 1) {
|
|
11084
|
+
const selection = new fabric.ActiveSelection(memberObjs, { canvas: fabricCanvas });
|
|
11085
|
+
restoreGroupSelectionVisualState(selection, parent.id);
|
|
11086
|
+
fabricCanvas.setActiveObject(selection);
|
|
11087
|
+
selection.setCoords();
|
|
11088
|
+
fabricCanvas._target = selection;
|
|
11089
|
+
opt.target = selection;
|
|
11090
|
+
pendingGroupPromotionRef.current = { groupId: parent.id, selection };
|
|
11091
|
+
} else if (memberObjs.length === 1) {
|
|
11092
|
+
const only = memberObjs[0];
|
|
11093
|
+
only.__pixldocsGroupSelection = parent.id;
|
|
11094
|
+
fabricCanvas.setActiveObject(only);
|
|
11095
|
+
only.setCoords();
|
|
11096
|
+
fabricCanvas._target = only;
|
|
11097
|
+
opt.target = only;
|
|
11098
|
+
pendingGroupPromotionRef.current = { groupId: parent.id, selection: only };
|
|
11099
|
+
}
|
|
11100
|
+
}
|
|
11101
|
+
} else if (!target || targetId === "__background__") {
|
|
11102
|
+
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));
|
|
11103
|
+
if (isMultiSelectKey) return;
|
|
11104
|
+
try {
|
|
11105
|
+
const pointer = fabricCanvas.getPointer(opt.e);
|
|
11106
|
+
const px = pointer.x;
|
|
11107
|
+
const py = pointer.y;
|
|
11108
|
+
const pick = pickGroupAtPointer(px, py, childrenNow, activeEditingGroupId);
|
|
11109
|
+
if (pick) {
|
|
11110
|
+
const parent = pick.group;
|
|
11111
|
+
if (activeEditingGroupId !== parent.id) {
|
|
11112
|
+
const memberIds = new Set(getAllElementIds(parent.children ?? []));
|
|
11113
|
+
const memberObjs = fabricCanvas.getObjects().filter((o) => {
|
|
11114
|
+
const oid = getObjectId(o);
|
|
11115
|
+
return !!oid && memberIds.has(oid);
|
|
11116
|
+
});
|
|
11117
|
+
if (memberObjs.length > 1) {
|
|
11118
|
+
const selection = new fabric.ActiveSelection(memberObjs, { canvas: fabricCanvas });
|
|
11119
|
+
restoreGroupSelectionVisualState(selection, parent.id);
|
|
11120
|
+
fabricCanvas.setActiveObject(selection);
|
|
11121
|
+
selection.setCoords();
|
|
11122
|
+
fabricCanvas._target = selection;
|
|
11123
|
+
opt.target = selection;
|
|
11124
|
+
pendingGroupPromotionRef.current = { groupId: parent.id, selection };
|
|
11125
|
+
} else if (memberObjs.length === 1) {
|
|
11126
|
+
const only = memberObjs[0];
|
|
11127
|
+
only.__pixldocsGroupSelection = parent.id;
|
|
11128
|
+
fabricCanvas.setActiveObject(only);
|
|
11129
|
+
fabricCanvas._target = only;
|
|
11130
|
+
opt.target = only;
|
|
11131
|
+
pendingGroupPromotionRef.current = { groupId: parent.id, selection: only };
|
|
11132
|
+
}
|
|
11133
|
+
}
|
|
11134
|
+
}
|
|
11135
|
+
} catch {
|
|
11136
|
+
}
|
|
11137
|
+
}
|
|
10424
11138
|
promoteToCropGroup(opt);
|
|
10425
11139
|
});
|
|
10426
11140
|
fabricCanvas.on("mouse:move:before", promoteToCropGroup);
|
|
11141
|
+
fabricCanvas.on("after:render", () => {
|
|
11142
|
+
var _a2;
|
|
11143
|
+
try {
|
|
11144
|
+
const active = fabricCanvas.getActiveObject();
|
|
11145
|
+
if (!(active instanceof fabric.ActiveSelection)) return;
|
|
11146
|
+
const logicalIds = active.__pixldocsLogicalGroupIds;
|
|
11147
|
+
if (!logicalIds || logicalIds.length < 1) return;
|
|
11148
|
+
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
11149
|
+
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
11150
|
+
const ctx = ((_a2 = fabricCanvas.getContext) == null ? void 0 : _a2.call(fabricCanvas)) ?? fabricCanvas.contextContainer;
|
|
11151
|
+
if (!ctx) return;
|
|
11152
|
+
const vt = fabricCanvas.viewportTransform;
|
|
11153
|
+
ctx.save();
|
|
11154
|
+
if (vt) ctx.transform(vt[0], vt[1], vt[2], vt[3], vt[4], vt[5]);
|
|
11155
|
+
ctx.strokeStyle = SELECTION_PRIMARY;
|
|
11156
|
+
ctx.lineWidth = 1.25 / ((vt == null ? void 0 : vt[0]) || 1);
|
|
11157
|
+
ctx.setLineDash([]);
|
|
11158
|
+
for (const gid of logicalIds) {
|
|
11159
|
+
const node = findNodeById(childrenNow, gid);
|
|
11160
|
+
if (!node || !isGroup(node)) continue;
|
|
11161
|
+
const b = groupFabricUnionBBox(node);
|
|
11162
|
+
if (!b) continue;
|
|
11163
|
+
ctx.strokeRect(b.left, b.top, b.right - b.left, b.bottom - b.top);
|
|
11164
|
+
}
|
|
11165
|
+
ctx.restore();
|
|
11166
|
+
} catch {
|
|
11167
|
+
}
|
|
11168
|
+
});
|
|
11169
|
+
fabricCanvas.on("mouse:move", (opt) => {
|
|
11170
|
+
if (fabricCanvas._currentTransform) return;
|
|
11171
|
+
if (editLockRef.current) return;
|
|
11172
|
+
const t = opt.target;
|
|
11173
|
+
const tid = t ? getObjectId(t) : null;
|
|
11174
|
+
if (t && tid && tid !== "__background__") return;
|
|
11175
|
+
try {
|
|
11176
|
+
const pointer = fabricCanvas.getPointer(opt.e);
|
|
11177
|
+
const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
|
|
11178
|
+
const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
|
|
11179
|
+
const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
|
|
11180
|
+
const pick = pickGroupAtPointer(pointer.x, pointer.y, childrenNow, activeEditingGroupId);
|
|
11181
|
+
fabricCanvas.defaultCursor = pick ? "move" : "default";
|
|
11182
|
+
} catch {
|
|
11183
|
+
fabricCanvas.defaultCursor = "default";
|
|
11184
|
+
}
|
|
11185
|
+
});
|
|
10427
11186
|
fabricCanvas.on("mouse:down", (ev) => {
|
|
10428
11187
|
if (fabricCanvas._currentTransform) {
|
|
10429
11188
|
lockEdits();
|
|
10430
|
-
didTransformRef.current = true;
|
|
10431
11189
|
}
|
|
10432
11190
|
const o = fabricCanvas.getActiveObject();
|
|
10433
11191
|
pendingTextEditOnUpRef.current = null;
|
|
@@ -10441,6 +11199,38 @@ const PageCanvas = forwardRef(
|
|
|
10441
11199
|
setRotationLabel(null);
|
|
10442
11200
|
setSizeLabel(null);
|
|
10443
11201
|
dragStarted = false;
|
|
11202
|
+
const pendingPromotion = pendingGroupPromotionRef.current;
|
|
11203
|
+
pendingGroupPromotionRef.current = null;
|
|
11204
|
+
if (pendingPromotion && !didTransformRef.current) {
|
|
11205
|
+
const activeNow = fabricCanvas.getActiveObject();
|
|
11206
|
+
if (activeNow !== pendingPromotion.selection) {
|
|
11207
|
+
isSyncingSelectionToFabricRef.current = true;
|
|
11208
|
+
try {
|
|
11209
|
+
fabricCanvas.setActiveObject(pendingPromotion.selection);
|
|
11210
|
+
pendingPromotion.selection.setCoords();
|
|
11211
|
+
fabricCanvas.requestRenderAll();
|
|
11212
|
+
} finally {
|
|
11213
|
+
requestAnimationFrame(() => {
|
|
11214
|
+
isSyncingSelectionToFabricRef.current = false;
|
|
11215
|
+
});
|
|
11216
|
+
}
|
|
11217
|
+
selectElements([pendingPromotion.groupId], false, false);
|
|
11218
|
+
}
|
|
11219
|
+
try {
|
|
11220
|
+
const sel = pendingPromotion.selection;
|
|
11221
|
+
if (sel instanceof fabric.ActiveSelection) {
|
|
11222
|
+
restoreGroupSelectionVisualState(sel, pendingPromotion.groupId);
|
|
11223
|
+
sel.hasBorders = true;
|
|
11224
|
+
sel.setCoords();
|
|
11225
|
+
applyWarpAwareSelectionBorders(sel);
|
|
11226
|
+
} else {
|
|
11227
|
+
sel.__pixldocsGroupSelection = pendingPromotion.groupId;
|
|
11228
|
+
sel.setCoords();
|
|
11229
|
+
}
|
|
11230
|
+
fabricCanvas.requestRenderAll();
|
|
11231
|
+
} catch {
|
|
11232
|
+
}
|
|
11233
|
+
}
|
|
10444
11234
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10445
11235
|
if (activeObj && (activeObj.__cropGroup || ((_a2 = activeObj._ct) == null ? void 0 : _a2.isCropGroup))) {
|
|
10446
11236
|
activeObj.__lockScaleDuringCrop = false;
|
|
@@ -10482,6 +11272,34 @@ const PageCanvas = forwardRef(
|
|
|
10482
11272
|
if (!isActiveRef.current) return;
|
|
10483
11273
|
markTransforming(e.target);
|
|
10484
11274
|
};
|
|
11275
|
+
const getObjectFrameBoundsInSelection = (selection, obj, frameWidth, frameHeight) => {
|
|
11276
|
+
const w = Math.max(1, frameWidth ?? obj.width ?? 1);
|
|
11277
|
+
const h = Math.max(1, frameHeight ?? obj.height ?? 1);
|
|
11278
|
+
const originX = obj.originX ?? "left";
|
|
11279
|
+
const originY = obj.originY ?? "top";
|
|
11280
|
+
const localLeft = originX === "center" ? -w / 2 : originX === "right" ? -w : 0;
|
|
11281
|
+
const localTop = originY === "center" ? -h / 2 : originY === "bottom" ? -h : 0;
|
|
11282
|
+
const matrix = fabric.util.multiplyTransformMatrices(
|
|
11283
|
+
selection.calcTransformMatrix(),
|
|
11284
|
+
obj.calcOwnMatrix()
|
|
11285
|
+
);
|
|
11286
|
+
const points = [
|
|
11287
|
+
new fabric.Point(localLeft, localTop),
|
|
11288
|
+
new fabric.Point(localLeft + w, localTop),
|
|
11289
|
+
new fabric.Point(localLeft + w, localTop + h),
|
|
11290
|
+
new fabric.Point(localLeft, localTop + h)
|
|
11291
|
+
].map((point) => fabric.util.transformPoint(point, matrix));
|
|
11292
|
+
const xs = points.map((p) => p.x);
|
|
11293
|
+
const ys = points.map((p) => p.y);
|
|
11294
|
+
const left = Math.min(...xs);
|
|
11295
|
+
const top = Math.min(...ys);
|
|
11296
|
+
return {
|
|
11297
|
+
left,
|
|
11298
|
+
top,
|
|
11299
|
+
width: Math.max(1, Math.max(...xs) - left),
|
|
11300
|
+
height: Math.max(1, Math.max(...ys) - top)
|
|
11301
|
+
};
|
|
11302
|
+
};
|
|
10485
11303
|
fabricCanvas.on("object:added", (e) => {
|
|
10486
11304
|
var _a2;
|
|
10487
11305
|
const obj = e.target;
|
|
@@ -10601,11 +11419,18 @@ const PageCanvas = forwardRef(
|
|
|
10601
11419
|
}
|
|
10602
11420
|
if (obj instanceof fabric.Textbox) {
|
|
10603
11421
|
const sy = obj.scaleY ?? 1;
|
|
10604
|
-
|
|
11422
|
+
const sx = obj.scaleX ?? 1;
|
|
11423
|
+
const isUniformCornerScale = Math.abs(sx - sy) < 1e-3 && Math.abs(sx - 1) > 1e-3;
|
|
11424
|
+
if (isUniformCornerScale) {
|
|
11425
|
+
obj.setCoords();
|
|
11426
|
+
obj.dirty = true;
|
|
11427
|
+
} else if (Math.abs(sy - 1) > 1e-3) {
|
|
10605
11428
|
const center = obj.getCenterPoint();
|
|
10606
|
-
const
|
|
11429
|
+
const newVisualH = (obj.height ?? 0) * Math.abs(sy);
|
|
11430
|
+
const targetScaleY = Math.abs(sx - 1) > 1e-3 ? Math.abs(sx) : 1;
|
|
11431
|
+
const newMinH = Math.max(0, newVisualH / targetScaleY);
|
|
10607
11432
|
obj.minBoxHeight = newMinH;
|
|
10608
|
-
obj.scaleY =
|
|
11433
|
+
obj.scaleY = targetScaleY;
|
|
10609
11434
|
try {
|
|
10610
11435
|
obj.initDimensions();
|
|
10611
11436
|
} catch {
|
|
@@ -10727,7 +11552,7 @@ const PageCanvas = forwardRef(
|
|
|
10727
11552
|
});
|
|
10728
11553
|
let cropGroupSaveTimer = null;
|
|
10729
11554
|
fabricCanvas.on("object:modified", (e) => {
|
|
10730
|
-
var _a2, _b, _c, _d, _e, _f;
|
|
11555
|
+
var _a2, _b, _c, _d, _e, _f, _g;
|
|
10731
11556
|
try {
|
|
10732
11557
|
dragStarted = false;
|
|
10733
11558
|
setGuides([]);
|
|
@@ -10948,14 +11773,14 @@ const PageCanvas = forwardRef(
|
|
|
10948
11773
|
}
|
|
10949
11774
|
if (active && active instanceof fabric.Group && !(active instanceof fabric.ActiveSelection) && getObjectId(active)) {
|
|
10950
11775
|
const groupId = getObjectId(active);
|
|
10951
|
-
const
|
|
11776
|
+
const pageChildren3 = ((_e = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _e.children) ?? [];
|
|
10952
11777
|
const w = (active.width ?? 0) * (active.scaleX ?? 1);
|
|
10953
11778
|
const h = (active.height ?? 0) * (active.scaleY ?? 1);
|
|
10954
11779
|
const centerX = active.left ?? 0;
|
|
10955
11780
|
const centerY = active.top ?? 0;
|
|
10956
11781
|
const groupLeft = active.originX === "center" ? centerX - w / 2 : centerX;
|
|
10957
11782
|
const groupTop = active.originY === "center" ? centerY - h / 2 : centerY;
|
|
10958
|
-
const storePos = absoluteToStorePosition(groupLeft, groupTop, groupId,
|
|
11783
|
+
const storePos = absoluteToStorePosition(groupLeft, groupTop, groupId, pageChildren3);
|
|
10959
11784
|
useEditorStore.getState().updateNode(groupId, { left: storePos.left, top: storePos.top }, { recordHistory: false, skipLayoutRecalc: true });
|
|
10960
11785
|
commitHistory();
|
|
10961
11786
|
unlockEditsSoon();
|
|
@@ -10970,6 +11795,14 @@ const PageCanvas = forwardRef(
|
|
|
10970
11795
|
}
|
|
10971
11796
|
const activeObj = fabricCanvas.getActiveObject();
|
|
10972
11797
|
let activeObjects = fabricCanvas.getActiveObjects();
|
|
11798
|
+
const activeSelectionMoveStart = activeObj instanceof fabric.ActiveSelection && ((_f = activeSelectionMoveStartRef.current) == null ? void 0 : _f.selection) === activeObj ? activeSelectionMoveStartRef.current : null;
|
|
11799
|
+
const activeSelectionDelta = activeObj instanceof fabric.ActiveSelection && activeSelectionMoveStart ? (() => {
|
|
11800
|
+
const rect = activeObj.getBoundingRect();
|
|
11801
|
+
return {
|
|
11802
|
+
x: rect.left - activeSelectionMoveStart.selectionLeft,
|
|
11803
|
+
y: rect.top - activeSelectionMoveStart.selectionTop
|
|
11804
|
+
};
|
|
11805
|
+
})() : null;
|
|
10973
11806
|
if (activeObjects.length === 0 && modifiedTarget && getObjectId(modifiedTarget)) {
|
|
10974
11807
|
activeObjects = [modifiedTarget];
|
|
10975
11808
|
}
|
|
@@ -10991,8 +11824,53 @@ const PageCanvas = forwardRef(
|
|
|
10991
11824
|
const currentPage2 = getCurrentPageStore();
|
|
10992
11825
|
const selectedElementIds = activeObjects.map((obj) => getObjectId(obj)).filter((id) => !!id && id !== "__background__");
|
|
10993
11826
|
const anyCropGroup = activeObjects.some((o) => o.__cropGroup);
|
|
11827
|
+
const pageChildren2 = currentPage2.children ?? [];
|
|
11828
|
+
const selectedLogicalGroupIds = (useEditorStore.getState().canvas.selectedIds ?? []).filter((id) => {
|
|
11829
|
+
const node = findNodeById(pageChildren2, id);
|
|
11830
|
+
return !!(node && isGroup(node));
|
|
11831
|
+
});
|
|
11832
|
+
const activeSelectionHadTransform = activeObj instanceof fabric.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);
|
|
11833
|
+
if (!anyCropGroup && activeSelectionDelta && !activeSelectionHadTransform && selectedLogicalGroupIds.length > 0) {
|
|
11834
|
+
const selectedStoreIds = useEditorStore.getState().canvas.selectedIds ?? [];
|
|
11835
|
+
const groupMemberIds = /* @__PURE__ */ new Set();
|
|
11836
|
+
selectedLogicalGroupIds.forEach((gid) => {
|
|
11837
|
+
const groupNode = findNodeById(pageChildren2, gid);
|
|
11838
|
+
if (groupNode && isGroup(groupNode)) {
|
|
11839
|
+
getAllElementIds(groupNode.children ?? []).forEach((id) => groupMemberIds.add(id));
|
|
11840
|
+
}
|
|
11841
|
+
});
|
|
11842
|
+
const logicalStandaloneIds = selectedStoreIds.filter((id) => {
|
|
11843
|
+
if (selectedLogicalGroupIds.includes(id)) return false;
|
|
11844
|
+
if (groupMemberIds.has(id)) return false;
|
|
11845
|
+
return !!findNodeById(pageChildren2, id);
|
|
11846
|
+
});
|
|
11847
|
+
if (logicalStandaloneIds.length > 0) {
|
|
11848
|
+
const { updateNode: updateNodeStore, commitHistory: commitHistoryStore } = useEditorStore.getState();
|
|
11849
|
+
[...selectedLogicalGroupIds, ...logicalStandaloneIds].forEach((id) => {
|
|
11850
|
+
const node = findNodeById(pageChildren2, id);
|
|
11851
|
+
if (!node) return;
|
|
11852
|
+
const abs = getAbsoluteBounds(node, pageChildren2, pageBoundsOptions);
|
|
11853
|
+
const nextAbsLeft = abs.left + activeSelectionDelta.x;
|
|
11854
|
+
const nextAbsTop = abs.top + activeSelectionDelta.y;
|
|
11855
|
+
const storePos = absoluteToStorePosition(nextAbsLeft, nextAbsTop, id, pageChildren2);
|
|
11856
|
+
updateNodeStore(id, { left: storePos.left, top: storePos.top }, { recordHistory: false, skipLayoutRecalc: true });
|
|
11857
|
+
});
|
|
11858
|
+
commitHistoryStore();
|
|
11859
|
+
activeObjects.forEach((obj) => {
|
|
11860
|
+
const objId = getObjectId(obj);
|
|
11861
|
+
if (objId && objId !== "__background__") {
|
|
11862
|
+
justModifiedIdsRef.current.add(objId);
|
|
11863
|
+
modifiedIdsThisRound.add(objId);
|
|
11864
|
+
}
|
|
11865
|
+
});
|
|
11866
|
+
setTimeout(() => modifiedIdsThisRound.forEach((id) => justModifiedIdsRef.current.delete(id)), 150);
|
|
11867
|
+
activeSelectionMoveStartRef.current = null;
|
|
11868
|
+
groupSelectionTransformStartRef.current = null;
|
|
11869
|
+
unlockEditsSoon();
|
|
11870
|
+
return;
|
|
11871
|
+
}
|
|
11872
|
+
}
|
|
10994
11873
|
if (selectedElementIds.length > 0 && !anyCropGroup) {
|
|
10995
|
-
const pageChildren2 = currentPage2.children ?? [];
|
|
10996
11874
|
const firstObj = activeObjects[0];
|
|
10997
11875
|
const firstId = getObjectId(firstObj);
|
|
10998
11876
|
const parentGroups = selectedElementIds.map((id) => findParentGroup(pageChildren2, id)).filter((g) => g !== null);
|
|
@@ -11087,6 +11965,7 @@ const PageCanvas = forwardRef(
|
|
|
11087
11965
|
}
|
|
11088
11966
|
}
|
|
11089
11967
|
}
|
|
11968
|
+
const pendingCropGroupFrameBakes = [];
|
|
11090
11969
|
for (const obj of activeObjects) {
|
|
11091
11970
|
const objId = getObjectId(obj);
|
|
11092
11971
|
if (!objId || objId === "__background__") continue;
|
|
@@ -11140,10 +12019,16 @@ const PageCanvas = forwardRef(
|
|
|
11140
12019
|
}
|
|
11141
12020
|
if (obj instanceof fabric.Group && obj.__cropGroup) {
|
|
11142
12021
|
const ct = obj.__cropData;
|
|
11143
|
-
|
|
11144
|
-
|
|
11145
|
-
|
|
11146
|
-
|
|
12022
|
+
if (isActiveSelection && activeObj instanceof fabric.ActiveSelection) {
|
|
12023
|
+
const frameBounds = getObjectFrameBoundsInSelection(activeObj, obj, ct == null ? void 0 : ct.frameW, ct == null ? void 0 : ct.frameH);
|
|
12024
|
+
absoluteLeft = frameBounds.left;
|
|
12025
|
+
absoluteTop = frameBounds.top;
|
|
12026
|
+
} else {
|
|
12027
|
+
const w = ((ct == null ? void 0 : ct.frameW) ?? obj.width ?? 0) * Math.abs(obj.scaleX ?? 1);
|
|
12028
|
+
const h = ((ct == null ? void 0 : ct.frameH) ?? obj.height ?? 0) * Math.abs(obj.scaleY ?? 1);
|
|
12029
|
+
absoluteLeft = (absoluteLeft ?? 0) - w / 2;
|
|
12030
|
+
absoluteTop = (absoluteTop ?? 0) - h / 2;
|
|
12031
|
+
}
|
|
11147
12032
|
} else if (obj instanceof fabric.FabricImage && (obj.originX === "center" || obj.originY === "center")) {
|
|
11148
12033
|
const w = (obj.width ?? 0) * (obj.scaleX ?? 1);
|
|
11149
12034
|
const h = (obj.height ?? 0) * (obj.scaleY ?? 1);
|
|
@@ -11160,17 +12045,49 @@ const PageCanvas = forwardRef(
|
|
|
11160
12045
|
if (obj instanceof fabric.Group && obj.__cropGroup) {
|
|
11161
12046
|
const ct = obj.__cropData;
|
|
11162
12047
|
if (ct) {
|
|
11163
|
-
|
|
11164
|
-
|
|
12048
|
+
const sourceFrameW = Math.max(1, ct.frameW ?? obj.width ?? 1);
|
|
12049
|
+
const sourceFrameH = Math.max(1, ct.frameH ?? obj.height ?? 1);
|
|
12050
|
+
const appliedScaleX = Math.abs(isActiveSelection && activeObj ? activeObj.scaleX ?? 1 : obj.scaleX ?? 1);
|
|
12051
|
+
const appliedScaleY = Math.abs(isActiveSelection && activeObj ? activeObj.scaleY ?? 1 : obj.scaleY ?? 1);
|
|
12052
|
+
finalWidth = Math.max(1, sourceFrameW * appliedScaleX);
|
|
12053
|
+
finalHeight = Math.max(1, sourceFrameH * appliedScaleY);
|
|
11165
12054
|
finalScaleX = 1;
|
|
11166
12055
|
finalScaleY = 1;
|
|
11167
|
-
|
|
11168
|
-
|
|
12056
|
+
if (isActiveSelection && activeObj instanceof fabric.ActiveSelection) {
|
|
12057
|
+
const frameBounds = getObjectFrameBoundsInSelection(activeObj, obj, sourceFrameW, sourceFrameH);
|
|
12058
|
+
absoluteLeft = frameBounds.left;
|
|
12059
|
+
absoluteTop = frameBounds.top;
|
|
12060
|
+
} else {
|
|
12061
|
+
absoluteLeft = (decomposed.translateX ?? absoluteLeft) - finalWidth / 2;
|
|
12062
|
+
absoluteTop = (decomposed.translateY ?? absoluteTop) - finalHeight / 2;
|
|
12063
|
+
}
|
|
12064
|
+
finalAbsoluteMatrix = fabric.util.composeMatrix({
|
|
12065
|
+
translateX: absoluteLeft + finalWidth / 2,
|
|
12066
|
+
translateY: absoluteTop + finalHeight / 2,
|
|
12067
|
+
angle: decomposed.angle ?? (obj.angle ?? 0),
|
|
12068
|
+
scaleX: 1,
|
|
12069
|
+
scaleY: 1,
|
|
12070
|
+
skewX: 0,
|
|
12071
|
+
skewY: 0
|
|
12072
|
+
});
|
|
12073
|
+
if (isActiveSelection && activeObj instanceof fabric.ActiveSelection) {
|
|
12074
|
+
pendingCropGroupFrameBakes.push({
|
|
12075
|
+
obj,
|
|
12076
|
+
width: finalWidth,
|
|
12077
|
+
height: finalHeight,
|
|
12078
|
+
left: absoluteLeft,
|
|
12079
|
+
top: absoluteTop,
|
|
12080
|
+
angle: decomposed.angle ?? (obj.angle ?? 0)
|
|
12081
|
+
});
|
|
12082
|
+
} else {
|
|
12083
|
+
ct.frameW = finalWidth;
|
|
12084
|
+
ct.frameH = finalHeight;
|
|
12085
|
+
obj.set({ width: finalWidth, height: finalHeight, scaleX: 1, scaleY: 1 });
|
|
11169
12086
|
updateCoverLayout(obj);
|
|
11170
|
-
|
|
12087
|
+
}
|
|
12088
|
+
obj.__lastResizeHandle = null;
|
|
12089
|
+
if (!isActiveSelection) {
|
|
11171
12090
|
fabricCanvas.setActiveObject(obj);
|
|
11172
|
-
} else {
|
|
11173
|
-
obj.__lastResizeHandle = null;
|
|
11174
12091
|
}
|
|
11175
12092
|
}
|
|
11176
12093
|
} else if (obj instanceof fabric.FabricImage) {
|
|
@@ -11260,6 +12177,10 @@ const PageCanvas = forwardRef(
|
|
|
11260
12177
|
if (obj.textPath) {
|
|
11261
12178
|
elementUpdate.textPath = obj.textPath;
|
|
11262
12179
|
}
|
|
12180
|
+
const bakedFs = obj.fontSize;
|
|
12181
|
+
if (typeof bakedFs === "number" && bakedFs > 0) {
|
|
12182
|
+
elementUpdate.fontSize = bakedFs;
|
|
12183
|
+
}
|
|
11263
12184
|
}
|
|
11264
12185
|
if (sourceElement && sourceElement.opacity !== void 0) {
|
|
11265
12186
|
elementUpdate.opacity = sourceElement.opacity;
|
|
@@ -11267,7 +12188,7 @@ const PageCanvas = forwardRef(
|
|
|
11267
12188
|
updateElement(objId, elementUpdate, { recordHistory: false, skipLayoutRecalc: true });
|
|
11268
12189
|
obj.setCoords();
|
|
11269
12190
|
}
|
|
11270
|
-
const pageChildrenForReflow = ((
|
|
12191
|
+
const pageChildrenForReflow = ((_g = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _g.children) ?? [];
|
|
11271
12192
|
const stackGroupsToReflow = /* @__PURE__ */ new Set();
|
|
11272
12193
|
for (const id of modifiedIdsThisRound) {
|
|
11273
12194
|
const parent = findParentGroup(pageChildrenForReflow, id);
|
|
@@ -11291,6 +12212,25 @@ const PageCanvas = forwardRef(
|
|
|
11291
12212
|
} finally {
|
|
11292
12213
|
skipActiveSelectionBakeOnClearRef.current = false;
|
|
11293
12214
|
}
|
|
12215
|
+
for (const bake of pendingCropGroupFrameBakes) {
|
|
12216
|
+
const ct = bake.obj.__cropData;
|
|
12217
|
+
if (!ct) continue;
|
|
12218
|
+
ct.frameW = bake.width;
|
|
12219
|
+
ct.frameH = bake.height;
|
|
12220
|
+
bake.obj.set({
|
|
12221
|
+
left: bake.left + bake.width / 2,
|
|
12222
|
+
top: bake.top + bake.height / 2,
|
|
12223
|
+
width: bake.width,
|
|
12224
|
+
height: bake.height,
|
|
12225
|
+
scaleX: 1,
|
|
12226
|
+
scaleY: 1,
|
|
12227
|
+
angle: bake.angle,
|
|
12228
|
+
originX: "center",
|
|
12229
|
+
originY: "center"
|
|
12230
|
+
});
|
|
12231
|
+
updateCoverLayout(bake.obj);
|
|
12232
|
+
bake.obj.setCoords();
|
|
12233
|
+
}
|
|
11294
12234
|
if (membersToReselect.length > 1) {
|
|
11295
12235
|
const newSel = new fabric.ActiveSelection(membersToReselect, { canvas: fabricCanvas });
|
|
11296
12236
|
if (wasGroupSel) restoreGroupSelectionVisualState(newSel, wasGroupSel);
|
|
@@ -11309,6 +12249,7 @@ const PageCanvas = forwardRef(
|
|
|
11309
12249
|
fabricCanvas.requestRenderAll();
|
|
11310
12250
|
}
|
|
11311
12251
|
groupSelectionTransformStartRef.current = null;
|
|
12252
|
+
activeSelectionMoveStartRef.current = null;
|
|
11312
12253
|
setTimeout(() => modifiedIdsThisRound.forEach((id) => justModifiedIdsRef.current.delete(id)), 150);
|
|
11313
12254
|
commitHistory();
|
|
11314
12255
|
unlockEditsSoon();
|
|
@@ -11337,6 +12278,7 @@ const PageCanvas = forwardRef(
|
|
|
11337
12278
|
}
|
|
11338
12279
|
});
|
|
11339
12280
|
fabricCanvas.on("mouse:dblclick", (e) => {
|
|
12281
|
+
var _a2, _b;
|
|
11340
12282
|
if (!isActiveRef.current || !allowEditing) return;
|
|
11341
12283
|
let target = e.target;
|
|
11342
12284
|
if (!target) {
|
|
@@ -11345,7 +12287,10 @@ const PageCanvas = forwardRef(
|
|
|
11345
12287
|
}
|
|
11346
12288
|
if (target && target instanceof fabric.Group && target.__cropGroup) {
|
|
11347
12289
|
const ct = target.__cropData;
|
|
11348
|
-
|
|
12290
|
+
const innerImg = ct == null ? void 0 : ct._img;
|
|
12291
|
+
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) || "";
|
|
12292
|
+
const isPlaceholder = !innerSrc || innerSrc === EMPTY_IMAGE_PLACEHOLDER_DATA_URL;
|
|
12293
|
+
if (innerImg && !isPlaceholder && !isCropGroupInCropMode(target)) {
|
|
11349
12294
|
enterCropMode(target);
|
|
11350
12295
|
return;
|
|
11351
12296
|
}
|
|
@@ -11579,14 +12524,7 @@ const PageCanvas = forwardRef(
|
|
|
11579
12524
|
try {
|
|
11580
12525
|
const newSel = new fabric.ActiveSelection(freshMembers, { canvas: fc });
|
|
11581
12526
|
if (activeSelectionSnapshot.groupSelectionId) {
|
|
11582
|
-
newSel
|
|
11583
|
-
suppressGroupMemberBordersRef.current = freshMembers;
|
|
11584
|
-
for (const m of freshMembers) {
|
|
11585
|
-
if (m.__pixldocsOrigHasBorders === void 0) {
|
|
11586
|
-
m.__pixldocsOrigHasBorders = m.hasBorders;
|
|
11587
|
-
}
|
|
11588
|
-
m.hasBorders = false;
|
|
11589
|
-
}
|
|
12527
|
+
applyLogicalGroupSelectionVisualState(newSel, activeSelectionSnapshot.groupSelectionId);
|
|
11590
12528
|
}
|
|
11591
12529
|
fc.setActiveObject(newSel);
|
|
11592
12530
|
newSel.setCoords();
|
|
@@ -11971,6 +12909,7 @@ const PageCanvas = forwardRef(
|
|
|
11971
12909
|
continue;
|
|
11972
12910
|
}
|
|
11973
12911
|
if (existingObj instanceof fabric.Group && existingObj.__cropGroup) {
|
|
12912
|
+
updateFabricObject(existingObj, element, wasJustModified);
|
|
11974
12913
|
existingObj.set({
|
|
11975
12914
|
flipX: element.flipX ?? false,
|
|
11976
12915
|
flipY: element.flipY ?? false,
|
|
@@ -11978,6 +12917,7 @@ const PageCanvas = forwardRef(
|
|
|
11978
12917
|
});
|
|
11979
12918
|
existingObj.setCoords();
|
|
11980
12919
|
fc.requestRenderAll();
|
|
12920
|
+
if (wasJustModified) justModifiedIdsRef.current.delete(element.id);
|
|
11981
12921
|
continue;
|
|
11982
12922
|
}
|
|
11983
12923
|
if (existingObj instanceof fabric.Textbox && wasJustModified && !syncTriggeredByPanelRef.current) {
|
|
@@ -12244,18 +13184,17 @@ const PageCanvas = forwardRef(
|
|
|
12244
13184
|
}
|
|
12245
13185
|
if (!shouldSkipUpdates2) {
|
|
12246
13186
|
const dfsIds = [];
|
|
12247
|
-
const visit = (nodes
|
|
12248
|
-
const
|
|
12249
|
-
for (const n of list) {
|
|
13187
|
+
const visit = (nodes) => {
|
|
13188
|
+
for (const n of nodes) {
|
|
12250
13189
|
if (isElement(n)) dfsIds.push(n.id);
|
|
12251
13190
|
else if (isGroup(n)) {
|
|
12252
13191
|
const g = n;
|
|
12253
13192
|
if (sectionGroupIds.has(g.id)) dfsIds.push(g.id);
|
|
12254
|
-
visit(g.children ?? []
|
|
13193
|
+
visit(g.children ?? []);
|
|
12255
13194
|
}
|
|
12256
13195
|
}
|
|
12257
13196
|
};
|
|
12258
|
-
visit(pageTree
|
|
13197
|
+
visit(pageTree);
|
|
12259
13198
|
const allFabricObjects = fc.getObjects();
|
|
12260
13199
|
allFabricObjects.sort((a, b) => {
|
|
12261
13200
|
const aIndex = dfsIds.indexOf(getObjectId(a) || "");
|
|
@@ -12317,14 +13256,7 @@ const PageCanvas = forwardRef(
|
|
|
12317
13256
|
try {
|
|
12318
13257
|
const newSel = new fabric.ActiveSelection(freshMembers, { canvas: fc });
|
|
12319
13258
|
if (activeSelectionSnapshot.groupSelectionId) {
|
|
12320
|
-
newSel
|
|
12321
|
-
suppressGroupMemberBordersRef.current = freshMembers;
|
|
12322
|
-
for (const m of freshMembers) {
|
|
12323
|
-
if (m.__pixldocsOrigHasBorders === void 0) {
|
|
12324
|
-
m.__pixldocsOrigHasBorders = m.hasBorders;
|
|
12325
|
-
}
|
|
12326
|
-
m.hasBorders = false;
|
|
12327
|
-
}
|
|
13259
|
+
applyLogicalGroupSelectionVisualState(newSel, activeSelectionSnapshot.groupSelectionId);
|
|
12328
13260
|
}
|
|
12329
13261
|
fc.setActiveObject(newSel);
|
|
12330
13262
|
newSel.setCoords();
|
|
@@ -12516,12 +13448,24 @@ const PageCanvas = forwardRef(
|
|
|
12516
13448
|
isSyncingSelectionToFabricRef.current = true;
|
|
12517
13449
|
const selectedSet = new Set(selectedIds);
|
|
12518
13450
|
const pageChildrenForSelection = ((_a2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
|
|
12519
|
-
const
|
|
13451
|
+
const selectedGroupIds = selectedIds.filter((id) => {
|
|
12520
13452
|
const node = findNodeById(pageChildrenForSelection, id);
|
|
12521
13453
|
return !!(node && isGroup(node));
|
|
12522
13454
|
});
|
|
12523
|
-
const
|
|
12524
|
-
const
|
|
13455
|
+
const selectedGroupSelectionId = selectedGroupIds[0];
|
|
13456
|
+
const selectedGroupMemberIdsAll = /* @__PURE__ */ new Set();
|
|
13457
|
+
for (const gid of selectedGroupIds) {
|
|
13458
|
+
const groupNode = findNodeById(pageChildrenForSelection, gid);
|
|
13459
|
+
if (groupNode && isGroup(groupNode)) {
|
|
13460
|
+
getAllElementIds(groupNode.children ?? []).forEach((id) => selectedGroupMemberIdsAll.add(id));
|
|
13461
|
+
}
|
|
13462
|
+
}
|
|
13463
|
+
const standaloneSelectedIds = selectedIds.filter((id) => {
|
|
13464
|
+
if (selectedGroupIds.includes(id)) return false;
|
|
13465
|
+
if (selectedGroupMemberIdsAll.has(id)) return false;
|
|
13466
|
+
return !!findNodeById(pageChildrenForSelection, id);
|
|
13467
|
+
});
|
|
13468
|
+
const isPureSingleGroupSelection = selectedGroupIds.length === 1 && standaloneSelectedIds.length === 0;
|
|
12525
13469
|
const toSelect = [];
|
|
12526
13470
|
for (const obj of fc.getObjects()) {
|
|
12527
13471
|
const id = getObjectId(obj);
|
|
@@ -12530,17 +13474,29 @@ const PageCanvas = forwardRef(
|
|
|
12530
13474
|
toSelect.push(obj);
|
|
12531
13475
|
continue;
|
|
12532
13476
|
}
|
|
12533
|
-
if (id &&
|
|
13477
|
+
if (id && selectedGroupMemberIdsAll.has(id)) {
|
|
12534
13478
|
toSelect.push(obj);
|
|
12535
13479
|
continue;
|
|
12536
13480
|
}
|
|
12537
13481
|
if (obj instanceof fabric.Group && obj.__docuforgeSectionGroup) {
|
|
12538
13482
|
for (const child of obj.getObjects()) {
|
|
12539
13483
|
const childId = getObjectId(child);
|
|
12540
|
-
if (childId && (selectedSet.has(childId) ||
|
|
13484
|
+
if (childId && (selectedSet.has(childId) || selectedGroupMemberIdsAll.has(childId))) toSelect.push(child);
|
|
12541
13485
|
}
|
|
12542
13486
|
}
|
|
12543
13487
|
}
|
|
13488
|
+
const restoreSuppressedBordersForSelectionSync = () => {
|
|
13489
|
+
const suppressed = suppressGroupMemberBordersRef.current;
|
|
13490
|
+
for (const member of suppressed) {
|
|
13491
|
+
const origBorders = member.__pixldocsOrigHasBorders;
|
|
13492
|
+
const origControls = member.__pixldocsOrigHasControls;
|
|
13493
|
+
member.hasBorders = origBorders !== void 0 ? origBorders : true;
|
|
13494
|
+
member.hasControls = origControls !== void 0 ? origControls : true;
|
|
13495
|
+
delete member.__pixldocsOrigHasBorders;
|
|
13496
|
+
delete member.__pixldocsOrigHasControls;
|
|
13497
|
+
}
|
|
13498
|
+
suppressGroupMemberBordersRef.current = [];
|
|
13499
|
+
};
|
|
12544
13500
|
if (toSelect.length === 0) {
|
|
12545
13501
|
if (!syncLockedRef.current && !editLockRef.current) {
|
|
12546
13502
|
fc.discardActiveObject();
|
|
@@ -12551,6 +13507,12 @@ const PageCanvas = forwardRef(
|
|
|
12551
13507
|
if (objId) {
|
|
12552
13508
|
justModifiedIdsRef.current.add(objId);
|
|
12553
13509
|
}
|
|
13510
|
+
if (!selectedGroupSelectionId) {
|
|
13511
|
+
restoreSuppressedBordersForSelectionSync();
|
|
13512
|
+
delete obj.__pixldocsGroupSelection;
|
|
13513
|
+
delete obj.__pixldocsLogicalGroupIds;
|
|
13514
|
+
obj.set({ selectable: true, evented: true, hasBorders: true, hasControls: true });
|
|
13515
|
+
}
|
|
12554
13516
|
fc.setActiveObject(obj);
|
|
12555
13517
|
obj.setCoords();
|
|
12556
13518
|
} else {
|
|
@@ -12559,13 +13521,39 @@ const PageCanvas = forwardRef(
|
|
|
12559
13521
|
const sameSelection = active instanceof fabric.ActiveSelection && active.getObjects().length === toSelect.length && toSelect.every((obj) => active.getObjects().includes(obj));
|
|
12560
13522
|
if (sameSelection && isFlatGroupSelection) {
|
|
12561
13523
|
if (selectedGroupSelectionId && active instanceof fabric.ActiveSelection) {
|
|
12562
|
-
|
|
12563
|
-
|
|
12564
|
-
|
|
13524
|
+
if (isPureSingleGroupSelection) {
|
|
13525
|
+
active.__pixldocsGroupSelection = selectedGroupSelectionId;
|
|
13526
|
+
delete active.__pixldocsLogicalGroupIds;
|
|
13527
|
+
suppressGroupMemberBordersRef.current = active.getObjects();
|
|
13528
|
+
} else {
|
|
13529
|
+
delete active.__pixldocsGroupSelection;
|
|
13530
|
+
active.__pixldocsLogicalGroupIds = selectedGroupIds;
|
|
13531
|
+
active.hasBorders = true;
|
|
13532
|
+
suppressGroupMemberBordersRef.current = active.getObjects().filter((m) => {
|
|
13533
|
+
const id = getObjectId(m);
|
|
13534
|
+
return !!id && selectedGroupMemberIdsAll.has(id);
|
|
13535
|
+
});
|
|
13536
|
+
}
|
|
13537
|
+
suppressGroupMemberBordersRef.current.forEach((m) => {
|
|
13538
|
+
var _a3;
|
|
12565
13539
|
if (m.__pixldocsOrigHasBorders === void 0) m.__pixldocsOrigHasBorders = m.hasBorders;
|
|
13540
|
+
if (m.__pixldocsOrigHasControls === void 0) m.__pixldocsOrigHasControls = m.hasControls;
|
|
12566
13541
|
m.hasBorders = false;
|
|
13542
|
+
m.hasControls = false;
|
|
13543
|
+
if (m.__cropGroup || ((_a3 = m._ct) == null ? void 0 : _a3.isCropGroup)) {
|
|
13544
|
+
if (m.__pixldocsOrigLockScalingX === void 0) {
|
|
13545
|
+
m.__pixldocsOrigLockScalingX = m.lockScalingX;
|
|
13546
|
+
m.__pixldocsOrigLockScalingY = m.lockScalingY;
|
|
13547
|
+
}
|
|
13548
|
+
m.lockScalingX = false;
|
|
13549
|
+
m.lockScalingY = false;
|
|
13550
|
+
}
|
|
12567
13551
|
});
|
|
12568
|
-
|
|
13552
|
+
if (isPureSingleGroupSelection) {
|
|
13553
|
+
active.hasBorders = true;
|
|
13554
|
+
active.setCoords();
|
|
13555
|
+
applyWarpAwareSelectionBorders(active);
|
|
13556
|
+
}
|
|
12569
13557
|
}
|
|
12570
13558
|
fc.requestRenderAll();
|
|
12571
13559
|
} else {
|
|
@@ -12575,13 +13563,33 @@ const PageCanvas = forwardRef(
|
|
|
12575
13563
|
});
|
|
12576
13564
|
const selection = new fabric.ActiveSelection(toSelect, { canvas: fc });
|
|
12577
13565
|
if (selectedGroupSelectionId) {
|
|
12578
|
-
|
|
12579
|
-
|
|
12580
|
-
|
|
13566
|
+
if (isPureSingleGroupSelection) {
|
|
13567
|
+
selection.__pixldocsGroupSelection = selectedGroupSelectionId;
|
|
13568
|
+
suppressGroupMemberBordersRef.current = toSelect;
|
|
13569
|
+
} else {
|
|
13570
|
+
selection.__pixldocsLogicalGroupIds = selectedGroupIds;
|
|
13571
|
+
selection.hasBorders = true;
|
|
13572
|
+
suppressGroupMemberBordersRef.current = toSelect.filter((m) => {
|
|
13573
|
+
const id = getObjectId(m);
|
|
13574
|
+
return !!id && selectedGroupMemberIdsAll.has(id);
|
|
13575
|
+
});
|
|
13576
|
+
}
|
|
13577
|
+
suppressGroupMemberBordersRef.current.forEach((m) => {
|
|
13578
|
+
var _a3;
|
|
12581
13579
|
if (m.__pixldocsOrigHasBorders === void 0) m.__pixldocsOrigHasBorders = m.hasBorders;
|
|
13580
|
+
if (m.__pixldocsOrigHasControls === void 0) m.__pixldocsOrigHasControls = m.hasControls;
|
|
12582
13581
|
m.hasBorders = false;
|
|
13582
|
+
m.hasControls = false;
|
|
13583
|
+
if (m.__cropGroup || ((_a3 = m._ct) == null ? void 0 : _a3.isCropGroup)) {
|
|
13584
|
+
if (m.__pixldocsOrigLockScalingX === void 0) {
|
|
13585
|
+
m.__pixldocsOrigLockScalingX = m.lockScalingX;
|
|
13586
|
+
m.__pixldocsOrigLockScalingY = m.lockScalingY;
|
|
13587
|
+
}
|
|
13588
|
+
m.lockScalingX = false;
|
|
13589
|
+
m.lockScalingY = false;
|
|
13590
|
+
}
|
|
12583
13591
|
});
|
|
12584
|
-
applyWarpAwareSelectionBorders(selection);
|
|
13592
|
+
if (isPureSingleGroupSelection) applyWarpAwareSelectionBorders(selection);
|
|
12585
13593
|
}
|
|
12586
13594
|
fc.setActiveObject(selection);
|
|
12587
13595
|
if (!isFlatGroupSelection) {
|
|
@@ -12887,7 +13895,7 @@ const PageCanvas = forwardRef(
|
|
|
12887
13895
|
const angleTextPathActive = isTextbox && ((_b = element.textPath) == null ? void 0 : _b.preset) === "rise";
|
|
12888
13896
|
const appliedSkewY = angleTextPathActive ? 0 : element.skewY ?? 0;
|
|
12889
13897
|
let posIfNotSkipped = skipPositionUpdate ? {} : { left: fabricPos.left, top: fabricPos.top };
|
|
12890
|
-
if (!skipPositionUpdate && obj instanceof fabric.FabricImage && obj.originX === "center") {
|
|
13898
|
+
if (!skipPositionUpdate && (obj instanceof fabric.FabricImage && obj.originX === "center" || obj instanceof fabric.Group && obj.__cropGroup)) {
|
|
12891
13899
|
const vW = rW * effectiveScaleX;
|
|
12892
13900
|
const vH = rH * effectiveScaleY;
|
|
12893
13901
|
posIfNotSkipped = { left: fabricPos.left + vW / 2, top: fabricPos.top + vH / 2 };
|
|
@@ -13066,7 +14074,23 @@ const PageCanvas = forwardRef(
|
|
|
13066
14074
|
objectCaching: false,
|
|
13067
14075
|
noScaleCache: true,
|
|
13068
14076
|
splitByGrapheme,
|
|
13069
|
-
text
|
|
14077
|
+
text,
|
|
14078
|
+
// Text outline (stroke). Only apply when BOTH a stroke color and
|
|
14079
|
+
// positive width are explicitly set — otherwise fabric defaults
|
|
14080
|
+
// stroke to black and renders an unwanted outline on existing
|
|
14081
|
+
// text elements that carry a stray strokeWidth.
|
|
14082
|
+
...(() => {
|
|
14083
|
+
const s = element.stroke;
|
|
14084
|
+
const w = Number(element.strokeWidth) || 0;
|
|
14085
|
+
const has = !!s && w > 0;
|
|
14086
|
+
return has ? {
|
|
14087
|
+
stroke: s,
|
|
14088
|
+
strokeWidth: w,
|
|
14089
|
+
paintFirst: element.paintFirst || "fill",
|
|
14090
|
+
strokeUniform: true,
|
|
14091
|
+
strokeLineJoin: "round"
|
|
14092
|
+
} : { stroke: void 0, strokeWidth: 0 };
|
|
14093
|
+
})()
|
|
13070
14094
|
});
|
|
13071
14095
|
const valign = element.verticalAlign || "top";
|
|
13072
14096
|
const minBoxH = Math.max(0, Number(element.minBoxHeight) || 0);
|
|
@@ -13722,7 +14746,10 @@ const PageCanvas = forwardRef(
|
|
|
13722
14746
|
let panX = element.cropPanX ?? 0.5;
|
|
13723
14747
|
let panY = element.cropPanY ?? 0.5;
|
|
13724
14748
|
let zoom2 = element.cropZoom ?? 1;
|
|
13725
|
-
|
|
14749
|
+
const elementHasExplicitCrop = element.cropPanX != null || element.cropPanY != null || element.cropZoom != null;
|
|
14750
|
+
const existingGroupSource = existingCropGroup ? String(existingCropGroup.__imageSrc || "") : "";
|
|
14751
|
+
const canPreserveLiveCrop = Boolean(existingCropGroup) && (elementHasExplicitCrop || existingGroupSource === imageUrl);
|
|
14752
|
+
if (canPreserveLiveCrop && existingCropGroup) {
|
|
13726
14753
|
const existingImg = (_j = existingCropGroup.__cropData) == null ? void 0 : _j._img;
|
|
13727
14754
|
if (existingImg) {
|
|
13728
14755
|
panX = ((_k = existingImg._ct) == null ? void 0 : _k.panX) ?? existingImg.__panX ?? panX;
|
|
@@ -15063,6 +16090,19 @@ function setInTree(nodes, elementId, targetProperty, value) {
|
|
|
15063
16090
|
} else if (targetProperty === "text" && node.type === "text" && typeof value === "string") {
|
|
15064
16091
|
const textVal = value === "" ? " " : value;
|
|
15065
16092
|
node[targetProperty] = applyTextCase(textVal, node.textCase);
|
|
16093
|
+
} else if ((targetProperty === "src" || targetProperty === "imageUrl") && node.type === "image") {
|
|
16094
|
+
const previousSrc = String(node.src || node.imageUrl || "");
|
|
16095
|
+
const nextSrc = String(value ?? "");
|
|
16096
|
+
const srcChanged = nextSrc !== "" && nextSrc !== previousSrc;
|
|
16097
|
+
node.src = value;
|
|
16098
|
+
node.imageUrl = value;
|
|
16099
|
+
if (srcChanged) {
|
|
16100
|
+
delete node.imageNaturalWidth;
|
|
16101
|
+
delete node.imageNaturalHeight;
|
|
16102
|
+
delete node.cropPanX;
|
|
16103
|
+
delete node.cropPanY;
|
|
16104
|
+
delete node.cropZoom;
|
|
16105
|
+
}
|
|
15066
16106
|
} else {
|
|
15067
16107
|
node[targetProperty] = value;
|
|
15068
16108
|
}
|
|
@@ -15072,10 +16112,6 @@ function setInTree(nodes, elementId, targetProperty, value) {
|
|
|
15072
16112
|
delete node.height;
|
|
15073
16113
|
}
|
|
15074
16114
|
}
|
|
15075
|
-
if ((targetProperty === "src" || targetProperty === "imageUrl") && node.type === "image") {
|
|
15076
|
-
delete node.imageNaturalWidth;
|
|
15077
|
-
delete node.imageNaturalHeight;
|
|
15078
|
-
}
|
|
15079
16115
|
return true;
|
|
15080
16116
|
}
|
|
15081
16117
|
if (node.children && Array.isArray(node.children)) {
|
|
@@ -19863,10 +20899,11 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
19863
20899
|
for (const obj of objs) {
|
|
19864
20900
|
const isGroupLike = obj instanceof fabric.Group || (obj == null ? void 0 : obj.type) === "group" || Array.isArray(obj == null ? void 0 : obj._objects);
|
|
19865
20901
|
const isFadedCropGroup = isGroupLike && (Boolean(obj.__edgeFadeRenderConfig) || Boolean(obj.__edgeFadeKey) || Boolean(obj.__edgeFadeInputKey));
|
|
19866
|
-
|
|
20902
|
+
const hasSvgMaskClip = isGroupLike && obj.__cropGroup && obj.clipPath && (obj.clipPath.__svgMask === true || obj.clipPath.__svgMaskUrl || obj.clipPath.__svgMaskType || obj.__svgMaskUrl || obj.__svgMaskType);
|
|
20903
|
+
if (!isFadedCropGroup && !hasSvgMaskClip) continue;
|
|
19867
20904
|
try {
|
|
19868
20905
|
const baked = obj.toCanvasElement({
|
|
19869
|
-
multiplier: 2,
|
|
20906
|
+
multiplier: hasSvgMaskClip ? 4 : 2,
|
|
19870
20907
|
enableRetinaScaling: false
|
|
19871
20908
|
});
|
|
19872
20909
|
const rect = obj.getBoundingRect();
|
|
@@ -19939,9 +20976,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
19939
20976
|
}
|
|
19940
20977
|
return svgString;
|
|
19941
20978
|
}
|
|
19942
|
-
const resolvedPackageVersion = "0.5.
|
|
20979
|
+
const resolvedPackageVersion = "0.5.226";
|
|
19943
20980
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
19944
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
20981
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.226";
|
|
19945
20982
|
const roundParityValue = (value) => {
|
|
19946
20983
|
if (typeof value !== "number") return value;
|
|
19947
20984
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -20685,7 +21722,7 @@ class PixldocsRenderer {
|
|
|
20685
21722
|
await this.waitForCanvasScene(container, cloned, i);
|
|
20686
21723
|
}
|
|
20687
21724
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
20688
|
-
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-
|
|
21725
|
+
const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-DVspHEZh.js");
|
|
20689
21726
|
const prepared = preparePagesForExport(
|
|
20690
21727
|
cloned.pages,
|
|
20691
21728
|
canvasWidth,
|
|
@@ -23005,7 +24042,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
23005
24042
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
23006
24043
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
23007
24044
|
try {
|
|
23008
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-
|
|
24045
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-DVspHEZh.js");
|
|
23009
24046
|
try {
|
|
23010
24047
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
23011
24048
|
} catch {
|
|
@@ -23404,4 +24441,4 @@ export {
|
|
|
23404
24441
|
buildTeaserBlurFlatKeys as y,
|
|
23405
24442
|
collectFontDescriptorsFromConfig as z
|
|
23406
24443
|
};
|
|
23407
|
-
//# sourceMappingURL=index-
|
|
24444
|
+
//# sourceMappingURL=index-ZjC8BLGn.js.map
|