@pixldocs/canvas-renderer 0.5.396 → 0.5.397

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.
@@ -10592,6 +10592,56 @@ const collectFabricObjectWorldPoints = (objects) => {
10592
10592
  }
10593
10593
  return points;
10594
10594
  };
10595
+ const collectFabricObjectWorldCenters = (objects) => {
10596
+ var _a2;
10597
+ const centers = [];
10598
+ for (const obj of objects) {
10599
+ try {
10600
+ obj.setCoords();
10601
+ } catch {
10602
+ }
10603
+ const coords = typeof obj.getCoords === "function" ? obj.getCoords() : null;
10604
+ if (Array.isArray(coords) && coords.length >= 4) {
10605
+ const pts = coords.slice(0, 4).map((p) => ({ x: Number(p.x), y: Number(p.y) })).filter((p) => Number.isFinite(p.x) && Number.isFinite(p.y));
10606
+ if (pts.length) centers.push({ x: pts.reduce((sum, p) => sum + p.x, 0) / pts.length, y: pts.reduce((sum, p) => sum + p.y, 0) / pts.length });
10607
+ continue;
10608
+ }
10609
+ try {
10610
+ const center = (_a2 = obj.getCenterPoint) == null ? void 0 : _a2.call(obj);
10611
+ if (center && Number.isFinite(center.x) && Number.isFinite(center.y)) centers.push({ x: center.x, y: center.y });
10612
+ } catch {
10613
+ }
10614
+ }
10615
+ return centers;
10616
+ };
10617
+ const logicalFrameContainsWorldCenters = (frame, angle, centers) => {
10618
+ if (!isValidLogicalGroupFrame(frame) || centers.length === 0) return true;
10619
+ const a = typeof angle === "number" && Number.isFinite(angle) ? normalizeAngle180(angle) : 0;
10620
+ const cx = frame.left + frame.width / 2;
10621
+ const cy = frame.top + frame.height / 2;
10622
+ const rad = -a * Math.PI / 180;
10623
+ const c = Math.cos(rad);
10624
+ const s = Math.sin(rad);
10625
+ const tolerance = Math.max(8, Math.min(frame.width, frame.height) * 0.08);
10626
+ return centers.every((p) => {
10627
+ const dx = p.x - cx;
10628
+ const dy = p.y - cy;
10629
+ const localX = cx + dx * c - dy * s;
10630
+ const localY = cy + dx * s + dy * c;
10631
+ return localX >= frame.left - tolerance && localX <= frame.left + frame.width + tolerance && localY >= frame.top - tolerance && localY <= frame.top + frame.height + tolerance;
10632
+ });
10633
+ };
10634
+ const shouldRepairUnrotatedLogicalGroupFrame = (storedFrame, contentFrame, angle) => {
10635
+ if (!isValidLogicalGroupFrame(storedFrame) || !isValidLogicalGroupFrame(contentFrame)) return false;
10636
+ if (Math.abs(normalizeAngle180(typeof angle === "number" && Number.isFinite(angle) ? angle : 0)) > 0.5) return false;
10637
+ const storedArea = storedFrame.width * storedFrame.height;
10638
+ const contentArea = contentFrame.width * contentFrame.height;
10639
+ const areaRatio = storedArea / Math.max(1, contentArea);
10640
+ const dx = Math.abs(storedFrame.left + storedFrame.width / 2 - (contentFrame.left + contentFrame.width / 2));
10641
+ const dy = Math.abs(storedFrame.top + storedFrame.height / 2 - (contentFrame.top + contentFrame.height / 2));
10642
+ const driftTolerance = Math.max(12, Math.min(storedFrame.width, storedFrame.height) * 0.08);
10643
+ return areaRatio > 1.35 || dx > driftTolerance || dy > driftTolerance;
10644
+ };
10595
10645
  let ensureCanvaControlRenders = () => {
10596
10646
  };
