@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.
@@ -10574,6 +10574,56 @@ const collectFabricObjectWorldPoints = (objects) => {
10574
10574
  }
10575
10575
  return points;
10576
10576
  };
10577
+ const collectFabricObjectWorldCenters = (objects) => {
10578
+ var _a2;
10579
+ const centers = [];
10580
+ for (const obj of objects) {
10581
+ try {
10582
+ obj.setCoords();
10583
+ } catch {
10584
+ }
10585
+ const coords = typeof obj.getCoords === "function" ? obj.getCoords() : null;
10586
+ if (Array.isArray(coords) && coords.length >= 4) {
10587
+ 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));
10588
+ 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 });
10589
+ continue;
10590
+ }
10591
+ try {
10592
+ const center = (_a2 = obj.getCenterPoint) == null ? void 0 : _a2.call(obj);
10593
+ if (center && Number.isFinite(center.x) && Number.isFinite(center.y)) centers.push({ x: center.x, y: center.y });
10594
+ } catch {
10595
+ }
10596
+ }
10597
+ return centers;
10598
+ };
10599
+ const logicalFrameContainsWorldCenters = (frame, angle, centers) => {
10600
+ if (!isValidLogicalGroupFrame(frame) || centers.length === 0) return true;
10601
+ const a = typeof angle === "number" && Number.isFinite(angle) ? normalizeAngle180(angle) : 0;
10602
+ const cx = frame.left + frame.width / 2;
10603
+ const cy = frame.top + frame.height / 2;
10604
+ const rad = -a * Math.PI / 180;
10605
+ const c = Math.cos(rad);
10606
+ const s = Math.sin(rad);
10607
+ const tolerance = Math.max(8, Math.min(frame.width, frame.height) * 0.08);
10608
+ return centers.every((p) => {
10609
+ const dx = p.x - cx;
10610
+ const dy = p.y - cy;
10611
+ const localX = cx + dx * c - dy * s;
10612
+ const localY = cy + dx * s + dy * c;
10613
+ return localX >= frame.left - tolerance && localX <= frame.left + frame.width + tolerance && localY >= frame.top - tolerance && localY <= frame.top + frame.height + tolerance;
10614
+ });
10615
+ };
10616
+ const shouldRepairUnrotatedLogicalGroupFrame = (storedFrame, contentFrame, angle) => {
10617
+ if (!isValidLogicalGroupFrame(storedFrame) || !isValidLogicalGroupFrame(contentFrame)) return false;
10618
+ if (Math.abs(normalizeAngle180(typeof angle === "number" && Number.isFinite(angle) ? angle : 0)) > 0.5) return false;
10619
+ const storedArea = storedFrame.width * storedFrame.height;
10620
+ const contentArea = contentFrame.width * contentFrame.height;
10621
+ const areaRatio = storedArea / Math.max(1, contentArea);
10622
+ const dx = Math.abs(storedFrame.left + storedFrame.width / 2 - (contentFrame.left + contentFrame.width / 2));
10623
+ const dy = Math.abs(storedFrame.top + storedFrame.height / 2 - (contentFrame.top + contentFrame.height / 2));
10624
+ const driftTolerance = Math.max(12, Math.min(storedFrame.width, storedFrame.height) * 0.08);
10625
+ return areaRatio > 1.35 || dx > driftTolerance || dy > driftTolerance;
10626
+ };
10577
10627
  let ensureCanvaControlRenders = () => {
10578
10628
  };
