@pixldocs/canvas-renderer 0.5.393 → 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]
@@ -13582,15 +13588,7 @@ 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 = 2;
13586
- const norm = (a) => {
13587
- const n = (a % 360 + 360) % 360;
13588
- return n > 180 ? n - 360 : n;
13589
- };
13590
- const angleDelta = (a, b) => {
13591
- const d = Math.abs(norm(a) - norm(b));
13592
- return Math.min(d, 360 - d);
13593
- };
13591
+ const savedGroupAngle = typeof g.angle === "number" && Number.isFinite(g.angle) ? normalizeAngle180(g.angle) : null;
13594
13592
  const worldPoints = [];
13595
13593
  for (const m of members) {
13596
13594
  (_a2 = m.setCoords) == null ? void 0 : _a2.call(m);
@@ -13601,31 +13599,35 @@ const PageCanvas = react.forwardRef(
13601
13599
  if (p) worldPoints.push({ x: p.x, y: p.y });
13602
13600
  }
13603
13601
  }
13604
- const orientedAreaForAngle = (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;
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 });
13616
13625
  }
13617
- return Math.max(1, (xX - nX) * (xY - nY));
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;
13618
13629
  };
13619
- const buckets = [];
13620
- for (const m of members) {
13621
- const a = norm(m.angle ?? 0);
13622
- const b = buckets.find((x) => angleDelta(x.angle, a) <= TOL);
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 = orientedAreaForAngle(b.angle);
13627
- buckets.sort((a, b) => b.count - a.count || a.area - b.area || Math.abs(b.angle) - Math.abs(a.angle));
13628
- const a0 = buckets[0].angle;
13630
+ const a0 = savedGroupAngle ?? getLegacyDominantAngle();
13629
13631
  const rad = -a0 * Math.PI / 180;
13630
13632
  const cos = Math.cos(rad), sin = Math.sin(rad);
13631
13633
  let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
@@ -15369,6 +15371,14 @@ const PageCanvas = react.forwardRef(
15369
15371
  360 - Math.abs(currentSelAngle - startSelAngle)
15370
15372
  );
15371
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
+ }
15372
15382
  if (!hadScale && !hadRotation && (Math.abs(deltaX) > 0.1 || Math.abs(deltaY) > 0.1)) {
15373
15383
  const { updateNode: updateNodeStore, commitHistory: commitHistoryStore, getCurrentElements } = useEditorStore.getState();
15374
15384
  const newLeft = (groupToMove.left ?? 0) + deltaX;
@@ -25115,9 +25125,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
25115
25125
  }
25116
25126
  return svgString;
25117
25127
  }
25118
- const resolvedPackageVersion = "0.5.393";
25128
+ const resolvedPackageVersion = "0.5.394";
25119
25129
  const PACKAGE_VERSION = resolvedPackageVersion;
25120
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.393";
25130
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.394";
25121
25131
  const roundParityValue = (value) => {
25122
25132
  if (typeof value !== "number") return value;
25123
25133
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -25931,7 +25941,7 @@ class PixldocsRenderer {
25931
25941
  await this.waitForCanvasScene(container, cloned, i);
25932
25942
  }
25933
25943
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
25934
- const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-BWhYgu3c.cjs"));
25944
+ const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-RJHpxl55.cjs"));
25935
25945
  const prepared = preparePagesForExport(
25936
25946
  cloned.pages,
25937
25947
  canvasWidth,
@@ -28251,7 +28261,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
28251
28261
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
28252
28262
  sanitizeSvgTreeForPdf(svgToDraw);
28253
28263
  try {
28254
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-BWhYgu3c.cjs"));
28264
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-RJHpxl55.cjs"));
28255
28265
  try {
28256
28266
  await logTextMeasurementDiagnostic(svgToDraw);
28257
28267
  } catch {
@@ -28648,4 +28658,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
28648
28658
  exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
28649
28659
  exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
28650
28660
  exports.warmTemplateFromForm = warmTemplateFromForm;
28651
- //# sourceMappingURL=index-B0Ej1RxQ.cjs.map
28661
+ //# sourceMappingURL=index-mH5LwfhM.cjs.map