10597
10647
  try {
@@ -11585,13 +11635,40 @@ function applyWarpAwareSelectionBorders(selection, preferredGroupAngle, preferre
11585
11635
  for (const b of buckets) b.area = orientedAreaForAngle(b.angle);
11586
11636
  buckets.sort((a, b) => b.count - a.count || a.area - b.area || Math.abs(b.angle) - Math.abs(a.angle));
11587
11637
  const dominant = buckets[0];
11588
- const rawPreferredGroupAngle = typeof preferredGroupAngle === "number" && Number.isFinite(preferredGroupAngle) ? preferredGroupAngle : typeof selection.__pixldocsGroupAngle === "number" && Number.isFinite(selection.__pixldocsGroupAngle) ? selection.__pixldocsGroupAngle : null;
11638
+ let effectivePreferredGroupAngle = preferredGroupAngle;
11639
+ let effectivePreferredGroupFrame = preferredGroupFrame;
11640
+ const logicalGroupId = selection.__pixldocsGroupSelection;
11641
+ if (logicalGroupId && (!(typeof effectivePreferredGroupAngle === "number" && Number.isFinite(effectivePreferredGroupAngle)) || !isValidLogicalGroupFrame(effectivePreferredGroupFrame))) {
11642
+ try {
11643
+ const stateNow = useEditorStore.getState();
11644
+ const pageNow = stateNow.canvas.pages.find((p) => p.id === stateNow.canvas.currentPageId);
11645
+ const groupNode = pageNow ? findNodeById(pageNow.children ?? [], logicalGroupId) : null;
11646
+ if (groupNode && isGroup(groupNode)) {
11647
+ if (!(typeof effectivePreferredGroupAngle === "number" && Number.isFinite(effectivePreferredGroupAngle)) && typeof groupNode.angle === "number") {
11648
+ effectivePreferredGroupAngle = groupNode.angle;
11649
+ }
11650
+ if (!isValidLogicalGroupFrame(effectivePreferredGroupFrame)) {
11651
+ effectivePreferredGroupFrame = frameFromStoredGroupNode(groupNode, (pageNow == null ? void 0 : pageNow.children) ?? []);
11652
+ }
11653
+ }
11654
+ } catch {
11655
+ }
11656
+ }
11657
+ const rawPreferredGroupAngle = typeof effectivePreferredGroupAngle === "number" && Number.isFinite(effectivePreferredGroupAngle) ? effectivePreferredGroupAngle : typeof selection.__pixldocsGroupAngle === "number" && Number.isFinite(selection.__pixldocsGroupAngle) ? selection.__pixldocsGroupAngle : null;
11589
11658
  const preferredAngle = rawPreferredGroupAngle != null ? normalizeAngle180(rawPreferredGroupAngle) : null;
11590
11659
  let targetAngle = preferredAngle;
11591
- const isLogicalGroupSelection = !!selection.__pixldocsGroupSelection;
11660
+ const isLogicalGroupSelection = !!logicalGroupId;
11592
11661
  if (targetAngle == null && dominant && Math.abs(dominant.angle) > 0.5 && (isLogicalGroupSelection || kids.length === 1 || dominant.count >= 2 || dominant.count === kids.length)) {
11593
11662
  targetAngle = dominant.angle;
11594
11663
  }
11664
+ if (isLogicalGroupSelection && isValidLogicalGroupFrame(effectivePreferredGroupFrame) && targetAngle != null) {
11665
+ const contentFrame = orientedFrameFromWorldPoints(worldPoints, targetAngle);
11666
+ if (shouldRepairUnrotatedLogicalGroupFrame(effectivePreferredGroupFrame, contentFrame, targetAngle)) {
11667
+ effectivePreferredGroupFrame = contentFrame;
11668
+ } else if (!logicalFrameContainsWorldCenters(effectivePreferredGroupFrame, targetAngle, collectFabricObjectWorldCenters(kids))) {
11669
+ effectivePreferredGroupFrame = null;
11670
+ }
11671
+ }
11595
11672
  if (targetAngle != null) {
11596
11673
  const restoreKidsFromWorld = () => {
11597
11674
  const invSelection = fabric__namespace.util.invertTransform(
@@ -11630,7 +11707,7 @@ function applyWarpAwareSelectionBorders(selection, preferredGroupAngle, preferre
11630
11707
  targetAngle,
11631
11708
  worldAngles
11632
11709
  });
11633
- const fixedFrame = preferredGroupFrame && Number.isFinite(preferredGroupFrame.left) && Number.isFinite(preferredGroupFrame.top) && Number.isFinite(preferredGroupFrame.width) && preferredGroupFrame.width > 0 && Number.isFinite(preferredGroupFrame.height) && preferredGroupFrame.height > 0 ? preferredGroupFrame : null;
11710
+ const fixedFrame = effectivePreferredGroupFrame && Number.isFinite(effectivePreferredGroupFrame.left) && Number.isFinite(effectivePreferredGroupFrame.top) && Number.isFinite(effectivePreferredGroupFrame.width) && effectivePreferredGroupFrame.width > 0 && Number.isFinite(effectivePreferredGroupFrame.height) && effectivePreferredGroupFrame.height > 0 ? effectivePreferredGroupFrame : null;
11634
11711
  selection.set({ angle: targetAngle, scaleX: 1, scaleY: 1, skewX: 0, skewY: 0 });
11635
11712
  if (fixedFrame) {
11636
11713
  selection.set({ width: fixedFrame.width, height: fixedFrame.height, originX: "center", originY: "center" });
@@ -11781,8 +11858,17 @@ const PageCanvas = react.forwardRef(
11781
11858
  }
11782
11859
  let groupFrame = groupNode && isGroup(groupNode) ? frameFromStoredGroupNode(groupNode, (pageNow == null ? void 0 : pageNow.children) ?? []) : null;
11783
11860
  let groupFrameWasInferred = false;
11861
+ const memberWorldPoints = collectFabricObjectWorldPoints(members);
11862
+ const memberWorldCenters = collectFabricObjectWorldCenters(members);
11863
+ const contentFrame = typeof groupAngle === "number" && Number.isFinite(groupAngle) ? orientedFrameFromWorldPoints(memberWorldPoints, normalizeAngle180(groupAngle)) : null;
11864
+ if (shouldRepairUnrotatedLogicalGroupFrame(groupFrame, contentFrame, groupAngle)) {
11865
+ groupFrame = contentFrame;
11866
+ groupFrameWasInferred = true;
11867
+ } else if (groupFrame && !logicalFrameContainsWorldCenters(groupFrame, groupAngle, memberWorldCenters)) {
11868
+ groupFrame = null;
11869
+ }
11784
11870
  if (!groupFrame && groupNode && isGroup(groupNode) && typeof groupAngle === "number" && Number.isFinite(groupAngle)) {
11785
- groupFrame = orientedFrameFromWorldPoints(collectFabricObjectWorldPoints(members), normalizeAngle180(groupAngle));
11871
+ groupFrame = contentFrame ?? orientedFrameFromWorldPoints(memberWorldPoints, normalizeAngle180(groupAngle));
11786
11872
  groupFrameWasInferred = isValidLogicalGroupFrame(groupFrame);
11787
11873
  }
11788
11874
  if (groupNode && isGroup(groupNode)) {
@@ -25351,9 +25437,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
25351
25437
  }
25352
25438
  return svgString;
25353
25439
  }
25354
- const resolvedPackageVersion = "0.5.396";
25440
+ const resolvedPackageVersion = "0.5.397";
25355
25441
  const PACKAGE_VERSION = resolvedPackageVersion;
25356
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.396";
25442
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.397";
25357
25443
  const roundParityValue = (value) => {
25358
25444
  if (typeof value !== "number") return value;
25359
25445
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -26167,7 +26253,7 @@ class PixldocsRenderer {
26167
26253
  await this.waitForCanvasScene(container, cloned, i);
26168
26254
  }
26169
26255
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
26170
- const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-oL70Zv8c.cjs"));
26256
+ const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-o6mqay90.cjs"));
26171
26257
  const prepared = preparePagesForExport(
26172
26258
  cloned.pages,
26173
26259
  canvasWidth,
@@ -28487,7 +28573,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
28487
28573
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
28488
28574
  sanitizeSvgTreeForPdf(svgToDraw);
28489
28575
  try {
28490
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-oL70Zv8c.cjs"));
28576
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-o6mqay90.cjs"));
28491
28577
  try {
28492
28578
  await logTextMeasurementDiagnostic(svgToDraw);
28493
28579
  } catch {
@@ -28884,4 +28970,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
28884
28970
  exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
28885
28971
  exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
28886
28972
  exports.warmTemplateFromForm = warmTemplateFromForm;
28887
- //# sourceMappingURL=index-DQYnrYMM.cjs.map
28973
+ //# sourceMappingURL=index-BgYo0VtS.cjs.map