10579
10629
  try {
@@ -11567,13 +11617,40 @@ function applyWarpAwareSelectionBorders(selection, preferredGroupAngle, preferre
11567
11617
  for (const b of buckets) b.area = orientedAreaForAngle(b.angle);
11568
11618
  buckets.sort((a, b) => b.count - a.count || a.area - b.area || Math.abs(b.angle) - Math.abs(a.angle));
11569
11619
  const dominant = buckets[0];
11570
- const rawPreferredGroupAngle = typeof preferredGroupAngle === "number" && Number.isFinite(preferredGroupAngle) ? preferredGroupAngle : typeof selection.__pixldocsGroupAngle === "number" && Number.isFinite(selection.__pixldocsGroupAngle) ? selection.__pixldocsGroupAngle : null;
11620
+ let effectivePreferredGroupAngle = preferredGroupAngle;
11621
+ let effectivePreferredGroupFrame = preferredGroupFrame;
11622
+ const logicalGroupId = selection.__pixldocsGroupSelection;
11623
+ if (logicalGroupId && (!(typeof effectivePreferredGroupAngle === "number" && Number.isFinite(effectivePreferredGroupAngle)) || !isValidLogicalGroupFrame(effectivePreferredGroupFrame))) {
11624
+ try {
11625
+ const stateNow = useEditorStore.getState();
11626
+ const pageNow = stateNow.canvas.pages.find((p) => p.id === stateNow.canvas.currentPageId);
11627
+ const groupNode = pageNow ? findNodeById(pageNow.children ?? [], logicalGroupId) : null;
11628
+ if (groupNode && isGroup(groupNode)) {
11629
+ if (!(typeof effectivePreferredGroupAngle === "number" && Number.isFinite(effectivePreferredGroupAngle)) && typeof groupNode.angle === "number") {
11630
+ effectivePreferredGroupAngle = groupNode.angle;
11631
+ }
11632
+ if (!isValidLogicalGroupFrame(effectivePreferredGroupFrame)) {
11633
+ effectivePreferredGroupFrame = frameFromStoredGroupNode(groupNode, (pageNow == null ? void 0 : pageNow.children) ?? []);
11634
+ }
11635
+ }
11636
+ } catch {
11637
+ }
11638
+ }
11639
+ const rawPreferredGroupAngle = typeof effectivePreferredGroupAngle === "number" && Number.isFinite(effectivePreferredGroupAngle) ? effectivePreferredGroupAngle : typeof selection.__pixldocsGroupAngle === "number" && Number.isFinite(selection.__pixldocsGroupAngle) ? selection.__pixldocsGroupAngle : null;
11571
11640
  const preferredAngle = rawPreferredGroupAngle != null ? normalizeAngle180(rawPreferredGroupAngle) : null;
11572
11641
  let targetAngle = preferredAngle;
11573
- const isLogicalGroupSelection = !!selection.__pixldocsGroupSelection;
11642
+ const isLogicalGroupSelection = !!logicalGroupId;
11574
11643
  if (targetAngle == null && dominant && Math.abs(dominant.angle) > 0.5 && (isLogicalGroupSelection || kids.length === 1 || dominant.count >= 2 || dominant.count === kids.length)) {
11575
11644
  targetAngle = dominant.angle;
11576
11645
  }
11646
+ if (isLogicalGroupSelection && isValidLogicalGroupFrame(effectivePreferredGroupFrame) && targetAngle != null) {
11647
+ const contentFrame = orientedFrameFromWorldPoints(worldPoints, targetAngle);
11648
+ if (shouldRepairUnrotatedLogicalGroupFrame(effectivePreferredGroupFrame, contentFrame, targetAngle)) {
11649
+ effectivePreferredGroupFrame = contentFrame;
11650
+ } else if (!logicalFrameContainsWorldCenters(effectivePreferredGroupFrame, targetAngle, collectFabricObjectWorldCenters(kids))) {
11651
+ effectivePreferredGroupFrame = null;
11652
+ }
11653
+ }
11577
11654
  if (targetAngle != null) {
11578
11655
  const restoreKidsFromWorld = () => {
11579
11656
  const invSelection = fabric.util.invertTransform(
@@ -11612,7 +11689,7 @@ function applyWarpAwareSelectionBorders(selection, preferredGroupAngle, preferre
11612
11689
  targetAngle,
11613
11690
  worldAngles
11614
11691
  });
11615
- 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;
11692
+ 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;
11616
11693
  selection.set({ angle: targetAngle, scaleX: 1, scaleY: 1, skewX: 0, skewY: 0 });
11617
11694
  if (fixedFrame) {
11618
11695
  selection.set({ width: fixedFrame.width, height: fixedFrame.height, originX: "center", originY: "center" });
@@ -11763,8 +11840,17 @@ const PageCanvas = forwardRef(
11763
11840
  }
11764
11841
  let groupFrame = groupNode && isGroup(groupNode) ? frameFromStoredGroupNode(groupNode, (pageNow == null ? void 0 : pageNow.children) ?? []) : null;
11765
11842
  let groupFrameWasInferred = false;
11843
+ const memberWorldPoints = collectFabricObjectWorldPoints(members);
11844
+ const memberWorldCenters = collectFabricObjectWorldCenters(members);
11845
+ const contentFrame = typeof groupAngle === "number" && Number.isFinite(groupAngle) ? orientedFrameFromWorldPoints(memberWorldPoints, normalizeAngle180(groupAngle)) : null;
11846
+ if (shouldRepairUnrotatedLogicalGroupFrame(groupFrame, contentFrame, groupAngle)) {
11847
+ groupFrame = contentFrame;
11848
+ groupFrameWasInferred = true;
11849
+ } else if (groupFrame && !logicalFrameContainsWorldCenters(groupFrame, groupAngle, memberWorldCenters)) {
11850
+ groupFrame = null;
11851
+ }
11766
11852
  if (!groupFrame && groupNode && isGroup(groupNode) && typeof groupAngle === "number" && Number.isFinite(groupAngle)) {
11767
- groupFrame = orientedFrameFromWorldPoints(collectFabricObjectWorldPoints(members), normalizeAngle180(groupAngle));
11853
+ groupFrame = contentFrame ?? orientedFrameFromWorldPoints(memberWorldPoints, normalizeAngle180(groupAngle));
11768
11854
  groupFrameWasInferred = isValidLogicalGroupFrame(groupFrame);
11769
11855
  }
11770
11856
  if (groupNode && isGroup(groupNode)) {
@@ -25333,9 +25419,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
25333
25419
  }
25334
25420
  return svgString;
25335
25421
  }
25336
- const resolvedPackageVersion = "0.5.396";
25422
+ const resolvedPackageVersion = "0.5.397";
25337
25423
  const PACKAGE_VERSION = resolvedPackageVersion;
25338
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.396";
25424
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.397";
25339
25425
  const roundParityValue = (value) => {
25340
25426
  if (typeof value !== "number") return value;
25341
25427
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -26149,7 +26235,7 @@ class PixldocsRenderer {
26149
26235
  await this.waitForCanvasScene(container, cloned, i);
26150
26236
  }
26151
26237
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
26152
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-RZWtHBw4.js");
26238
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-EYMFI-uk.js");
26153
26239
  const prepared = preparePagesForExport(
26154
26240
  cloned.pages,
26155
26241
  canvasWidth,
@@ -28469,7 +28555,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
28469
28555
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
28470
28556
  sanitizeSvgTreeForPdf(svgToDraw);
28471
28557
  try {
28472
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-RZWtHBw4.js");
28558
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-EYMFI-uk.js");
28473
28559
  try {
28474
28560
  await logTextMeasurementDiagnostic(svgToDraw);
28475
28561
  } catch {
@@ -28869,4 +28955,4 @@ export {
28869
28955
  buildTeaserBlurFlatKeys as y,
28870
28956
  collectFontDescriptorsFromConfig as z
28871
28957
  };
28872
- //# sourceMappingURL=index-BTGqkKaE.js.map
28958
+ //# sourceMappingURL=index-CqOZyZpi.js.map