@pixldocs/canvas-renderer 0.5.392 → 0.5.394

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.
@@ -10502,6 +10502,10 @@ function bakeEdgeFade(source, fade) {
10502
10502
  }
10503
10503
  const SELECTION_PRIMARY = "hsl(217, 91%, 60%)";
10504
10504
  const SELECTION_BORDER_SCALE = 2;
10505
+ const normalizeAngle180 = (angle) => {
10506
+ const n = (angle % 360 + 360) % 360;
10507
+ return n > 180 ? n - 360 : n;
10508
+ };
10505
10509
  let ensureCanvaControlRenders = () => {
10506
10510
  };
10507
10511
  try {
@@ -11432,7 +11436,7 @@ const bakeTextboxScaleIntoTypography = (obj, sourceElement) => {
11432
11436
  };
11433
11437
  return updates;
11434
11438
  };
11435
- function applyWarpAwareSelectionBorders(selection) {
11439
+ function applyWarpAwareSelectionBorders(selection, preferredGroupAngle) {
11436
11440
  var _a2;
11437
11441
  if (selection.__pixldocsOrigASHasBorders !== void 0) {
11438
11442
  selection.hasBorders = selection.__pixldocsOrigASHasBorders;
@@ -11444,17 +11448,13 @@ function applyWarpAwareSelectionBorders(selection) {
11444
11448
  if (selection.__pixldocsAlignedAngle == null) {
11445
11449
  const kids = selection.getObjects();
11446
11450
  if (kids.length >= 1) {
11447
- const norm = (a) => {
11448
- const n = (a % 360 + 360) % 360;
11449
- return n > 180 ? n - 360 : n;
11450
- };
11451
- const angleDelta = (a, b) => Math.abs(norm(a - b));
11451
+ const angleDelta = (a, b) => Math.abs(normalizeAngle180(a - b));
11452
11452
  const selectionMatrix = selection.calcTransformMatrix();
11453
11453
  const worldMatrices = kids.map((k) => fabric.util.multiplyTransformMatrices(
11454
11454
  selectionMatrix,
11455
11455
  k.calcOwnMatrix()
11456
11456
  ));
11457
- const worldAngles = worldMatrices.map((m) => norm(fabric.util.qrDecompose(m).angle ?? 0));
11457
+ const worldAngles = worldMatrices.map((m) => normalizeAngle180(fabric.util.qrDecompose(m).angle ?? 0));
11458
11458
  const worldPoints = [];
11459
11459
  for (const k of kids) {
11460
11460
  try {
@@ -11499,9 +11499,10 @@ function applyWarpAwareSelectionBorders(selection) {
11499
11499
  for (const b of buckets) b.area = orientedAreaForAngle(b.angle);
11500
11500
  buckets.sort((a, b) => b.count - a.count || a.area - b.area || Math.abs(b.angle) - Math.abs(a.angle));
11501
11501
  const dominant = buckets[0];
11502
- let targetAngle = null;
11502
+ const preferredAngle = typeof preferredGroupAngle === "number" && Number.isFinite(preferredGroupAngle) ? normalizeAngle180(preferredGroupAngle) : null;
11503
+ let targetAngle = preferredAngle;
11503
11504
  const isLogicalGroupSelection = !!selection.__pixldocsGroupSelection;
11504
- if (dominant && Math.abs(dominant.angle) > 0.5 && (isLogicalGroupSelection || kids.length === 1 || dominant.count >= 2 || dominant.count === kids.length)) {
11505
+ if (targetAngle == null && dominant && Math.abs(dominant.angle) > 0.5 && (isLogicalGroupSelection || kids.length === 1 || dominant.count >= 2 || dominant.count === kids.length)) {
11505
11506
  targetAngle = dominant.angle;
11506
11507
  }
11507
11508
  if (targetAngle != null) {
@@ -11638,6 +11639,11 @@ const PageCanvas = forwardRef(
11638
11639
  var _a2;
11639
11640
  selection.__pixldocsGroupSelection = groupId;
11640
11641
  delete selection.__pixldocsLogicalGroupIds;
11642
+ const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
11643
+ const groupNode = pageNow ? findNodeById(pageNow.children ?? [], groupId) : null;
11644
+ const groupAngle = groupNode && isGroup(groupNode) && typeof groupNode.angle === "number" ? groupNode.angle : void 0;
11645
+ if (groupAngle !== void 0) selection.__pixldocsGroupAngle = groupAngle;
11646
+ else delete selection.__pixldocsGroupAngle;
11641
11647
  selection.hasBorders = true;
11642
11648
  const members = selection.getObjects();
11643
11649
  for (const prev of suppressGroupMemberBordersRef.current) {
@@ -11671,8 +11677,8 @@ const PageCanvas = forwardRef(
11671
11677
  m.lockScalingY = false;
11672
11678
  }
11673
11679
  }
11674
- applyWarpAwareSelectionBorders(selection);
11675
- }, []);
11680
+ applyWarpAwareSelectionBorders(selection, groupAngle);
11681
+ }, [pageId]);
11676
11682
  const pageBoundsOptions = useMemo(
11677
11683
  () => ({ pageContentWidth: canvasWidth, pageContentHeight: canvasHeight }),
11678
11684
  [canvasWidth, canvasHeight]
@@ -13555,7 +13561,7 @@ const PageCanvas = forwardRef(
13555
13561
  return { left: minX, top: minY, right: maxX, bottom: maxY };
13556
13562
  };
13557
13563
  const groupFabricOrientedBBox = (g) => {
13558
- var _a2;
13564
+ var _a2, _b2;
13559
13565
  const memberIds = new Set(getAllElementIds(g.children ?? []));
13560
13566
  if (memberIds.size === 0) return null;
13561
13567
  const members = [];
@@ -13564,25 +13570,52 @@ const PageCanvas = forwardRef(
13564
13570
  if (oid && memberIds.has(oid)) members.push(o);
13565
13571
  }
13566
13572
  if (members.length === 0) return null;
13567
- const TOL = 0.5;
13568
- const buckets = [];
13573
+ const savedGroupAngle = typeof g.angle === "number" && Number.isFinite(g.angle) ? normalizeAngle180(g.angle) : null;
13574
+ const worldPoints = [];
13569
13575
  for (const m of members) {
13570
- const a = ((m.angle ?? 0) % 360 + 360) % 360;
13571
- const b = buckets.find((x) => {
13572
- const d = Math.min(Math.abs(x.angle - a), 360 - Math.abs(x.angle - a));
13573
- return d <= TOL;
13574
- });
13575
- if (b) b.count++;
13576
- else buckets.push({ angle: a, count: 1 });
13576
+ (_a2 = m.setCoords) == null ? void 0 : _a2.call(m);
13577
+ const aC = m.aCoords;
13578
+ if (!aC) continue;
13579
+ for (const k of ["tl", "tr", "br", "bl"]) {
13580
+ const p = aC[k];
13581
+ if (p) worldPoints.push({ x: p.x, y: p.y });
13582
+ }
13577
13583
  }
13578
- buckets.sort((a, b) => b.count - a.count);
13579
- const a0 = buckets[0].angle;
13584
+ const getLegacyDominantAngle = () => {
13585
+ var _a3;
13586
+ const areaFor = (angle) => {
13587
+ if (worldPoints.length === 0) return Number.POSITIVE_INFINITY;
13588
+ const r = -angle * Math.PI / 180;
13589
+ const c = Math.cos(r), s = Math.sin(r);
13590
+ let nX = Infinity, nY = Infinity, xX = -Infinity, xY = -Infinity;
13591
+ for (const p of worldPoints) {
13592
+ const xr = p.x * c - p.y * s;
13593
+ const yr = p.x * s + p.y * c;
13594
+ if (xr < nX) nX = xr;
13595
+ if (yr < nY) nY = yr;
13596
+ if (xr > xX) xX = xr;
13597
+ if (yr > xY) xY = yr;
13598
+ }
13599
+ return Math.max(1, (xX - nX) * (xY - nY));
13600
+ };
13601
+ const buckets = [];
13602
+ for (const m of members) {
13603
+ const a = normalizeAngle180(m.angle ?? 0);
13604
+ const b = buckets.find((x) => Math.abs(normalizeAngle180(x.angle - a)) <= 2);
13605
+ if (b) b.count++;
13606
+ else buckets.push({ angle: a, count: 1, area: Number.POSITIVE_INFINITY });
13607
+ }
13608
+ for (const b of buckets) b.area = areaFor(b.angle);
13609
+ buckets.sort((a, b) => b.count - a.count || a.area - b.area || Math.abs(b.angle) - Math.abs(a.angle));
13610
+ return ((_a3 = buckets[0]) == null ? void 0 : _a3.angle) ?? 0;
13611
+ };
13612
+ const a0 = savedGroupAngle ?? getLegacyDominantAngle();
13580
13613
  const rad = -a0 * Math.PI / 180;
13581
13614
  const cos = Math.cos(rad), sin = Math.sin(rad);
13582
13615
  let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
13583
13616
  let found = false;
13584
13617
  for (const m of members) {
13585
- (_a2 = m.setCoords) == null ? void 0 : _a2.call(m);
13618
+ (_b2 = m.setCoords) == null ? void 0 : _b2.call(m);
13586
13619
  const aC = m.aCoords;
13587
13620
  if (!aC) continue;
13588
13621
  for (const k of ["tl", "tr", "br", "bl"]) {
@@ -15320,6 +15353,14 @@ const PageCanvas = forwardRef(
15320
15353
  360 - Math.abs(currentSelAngle - startSelAngle)
15321
15354
  );
15322
15355
  const hadRotation = isActiveSelection && activeObj && angleDelta > 0.01;
15356
+ if (hadRotation && activeObj instanceof fabric.ActiveSelection && activeGroupSelectionId === groupToMove.id) {
15357
+ useEditorStore.getState().updateNode(
15358
+ groupToMove.id,
15359
+ { angle: currentSelAngle },
15360
+ { recordHistory: false, skipLayoutRecalc: true }
15361
+ );
15362
+ activeObj.__pixldocsGroupAngle = currentSelAngle;
15363
+ }
15323
15364
  if (!hadScale && !hadRotation && (Math.abs(deltaX) > 0.1 || Math.abs(deltaY) > 0.1)) {
15324
15365
  const { updateNode: updateNodeStore, commitHistory: commitHistoryStore, getCurrentElements } = useEditorStore.getState();
15325
15366
  const newLeft = (groupToMove.left ?? 0) + deltaX;
@@ -25066,9 +25107,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
25066
25107
  }
25067
25108
  return svgString;
25068
25109
  }
25069
- const resolvedPackageVersion = "0.5.392";
25110
+ const resolvedPackageVersion = "0.5.394";
25070
25111
  const PACKAGE_VERSION = resolvedPackageVersion;
25071
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.392";
25112
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.394";
25072
25113
  const roundParityValue = (value) => {
25073
25114
  if (typeof value !== "number") return value;
25074
25115
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -25882,7 +25923,7 @@ class PixldocsRenderer {
25882
25923
  await this.waitForCanvasScene(container, cloned, i);
25883
25924
  }
25884
25925
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
25885
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-CRmMt10E.js");
25926
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-BUj20FDX.js");
25886
25927
  const prepared = preparePagesForExport(
25887
25928
  cloned.pages,
25888
25929
  canvasWidth,
@@ -28202,7 +28243,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
28202
28243
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
28203
28244
  sanitizeSvgTreeForPdf(svgToDraw);
28204
28245
  try {
28205
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-CRmMt10E.js");
28246
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-BUj20FDX.js");
28206
28247
  try {
28207
28248
  await logTextMeasurementDiagnostic(svgToDraw);
28208
28249
  } catch {
@@ -28602,4 +28643,4 @@ export {
28602
28643
  buildTeaserBlurFlatKeys as y,
28603
28644
  collectFontDescriptorsFromConfig as z
28604
28645
  };
28605
- //# sourceMappingURL=index-BMosbEqF.js.map
28646
+ //# sourceMappingURL=index-CgnT1WJ6.js.map