@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.
@@ -10520,6 +10520,10 @@ function bakeEdgeFade(source, fade) {
10520
10520
  }
10521
10521
  const SELECTION_PRIMARY = "hsl(217, 91%, 60%)";
10522
10522
  const SELECTION_BORDER_SCALE = 2;
10523
+ const normalizeAngle180 = (angle) => {
10524
+ const n = (angle % 360 + 360) % 360;
10525
+ return n > 180 ? n - 360 : n;
10526
+ };
10523
10527
  let ensureCanvaControlRenders = () => {
10524
10528
  };
10525
10529
  try {
@@ -11450,7 +11454,7 @@ const bakeTextboxScaleIntoTypography = (obj, sourceElement) => {
11450
11454
  };
11451
11455
  return updates;
11452
11456
  };
11453
- function applyWarpAwareSelectionBorders(selection) {
11457
+ function applyWarpAwareSelectionBorders(selection, preferredGroupAngle) {
11454
11458
  var _a2;
11455
11459
  if (selection.__pixldocsOrigASHasBorders !== void 0) {
11456
11460
  selection.hasBorders = selection.__pixldocsOrigASHasBorders;
@@ -11462,17 +11466,13 @@ function applyWarpAwareSelectionBorders(selection) {
11462
11466
  if (selection.__pixldocsAlignedAngle == null) {
11463
11467
  const kids = selection.getObjects();
11464
11468
  if (kids.length >= 1) {
11465
- const norm = (a) => {
11466
- const n = (a % 360 + 360) % 360;
11467
- return n > 180 ? n - 360 : n;
11468
- };
11469
- const angleDelta = (a, b) => Math.abs(norm(a - b));
11469
+ const angleDelta = (a, b) => Math.abs(normalizeAngle180(a - b));
11470
11470
  const selectionMatrix = selection.calcTransformMatrix();
11471
11471
  const worldMatrices = kids.map((k) => fabric__namespace.util.multiplyTransformMatrices(
11472
11472
  selectionMatrix,
11473
11473
  k.calcOwnMatrix()
11474
11474
  ));
11475
- const worldAngles = worldMatrices.map((m) => norm(fabric__namespace.util.qrDecompose(m).angle ?? 0));
11475
+ const worldAngles = worldMatrices.map((m) => normalizeAngle180(fabric__namespace.util.qrDecompose(m).angle ?? 0));
11476
11476
  const worldPoints = [];
11477
11477
  for (const k of kids) {
11478
11478
  try {
@@ -11517,9 +11517,10 @@ function applyWarpAwareSelectionBorders(selection) {
11517
11517
  for (const b of buckets) b.area = orientedAreaForAngle(b.angle);
11518
11518
  buckets.sort((a, b) => b.count - a.count || a.area - b.area || Math.abs(b.angle) - Math.abs(a.angle));
11519
11519
  const dominant = buckets[0];
11520
- let targetAngle = null;
11520
+ const preferredAngle = typeof preferredGroupAngle === "number" && Number.isFinite(preferredGroupAngle) ? normalizeAngle180(preferredGroupAngle) : null;
11521
+ let targetAngle = preferredAngle;
11521
11522
  const isLogicalGroupSelection = !!selection.__pixldocsGroupSelection;
11522
- if (dominant && Math.abs(dominant.angle) > 0.5 && (isLogicalGroupSelection || kids.length === 1 || dominant.count >= 2 || dominant.count === kids.length)) {
11523
+ if (targetAngle == null && dominant && Math.abs(dominant.angle) > 0.5 && (isLogicalGroupSelection || kids.length === 1 || dominant.count >= 2 || dominant.count === kids.length)) {
11523
11524
  targetAngle = dominant.angle;
11524
11525
  }
11525
11526
  if (targetAngle != null) {
@@ -11656,6 +11657,11 @@ const PageCanvas = react.forwardRef(
11656
11657
  var _a2;
11657
11658
  selection.__pixldocsGroupSelection = groupId;
11658
11659
  delete selection.__pixldocsLogicalGroupIds;
11660
+ const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
11661
+ const groupNode = pageNow ? findNodeById(pageNow.children ?? [], groupId) : null;
11662
+ const groupAngle = groupNode && isGroup(groupNode) && typeof groupNode.angle === "number" ? groupNode.angle : void 0;
11663
+ if (groupAngle !== void 0) selection.__pixldocsGroupAngle = groupAngle;
11664
+ else delete selection.__pixldocsGroupAngle;
11659
11665
  selection.hasBorders = true;
11660
11666
  const members = selection.getObjects();
11661
11667
  for (const prev of suppressGroupMemberBordersRef.current) {
@@ -11689,8 +11695,8 @@ const PageCanvas = react.forwardRef(
11689
11695
  m.lockScalingY = false;
11690
11696
  }
11691
11697
  }
11692
- applyWarpAwareSelectionBorders(selection);
11693
- }, []);
11698
+ applyWarpAwareSelectionBorders(selection, groupAngle);
11699
+ }, [pageId]);
11694
11700
  const pageBoundsOptions = react.useMemo(
11695
11701
  () => ({ pageContentWidth: canvasWidth, pageContentHeight: canvasHeight }),
11696
11702
  [canvasWidth, canvasHeight]
@@ -13573,7 +13579,7 @@ const PageCanvas = react.forwardRef(
13573
13579
  return { left: minX, top: minY, right: maxX, bottom: maxY };
13574
13580
  };
13575
13581
  const groupFabricOrientedBBox = (g) => {
13576
- var _a2;
13582
+ var _a2, _b2;
13577
13583
  const memberIds = new Set(getAllElementIds(g.children ?? []));
13578
13584
  if (memberIds.size === 0) return null;
13579
13585
  const members = [];
@@ -13582,25 +13588,52 @@ const PageCanvas = react.forwardRef(
13582
13588
  if (oid && memberIds.has(oid)) members.push(o);
13583
13589
  }
13584
13590
  if (members.length === 0) return null;
13585
- const TOL = 0.5;
13586
- const buckets = [];
13591
+ const savedGroupAngle = typeof g.angle === "number" && Number.isFinite(g.angle) ? normalizeAngle180(g.angle) : null;
13592
+ const worldPoints = [];
13587
13593
  for (const m of members) {
13588
- const a = ((m.angle ?? 0) % 360 + 360) % 360;
13589
- const b = buckets.find((x) => {
13590
- const d = Math.min(Math.abs(x.angle - a), 360 - Math.abs(x.angle - a));
13591
- return d <= TOL;
13592
- });
13593
- if (b) b.count++;
13594
- else buckets.push({ angle: a, count: 1 });
13594
+ (_a2 = m.setCoords) == null ? void 0 : _a2.call(m);
13595
+ const aC = m.aCoords;
13596
+ if (!aC) continue;
13597
+ for (const k of ["tl", "tr", "br", "bl"]) {
13598
+ const p = aC[k];
13599
+ if (p) worldPoints.push({ x: p.x, y: p.y });
13600
+ }
13595
13601
  }
13596
- buckets.sort((a, b) => b.count - a.count);
13597
- const a0 = buckets[0].angle;
13602
+ const getLegacyDominantAngle = () => {
13603
+ var _a3;
13604
+ const areaFor = (angle) => {
13605
+ if (worldPoints.length === 0) return Number.POSITIVE_INFINITY;
13606
+ const r = -angle * Math.PI / 180;
13607
+ const c = Math.cos(r), s = Math.sin(r);
13608
+ let nX = Infinity, nY = Infinity, xX = -Infinity, xY = -Infinity;
13609
+ for (const p of worldPoints) {
13610
+ const xr = p.x * c - p.y * s;
13611
+ const yr = p.x * s + p.y * c;
13612
+ if (xr < nX) nX = xr;
13613
+ if (yr < nY) nY = yr;
13614
+ if (xr > xX) xX = xr;
13615
+ if (yr > xY) xY = yr;
13616
+ }
13617
+ return Math.max(1, (xX - nX) * (xY - nY));
13618
+ };
13619
+ const buckets = [];
13620
+ for (const m of members) {
13621
+ const a = normalizeAngle180(m.angle ?? 0);
13622
+ const b = buckets.find((x) => Math.abs(normalizeAngle180(x.angle - a)) <= 2);
13623
+ if (b) b.count++;
13624
+ else buckets.push({ angle: a, count: 1, area: Number.POSITIVE_INFINITY });
13625
+ }
13626
+ for (const b of buckets) b.area = areaFor(b.angle);
13627
+ buckets.sort((a, b) => b.count - a.count || a.area - b.area || Math.abs(b.angle) - Math.abs(a.angle));
13628
+ return ((_a3 = buckets[0]) == null ? void 0 : _a3.angle) ?? 0;
13629
+ };
13630
+ const a0 = savedGroupAngle ?? getLegacyDominantAngle();
13598
13631
  const rad = -a0 * Math.PI / 180;
13599
13632
  const cos = Math.cos(rad), sin = Math.sin(rad);
13600
13633
  let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
13601
13634
  let found = false;
13602
13635
  for (const m of members) {
13603
- (_a2 = m.setCoords) == null ? void 0 : _a2.call(m);
13636
+ (_b2 = m.setCoords) == null ? void 0 : _b2.call(m);
13604
13637
  const aC = m.aCoords;
13605
13638
  if (!aC) continue;
13606
13639
  for (const k of ["tl", "tr", "br", "bl"]) {
@@ -15338,6 +15371,14 @@ const PageCanvas = react.forwardRef(
15338
15371
  360 - Math.abs(currentSelAngle - startSelAngle)
15339
15372
  );
15340
15373
  const hadRotation = isActiveSelection && activeObj && angleDelta > 0.01;
15374
+ if (hadRotation && activeObj instanceof fabric__namespace.ActiveSelection && activeGroupSelectionId === groupToMove.id) {
15375
+ useEditorStore.getState().updateNode(
15376
+ groupToMove.id,
15377
+ { angle: currentSelAngle },
15378
+ { recordHistory: false, skipLayoutRecalc: true }
15379
+ );
15380
+ activeObj.__pixldocsGroupAngle = currentSelAngle;
15381
+ }
15341
15382
  if (!hadScale && !hadRotation && (Math.abs(deltaX) > 0.1 || Math.abs(deltaY) > 0.1)) {
15342
15383
  const { updateNode: updateNodeStore, commitHistory: commitHistoryStore, getCurrentElements } = useEditorStore.getState();
15343
15384
  const newLeft = (groupToMove.left ?? 0) + deltaX;
@@ -25084,9 +25125,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
25084
25125
  }
25085
25126
  return svgString;
25086
25127
  }
25087
- const resolvedPackageVersion = "0.5.392";
25128
+ const resolvedPackageVersion = "0.5.394";
25088
25129
  const PACKAGE_VERSION = resolvedPackageVersion;
25089
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.392";
25130
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.394";
25090
25131
  const roundParityValue = (value) => {
25091
25132
  if (typeof value !== "number") return value;
25092
25133
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -25900,7 +25941,7 @@ class PixldocsRenderer {
25900
25941
  await this.waitForCanvasScene(container, cloned, i);
25901
25942
  }
25902
25943
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
25903
- const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-DhWvQzRg.cjs"));
25944
+ const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-RJHpxl55.cjs"));
25904
25945
  const prepared = preparePagesForExport(
25905
25946
  cloned.pages,
25906
25947
  canvasWidth,
@@ -28220,7 +28261,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
28220
28261
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
28221
28262
  sanitizeSvgTreeForPdf(svgToDraw);
28222
28263
  try {
28223
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-DhWvQzRg.cjs"));
28264
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-RJHpxl55.cjs"));
28224
28265
  try {
28225
28266
  await logTextMeasurementDiagnostic(svgToDraw);
28226
28267
  } catch {
@@ -28617,4 +28658,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
28617
28658
  exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
28618
28659
  exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
28619
28660
  exports.warmTemplateFromForm = warmTemplateFromForm;
28620
- //# sourceMappingURL=index-B0qSXTeJ.cjs.map
28661
+ //# sourceMappingURL=index-mH5LwfhM.cjs.map