@pixldocs/canvas-renderer 0.5.401 → 0.5.403

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.
@@ -11502,15 +11502,17 @@ function applyWarpAwareSelectionBorders(selection) {
11502
11502
  let targetAngle = null;
11503
11503
  const isLogicalGroupSelection = !!selection.__pixldocsGroupSelection;
11504
11504
  const frozenGroupAngle = selection.__pixldocsFrozenGroupAngle;
11505
- if (isLogicalGroupSelection && typeof frozenGroupAngle === "number" && Math.abs(frozenGroupAngle) > 0.5) {
11506
- targetAngle = frozenGroupAngle;
11507
- }
11508
- if (targetAngle == null && dominant && Math.abs(dominant.angle) > 0.5 && // Dominant-angle alignment is required to keep side-handle resize
11509
- // shear-free on rotated children. Without it, Fabric's AS drags
11510
- // along world X/Y while rotated children render in their local
11511
- // frame visible skew. Frozen group angle (when persisted) takes
11512
- // priority above; otherwise fall back to dominant.
11513
- (isLogicalGroupSelection || kids.length === 1 || dominant.count >= 2 || dominant.count === kids.length)) {
11505
+ if (isLogicalGroupSelection) {
11506
+ targetAngle = typeof frozenGroupAngle === "number" ? frozenGroupAngle : 0;
11507
+ }
11508
+ if (targetAngle == null && dominant && Math.abs(dominant.angle) > 0.5 && // Canva-style: a *logical group* bbox is authoritative from the
11509
+ // persisted group.angle only. Individual child rotations must not
11510
+ // drift the group's selection bbox angle. The per-child rotation-
11511
+ // aware reflow (S^-1·R(θ) decomposition) keeps side-handle drags
11512
+ // shear-free on rotated text/image/crop-group kids without needing
11513
+ // the AS itself to tilt.
11514
+ // Ad-hoc multi-select (non-logical) still aligns to dominant.
11515
+ (!isLogicalGroupSelection && (kids.length === 1 || dominant.count >= 2 || dominant.count === kids.length))) {
11514
11516
  targetAngle = dominant.angle;
11515
11517
  }
11516
11518
  if (targetAngle != null) {
@@ -13235,7 +13237,7 @@ const PageCanvas = forwardRef(
13235
13237
  transformingIdsRef.current.clear();
13236
13238
  };
13237
13239
  const prepareGroupSelectionTransformStart = (target) => {
13238
- var _a2, _b2;
13240
+ var _a2, _b2, _c2;
13239
13241
  const active = target instanceof fabric.ActiveSelection ? target : fabricCanvas.getActiveObject();
13240
13242
  if (!(active instanceof fabric.ActiveSelection)) return;
13241
13243
  if (!activeSelectionMoveStartRef.current || activeSelectionMoveStartRef.current.selection !== active) {
@@ -13254,6 +13256,8 @@ const PageCanvas = forwardRef(
13254
13256
  if (!groupNode) return;
13255
13257
  const groupAbs = getAbsoluteBounds(groupNode, pageChildren2);
13256
13258
  const rect = active.getBoundingRect();
13259
+ const currentTransform = fabricCanvas._currentTransform;
13260
+ const originalSelectionAngle = (currentTransform == null ? void 0 : currentTransform.target) === active && typeof ((_c2 = currentTransform == null ? void 0 : currentTransform.original) == null ? void 0 : _c2.angle) === "number" ? currentTransform.original.angle : active.angle ?? 0;
13257
13261
  groupSelectionTransformStartRef.current = {
13258
13262
  groupId,
13259
13263
  selection: active,
@@ -13261,7 +13265,8 @@ const PageCanvas = forwardRef(
13261
13265
  selectionTop: rect.top,
13262
13266
  groupLeft: groupAbs.left,
13263
13267
  groupTop: groupAbs.top,
13264
- selectionAngle: ((active.angle ?? 0) % 360 + 360) % 360
13268
+ selectionAngle: (originalSelectionAngle % 360 + 360) % 360,
13269
+ groupAngle: isGroup(groupNode) ? groupNode.angle ?? 0 : 0
13265
13270
  };
13266
13271
  logRotDriftSelectionSnapshot("transform-start", active, {
13267
13272
  time: Math.round(performance.now()),
@@ -13694,6 +13699,7 @@ const PageCanvas = forwardRef(
13694
13699
  fabricCanvas.__isUserTransforming = true;
13695
13700
  syncLockedRef.current = true;
13696
13701
  lockEdits();
13702
+ prepareGroupSelectionTransformStart(opt.target ?? null);
13697
13703
  }
13698
13704
  let target = opt.target;
13699
13705
  let targetId = target ? getObjectId(target) : null;
@@ -14807,6 +14813,7 @@ const PageCanvas = forwardRef(
14807
14813
  markSimpleTransform(e);
14808
14814
  didTransformRef.current = true;
14809
14815
  const tr = e.target;
14816
+ prepareGroupSelectionTransformStart(tr);
14810
14817
  if (shouldLogRotDriftLiveTick(tr, "rotating")) {
14811
14818
  logRotDriftSelectionSnapshot("rotating", tr, {
14812
14819
  time: Math.round(performance.now()),
@@ -14919,7 +14926,7 @@ const PageCanvas = forwardRef(
14919
14926
  });
14920
14927
  let cropGroupSaveTimer = null;
14921
14928
  fabricCanvas.on("object:modified", (e) => {
14922
- var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j;
14929
+ var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k;
14923
14930
  try {
14924
14931
  if (suppressObjectModifiedDuringInternalReselectRef.current) return;
14925
14932
  dragStarted = false;
@@ -14945,13 +14952,16 @@ const PageCanvas = forwardRef(
14945
14952
  const t = e.target;
14946
14953
  if (t instanceof fabric.ActiveSelection) {
14947
14954
  const gid = t.__pixldocsGroupSelection;
14948
- const delta = ((t.angle ?? 0) + 360) % 360;
14955
+ const transformStart = gid && ((_a2 = groupSelectionTransformStartRef.current) == null ? void 0 : _a2.groupId) === gid && groupSelectionTransformStartRef.current.selection === t ? groupSelectionTransformStartRef.current : null;
14956
+ const current = ((t.angle ?? 0) % 360 + 360) % 360;
14957
+ const start = (((transformStart == null ? void 0 : transformStart.selectionAngle) ?? (transformStart == null ? void 0 : transformStart.groupAngle) ?? 0) % 360 + 360) % 360;
14958
+ const delta = ((current - start) % 360 + 360) % 360;
14949
14959
  const deltaSigned = delta > 180 ? delta - 360 : delta;
14950
14960
  if (gid && Math.abs(deltaSigned) > 0.01) {
14951
14961
  const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
14952
14962
  const node = pageNow ? findNodeById(pageNow.children ?? [], gid) : null;
14953
14963
  if (node && isGroup(node)) {
14954
- const prev = node.angle ?? 0;
14964
+ const prev = (transformStart == null ? void 0 : transformStart.groupAngle) ?? (node.angle ?? 0);
14955
14965
  const next = ((prev + deltaSigned) % 360 + 360) % 360;
14956
14966
  const nextSigned = next > 180 ? next - 360 : next;
14957
14967
  useEditorStore.getState().updateNode(
@@ -14990,7 +15000,7 @@ const PageCanvas = forwardRef(
14990
15000
  const active = fabricCanvas.getActiveObject();
14991
15001
  const activeId = active ? getObjectId(active) : null;
14992
15002
  if (active && activeId && activeId !== "__background__" && !(active instanceof fabric.Group)) {
14993
- const pageChildrenForParent = ((_a2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
15003
+ const pageChildrenForParent = ((_b2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
14994
15004
  const parentGroup = findParentGroup(pageChildrenForParent, activeId);
14995
15005
  if (parentGroup && isGroup(parentGroup) && parentGroup.backgroundColor) {
14996
15006
  let fabricSectionGroup = active.group && active.group instanceof fabric.Group ? active.group : null;
@@ -15072,7 +15082,7 @@ const PageCanvas = forwardRef(
15072
15082
  useEditorStore.getState().reflowStackGroupInPage(pageId, groupId);
15073
15083
  }
15074
15084
  const stateAfter = useEditorStore.getState();
15075
- const pageAfter = ((_b2 = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
15085
+ const pageAfter = ((_c2 = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _c2.children) ?? [];
15076
15086
  const groupNodeAfter = findNodeById(pageAfter, groupId);
15077
15087
  if (groupNodeAfter) {
15078
15088
  const abs = getAbsoluteBounds(groupNodeAfter, pageAfter);
@@ -15134,7 +15144,7 @@ const PageCanvas = forwardRef(
15134
15144
  }
15135
15145
  if (active && active instanceof fabric.Group && active.__docuforgeSectionGroup && getObjectId(active)) {
15136
15146
  const groupId = getObjectId(active);
15137
- const pageChildrenSec = ((_c2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _c2.children) ?? [];
15147
+ const pageChildrenSec = ((_d = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _d.children) ?? [];
15138
15148
  const modifiedTarget2 = e == null ? void 0 : e.target;
15139
15149
  const resizeScaleTarget = lastResizeScaleTargetRef.current;
15140
15150
  lastResizeScaleTargetRef.current = null;
@@ -15165,7 +15175,7 @@ const PageCanvas = forwardRef(
15165
15175
  const node = findNodeById(pageChildrenSec, groupId);
15166
15176
  if (isChildModified && node && !groupMoved) {
15167
15177
  const stateAfter = useEditorStore.getState();
15168
- const pageAfter = ((_d = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _d.children) ?? [];
15178
+ const pageAfter = ((_e = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _e.children) ?? [];
15169
15179
  const groupNodeAfter = findNodeById(pageAfter, groupId);
15170
15180
  if (groupNodeAfter) {
15171
15181
  const abs = getAbsoluteBounds(groupNodeAfter, pageAfter);
@@ -15181,7 +15191,7 @@ const PageCanvas = forwardRef(
15181
15191
  }
15182
15192
  if (active && active instanceof fabric.Group && !(active instanceof fabric.ActiveSelection) && getObjectId(active)) {
15183
15193
  const groupId = getObjectId(active);
15184
- const pageChildren3 = ((_e = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _e.children) ?? [];
15194
+ const pageChildren3 = ((_f = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _f.children) ?? [];
15185
15195
  const w = (active.width ?? 0) * (active.scaleX ?? 1);
15186
15196
  const h = (active.height ?? 0) * (active.scaleY ?? 1);
15187
15197
  const centerX = active.left ?? 0;
@@ -15203,7 +15213,7 @@ const PageCanvas = forwardRef(
15203
15213
  }
15204
15214
  const activeObj = fabricCanvas.getActiveObject();
15205
15215
  let activeObjects = fabricCanvas.getActiveObjects();
15206
- const activeSelectionMoveStart = activeObj instanceof fabric.ActiveSelection && ((_f = activeSelectionMoveStartRef.current) == null ? void 0 : _f.selection) === activeObj ? activeSelectionMoveStartRef.current : null;
15216
+ const activeSelectionMoveStart = activeObj instanceof fabric.ActiveSelection && ((_g = activeSelectionMoveStartRef.current) == null ? void 0 : _g.selection) === activeObj ? activeSelectionMoveStartRef.current : null;
15207
15217
  const activeSelectionDelta = activeObj instanceof fabric.ActiveSelection && activeSelectionMoveStart ? (() => {
15208
15218
  const rect = activeObj.getBoundingRect();
15209
15219
  return {
@@ -15595,7 +15605,7 @@ const PageCanvas = forwardRef(
15595
15605
  const localScaleX = 1 / sx;
15596
15606
  const localScaleY = 1 / sy;
15597
15607
  obj.set({ scaleX: localScaleX, scaleY: localScaleY });
15598
- const selectionMatrix = (_g = activeObj == null ? void 0 : activeObj.calcTransformMatrix) == null ? void 0 : _g.call(activeObj);
15608
+ const selectionMatrix = (_h = activeObj == null ? void 0 : activeObj.calcTransformMatrix) == null ? void 0 : _h.call(activeObj);
15599
15609
  const localCenter = selectionMatrix ? fabric.util.transformPoint(preBakeCenter, fabric.util.invertTransform(selectionMatrix)) : preBakeCenter;
15600
15610
  const localWidth = bakedW * localScaleX;
15601
15611
  const localHeight = bakedH * localScaleY;
@@ -15720,7 +15730,7 @@ const PageCanvas = forwardRef(
15720
15730
  const localScaleX = 1 / sx;
15721
15731
  const localScaleY = 1 / sy;
15722
15732
  obj.set({ scaleX: localScaleX, scaleY: localScaleY });
15723
- const selectionMatrix = (_h = activeObj == null ? void 0 : activeObj.calcTransformMatrix) == null ? void 0 : _h.call(activeObj);
15733
+ const selectionMatrix = (_i = activeObj == null ? void 0 : activeObj.calcTransformMatrix) == null ? void 0 : _i.call(activeObj);
15724
15734
  const localCenter = selectionMatrix ? fabric.util.transformPoint(preBakeCenter, fabric.util.invertTransform(selectionMatrix)) : preBakeCenter;
15725
15735
  const localWidth = bakedWidth * localScaleX;
15726
15736
  const localHeight = (obj.height ?? intrinsicHeight) * localScaleY;
@@ -15928,7 +15938,7 @@ const PageCanvas = forwardRef(
15928
15938
  updateElement(objId, elementUpdate, { recordHistory: false, skipLayoutRecalc: true });
15929
15939
  obj.setCoords();
15930
15940
  }
15931
- const pageChildrenForReflow = ((_i = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _i.children) ?? [];
15941
+ const pageChildrenForReflow = ((_j = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _j.children) ?? [];
15932
15942
  const stackGroupsToReflow = /* @__PURE__ */ new Set();
15933
15943
  for (const id of modifiedIdsThisRound) {
15934
15944
  const parent = findParentGroup(pageChildrenForReflow, id);
@@ -16007,7 +16017,7 @@ const PageCanvas = forwardRef(
16007
16017
  }
16008
16018
  fabricCanvas.setActiveObject(newSel);
16009
16019
  try {
16010
- (_j = newSel.triggerLayout) == null ? void 0 : _j.call(newSel);
16020
+ (_k = newSel.triggerLayout) == null ? void 0 : _k.call(newSel);
16011
16021
  } catch {
16012
16022
  }
16013
16023
  try {
@@ -25117,9 +25127,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
25117
25127
  }
25118
25128
  return svgString;
25119
25129
  }
25120
- const resolvedPackageVersion = "0.5.401";
25130
+ const resolvedPackageVersion = "0.5.403";
25121
25131
  const PACKAGE_VERSION = resolvedPackageVersion;
25122
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.401";
25132
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.403";
25123
25133
  const roundParityValue = (value) => {
25124
25134
  if (typeof value !== "number") return value;
25125
25135
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -25933,7 +25943,7 @@ class PixldocsRenderer {
25933
25943
  await this.waitForCanvasScene(container, cloned, i);
25934
25944
  }
25935
25945
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
25936
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-8uhoJ38-.js");
25946
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-V449U4Y7.js");
25937
25947
  const prepared = preparePagesForExport(
25938
25948
  cloned.pages,
25939
25949
  canvasWidth,
@@ -28253,7 +28263,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
28253
28263
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
28254
28264
  sanitizeSvgTreeForPdf(svgToDraw);
28255
28265
  try {
28256
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-8uhoJ38-.js");
28266
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-V449U4Y7.js");
28257
28267
  try {
28258
28268
  await logTextMeasurementDiagnostic(svgToDraw);
28259
28269
  } catch {
@@ -28653,4 +28663,4 @@ export {
28653
28663
  buildTeaserBlurFlatKeys as y,
28654
28664
  collectFontDescriptorsFromConfig as z
28655
28665
  };
28656
- //# sourceMappingURL=index-B0wcgE-q.js.map
28666
+ //# sourceMappingURL=index-B8c2DkaJ.js.map