@pixldocs/canvas-renderer 0.5.450 → 0.5.452

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.
@@ -5122,7 +5122,13 @@ function localDeltaToWorld(dx, dy, angleDeg) {
5122
5122
  function getWorldAngleDeg(obj) {
5123
5123
  var _a2;
5124
5124
  try {
5125
- if (typeof obj.getTotalAngle === "function") return obj.getTotalAngle() || 0;
5125
+ let total = 0;
5126
+ let cur = obj;
5127
+ while (cur) {
5128
+ total += Number(cur.angle ?? 0) || 0;
5129
+ cur = cur.group;
5130
+ }
5131
+ if (Number.isFinite(total)) return total;
5126
5132
  const matrix = (_a2 = obj.calcTransformMatrix) == null ? void 0 : _a2.call(obj);
5127
5133
  return matrix ? fabric__namespace.util.qrDecompose(matrix).angle || 0 : obj.angle || 0;
5128
5134
  } catch {
@@ -11705,13 +11711,13 @@ const angleDistanceDeg = (a, b) => {
11705
11711
  const delta = Math.abs(((a - b) % 360 + 540) % 360 - 180);
11706
11712
  return Number.isFinite(delta) ? delta : Number.POSITIVE_INFINITY;
11707
11713
  };
11708
- const normalizeMatrixForPersistedFlip = (matrix, persistedFlipX, persistedFlipY, expectedCleanAngle) => {
11714
+ const stripPersistedFlipForStableAngle = (matrix, persistedFlipX, persistedFlipY, expectedCleanAngle) => {
11709
11715
  if (!persistedFlipX && !persistedFlipY) return matrix;
11710
- if (!Number.isFinite(expectedCleanAngle)) return matrix;
11711
- const toggledVisual = toggleLogicalFlipInMatrix(matrix, persistedFlipX, persistedFlipY);
11712
- const cleanIfMatrixAlreadyHasFlip = fabric__namespace.util.qrDecompose(toggleLogicalFlipInMatrix(matrix, persistedFlipX, persistedFlipY)).angle ?? 0;
11713
- const cleanIfMatrixLostFlip = fabric__namespace.util.qrDecompose(matrix).angle ?? 0;
11714
- return angleDistanceDeg(cleanIfMatrixLostFlip, expectedCleanAngle) + 0.1 < angleDistanceDeg(cleanIfMatrixAlreadyHasFlip, expectedCleanAngle) ? toggledVisual : matrix;
11716
+ const toggled = toggleLogicalFlipInMatrix(matrix, persistedFlipX, persistedFlipY);
11717
+ if (!Number.isFinite(expectedCleanAngle)) return toggled;
11718
+ const asIsAngle = fabric__namespace.util.qrDecompose(matrix).angle ?? 0;
11719
+ const toggledAngle = fabric__namespace.util.qrDecompose(toggled).angle ?? 0;
11720
+ return angleDistanceDeg(toggledAngle, expectedCleanAngle) <= angleDistanceDeg(asIsAngle, expectedCleanAngle) ? toggled : matrix;
11715
11721
  };
11716
11722
  function applyWarpAwareSelectionBorders(selection) {
11717
11723
  var _a2;
@@ -14656,7 +14662,7 @@ const PageCanvas = react.forwardRef(
14656
14662
  fabricCanvas.on("selection:cleared", () => {
14657
14663
  });
14658
14664
  fabricCanvas.on("object:scaling", (e) => {
14659
- var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
14665
+ var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
14660
14666
  if (!isActiveRef.current) return;
14661
14667
  const t = e.target;
14662
14668
  if (t) lastResizeScaleTargetRef.current = t;
@@ -14949,9 +14955,19 @@ const PageCanvas = react.forwardRef(
14949
14955
  const liveGestureKey = `${obj.__pixldocsGroupSelection ?? "selection"}:${corner}:${((_k = groupSelectionTransformStartRef.current) == null ? void 0 : _k.selectionLeft) ?? obj.left ?? 0}:${((_l = groupSelectionTransformStartRef.current) == null ? void 0 : _l.selectionTop) ?? obj.top ?? 0}`;
14950
14956
  if (child.__asLiveGestureKey !== liveGestureKey) {
14951
14957
  child.__asLiveGestureKey = liveGestureKey;
14952
- child.__asLiveOrigAngle = Number.isFinite(child.angle) ? child.angle ?? 0 : 0;
14958
+ const childIdForAngle = getObjectId(child);
14959
+ const sourceChildForAngle = childIdForAngle ? elementsRef.current.find((el) => el.id === childIdForAngle) : null;
14960
+ const persistedChildFlipX = (sourceChildForAngle == null ? void 0 : sourceChildForAngle.flipX) ?? child.flipX ?? false;
14961
+ const persistedChildFlipY = (sourceChildForAngle == null ? void 0 : sourceChildForAngle.flipY) ?? child.flipY ?? false;
14962
+ const isFlippedImageLikeChild = (child instanceof fabric__namespace.FabricImage || child instanceof fabric__namespace.Group && (child.__cropGroup || ((_m = child._ct) == null ? void 0 : _m.isCropGroup))) && !!(persistedChildFlipX || persistedChildFlipY) && Number.isFinite(sourceChildForAngle == null ? void 0 : sourceChildForAngle.angle);
14963
+ if (child instanceof fabric__namespace.FabricImage || child instanceof fabric__namespace.Group && (child.__cropGroup || ((_n = child._ct) == null ? void 0 : _n.isCropGroup))) {
14964
+ child.set({ flipX: persistedChildFlipX, flipY: persistedChildFlipY });
14965
+ child.__asLivePersistedFlipX = persistedChildFlipX;
14966
+ child.__asLivePersistedFlipY = persistedChildFlipY;
14967
+ }
14968
+ child.__asLiveOrigAngle = isFlippedImageLikeChild ? sourceChildForAngle.angle ?? 0 : Number.isFinite(child.angle) ? child.angle ?? 0 : 0;
14953
14969
  }
14954
- if (child instanceof fabric__namespace.Group && (child.__cropGroup || ((_m = child._ct) == null ? void 0 : _m.isCropGroup))) {
14970
+ if (child instanceof fabric__namespace.Group && (child.__cropGroup || ((_o = child._ct) == null ? void 0 : _o.isCropGroup))) {
14955
14971
  const ct = child.__cropData;
14956
14972
  if (!ct) continue;
14957
14973
  if (child.__asLiveOrigAngle == null) {
@@ -15003,6 +15019,8 @@ const PageCanvas = react.forwardRef(
15003
15019
  child._set("scaleY", decC.scaleY);
15004
15020
  child._set("skewX", decC.skewX);
15005
15021
  child._set("skewY", decC.skewY);
15022
+ child._set("flipX", child.__asLivePersistedFlipX ?? child.flipX ?? false);
15023
+ child._set("flipY", child.__asLivePersistedFlipY ?? child.flipY ?? false);
15006
15024
  } catch {
15007
15025
  }
15008
15026
  try {
@@ -15060,6 +15078,8 @@ const PageCanvas = react.forwardRef(
15060
15078
  child._set("scaleY", decI.scaleY);
15061
15079
  child._set("skewX", decI.skewX);
15062
15080
  child._set("skewY", decI.skewY);
15081
+ child._set("flipX", child.__asLivePersistedFlipX ?? child.flipX ?? false);
15082
+ child._set("flipY", child.__asLivePersistedFlipY ?? child.flipY ?? false);
15063
15083
  } catch {
15064
15084
  }
15065
15085
  child.setCoords();
@@ -15120,7 +15140,7 @@ const PageCanvas = react.forwardRef(
15120
15140
  child.dirty = true;
15121
15141
  didReflowTextChild = true;
15122
15142
  }
15123
- if (isXSide && ((_n = groupShiftReflowSnapshotRef.current) == null ? void 0 : _n.selection) === obj) {
15143
+ if (isXSide && ((_p = groupShiftReflowSnapshotRef.current) == null ? void 0 : _p.selection) === obj) {
15124
15144
  const snap = groupShiftReflowSnapshotRef.current;
15125
15145
  const anchorEntry = snap.children[0];
15126
15146
  const anchorTopLive = anchorEntry.obj.top ?? 0;
@@ -15282,7 +15302,7 @@ const PageCanvas = react.forwardRef(
15282
15302
  setGuides(gridGuidesForScale.length ? [...scaleGuides, ...gridGuidesForScale] : scaleGuides);
15283
15303
  if (drilledGroupIdRef.current) {
15284
15304
  try {
15285
- (_o = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _o.call(fabricCanvas);
15305
+ (_q = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _q.call(fabricCanvas);
15286
15306
  } catch {
15287
15307
  }
15288
15308
  }
@@ -15689,12 +15709,18 @@ const PageCanvas = react.forwardRef(
15689
15709
  const absLeft = (active.left ?? 0) - ct.frameW / 2;
15690
15710
  const absTop = (active.top ?? 0) - ct.frameH / 2;
15691
15711
  const storePosCrop = absoluteToStorePosition(absLeft, absTop, objId, pageChildrenCrop);
15712
+ const sourceCropElement = pageChildrenCrop.length ? findNodeById(pageChildrenCrop, objId) : null;
15713
+ const cropAngle = sourceCropElement && isElement(sourceCropElement) && (sourceCropElement.flipX || sourceCropElement.flipY) && Number.isFinite(sourceCropElement.angle) ? sourceCropElement.angle ?? 0 : active.angle ?? 0;
15714
+ if ((sourceCropElement == null ? void 0 : sourceCropElement.flipX) || (sourceCropElement == null ? void 0 : sourceCropElement.flipY)) {
15715
+ active.set({ angle: cropAngle, flipX: sourceCropElement.flipX ?? false, flipY: sourceCropElement.flipY ?? false });
15716
+ active.setCoords();
15717
+ }
15692
15718
  updateElement2(objId, {
15693
15719
  width: ct.frameW,
15694
15720
  height: ct.frameH,
15695
15721
  left: storePosCrop.left,
15696
15722
  top: storePosCrop.top,
15697
- angle: active.angle ?? 0,
15723
+ angle: cropAngle,
15698
15724
  cropPanX: panX,
15699
15725
  cropPanY: panY,
15700
15726
  cropZoom: zoom3
@@ -15949,12 +15975,15 @@ const PageCanvas = react.forwardRef(
15949
15975
  360 - Math.abs(currentSelAngle - startSelAngle)
15950
15976
  );
15951
15977
  const hadRotation = isActiveSelection && activeObj && angleDelta > 0.01;
15952
- if (!hadScale && !hadRotation && (Math.abs(deltaX) > 0.1 || Math.abs(deltaY) > 0.1)) {
15978
+ const isMoveOnlyLogicalGroupGesture = !hadScale && !hadRotation && (Math.abs(deltaX) > 0.1 || Math.abs(deltaY) > 0.1);
15979
+ if (isMoveOnlyLogicalGroupGesture || !hadScale && !hadRotation && activeGroupSelectionId === groupToMove.id) {
15953
15980
  const { updateNode: updateNodeStore, commitHistory: commitHistoryStore, getCurrentElements } = useEditorStore.getState();
15954
- const newLeft = (groupToMove.left ?? 0) + deltaX;
15955
- const newTop = (groupToMove.top ?? 0) + deltaY;
15956
- updateNodeStore(groupToMove.id, { left: newLeft, top: newTop }, { recordHistory: false, skipLayoutRecalc: true });
15957
- commitHistoryStore();
15981
+ if (isMoveOnlyLogicalGroupGesture) {
15982
+ const newLeft = (groupToMove.left ?? 0) + deltaX;
15983
+ const newTop = (groupToMove.top ?? 0) + deltaY;
15984
+ updateNodeStore(groupToMove.id, { left: newLeft, top: newTop }, { recordHistory: false, skipLayoutRecalc: true });
15985
+ commitHistoryStore();
15986
+ }
15958
15987
  pendingGroupDrillInRef.current = null;
15959
15988
  fabricCanvas.__activeEditingGroupId = null;
15960
15989
  setDrilledGroupBounds(null);
@@ -16193,7 +16222,7 @@ const PageCanvas = react.forwardRef(
16193
16222
  useEditorStore.getState().updateElement(objId, { src: newSrc }, { recordHistory: false, skipLayoutRecalc: true });
16194
16223
  }
16195
16224
  } else if (isActiveSelection && (Math.abs((decomposed.scaleX ?? 1) - 1) > 1e-3 || Math.abs((decomposed.scaleY ?? 1) - 1) > 1e-3)) {
16196
- const imgChildLocalAngle = obj.__asLiveOrigAngle != null ? obj.__asLiveOrigAngle : obj.angle ?? 0;
16225
+ const imgChildLocalAngle = obj.__asLiveOrigAngle != null ? obj.__asLiveOrigAngle : ((sourceElement == null ? void 0 : sourceElement.flipX) || (sourceElement == null ? void 0 : sourceElement.flipY)) && Number.isFinite(sourceElement == null ? void 0 : sourceElement.angle) ? sourceElement.angle ?? 0 : obj.angle ?? 0;
16197
16226
  const imgChildNormAngle = (imgChildLocalAngle % 360 + 360) % 360;
16198
16227
  const imgChildIsRotated = Math.abs(imgChildNormAngle) > 0.5 && Math.abs(imgChildNormAngle - 360) > 0.5;
16199
16228
  const imgHandle = activeSelectionResizeHandle;
@@ -16512,17 +16541,17 @@ const PageCanvas = react.forwardRef(
16512
16541
  const persistedFlipY = (sourceElement == null ? void 0 : sourceElement.flipY) ?? objectFlipY;
16513
16542
  const isActiveSelectionResizeGesture = activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb" || activeSelectionResizeHandle === "tl" || activeSelectionResizeHandle === "tr" || activeSelectionResizeHandle === "bl" || activeSelectionResizeHandle === "br";
16514
16543
  const expectedCleanAngle = isActiveSelection && isActiveSelectionResizeGesture ? Number.isFinite(sourceElement == null ? void 0 : sourceElement.angle) ? (sourceElement == null ? void 0 : sourceElement.angle) ?? 0 : Number.isFinite(obj.angle) ? obj.angle ?? 0 : void 0 : void 0;
16515
- const normalizedFinalAbsoluteMatrix = normalizeMatrixForPersistedFlip(
16516
- toggleLogicalFlipInMatrix(
16517
- finalAbsoluteMatrix,
16518
- objectFlipX !== persistedFlipX,
16519
- objectFlipY !== persistedFlipY
16520
- ),
16544
+ const matrixWithPersistedFlipState = toggleLogicalFlipInMatrix(
16545
+ finalAbsoluteMatrix,
16546
+ objectFlipX !== persistedFlipX,
16547
+ objectFlipY !== persistedFlipY
16548
+ );
16549
+ const cleanTransformMatrix = stripPersistedFlipForStableAngle(
16550
+ matrixWithPersistedFlipState,
16521
16551
  persistedFlipX,
16522
16552
  persistedFlipY,
16523
16553
  expectedCleanAngle
16524
16554
  );
16525
- const cleanTransformMatrix = toggleLogicalFlipInMatrix(normalizedFinalAbsoluteMatrix, persistedFlipX, persistedFlipY);
16526
16555
  const persistedDecomposed = fabric__namespace.util.qrDecompose(cleanTransformMatrix);
16527
16556
  const elementUpdate = {
16528
16557
  left: storePos.left,
@@ -16604,7 +16633,7 @@ const PageCanvas = react.forwardRef(
16604
16633
  const isCropGroupObj = obj instanceof fabric__namespace.Group && obj.__cropGroup;
16605
16634
  const isPlainImageObj = obj instanceof fabric__namespace.FabricImage && !obj.__cropGroup && !obj.smartElementType;
16606
16635
  if (isActiveSelection && isActiveSelectionSideHandle && (isCropGroupObj || isPlainImageObj)) {
16607
- const childLocalAngleSrc = obj.__asLiveOrigAngle != null ? obj.__asLiveOrigAngle : Number.isFinite(sourceElement == null ? void 0 : sourceElement.angle) ? sourceElement.angle ?? 0 : obj.angle ?? 0;
16636
+ const childLocalAngleSrc = obj.__asLiveOrigAngle != null ? obj.__asLiveOrigAngle : ((sourceElement == null ? void 0 : sourceElement.flipX) || (sourceElement == null ? void 0 : sourceElement.flipY)) && Number.isFinite(sourceElement == null ? void 0 : sourceElement.angle) ? sourceElement.angle ?? 0 : Number.isFinite(sourceElement == null ? void 0 : sourceElement.angle) ? sourceElement.angle ?? 0 : obj.angle ?? 0;
16608
16637
  const normAng = (childLocalAngleSrc % 360 + 360) % 360;
16609
16638
  const isRotatedImg = Math.min(normAng, 360 - normAng) > 0.5;
16610
16639
  if (isRotatedImg && activeObj instanceof fabric__namespace.ActiveSelection) {
@@ -16843,6 +16872,8 @@ const PageCanvas = react.forwardRef(
16843
16872
  delete child.__asLiveParentWorldAngle;
16844
16873
  delete child.__asLiveFinalW;
16845
16874
  delete child.__asLiveFinalH;
16875
+ delete child.__asLivePersistedFlipX;
16876
+ delete child.__asLivePersistedFlipY;
16846
16877
  }
16847
16878
  }
16848
16879
  } catch {
@@ -25946,9 +25977,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
25946
25977
  }
25947
25978
  return svgString;
25948
25979
  }
25949
- const resolvedPackageVersion = "0.5.450";
25980
+ const resolvedPackageVersion = "0.5.452";
25950
25981
  const PACKAGE_VERSION = resolvedPackageVersion;
25951
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.450";
25982
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.452";
25952
25983
  const roundParityValue = (value) => {
25953
25984
  if (typeof value !== "number") return value;
25954
25985
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -26762,7 +26793,7 @@ class PixldocsRenderer {
26762
26793
  await this.waitForCanvasScene(container, cloned, i);
26763
26794
  }
26764
26795
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
26765
- const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-CF7KqDSy.cjs"));
26796
+ const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-DLdSAaBB.cjs"));
26766
26797
  const prepared = preparePagesForExport(
26767
26798
  cloned.pages,
26768
26799
  canvasWidth,
@@ -29082,7 +29113,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
29082
29113
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
29083
29114
  sanitizeSvgTreeForPdf(svgToDraw);
29084
29115
  try {
29085
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-CF7KqDSy.cjs"));
29116
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-DLdSAaBB.cjs"));
29086
29117
  try {
29087
29118
  await logTextMeasurementDiagnostic(svgToDraw);
29088
29119
  } catch {
@@ -29479,4 +29510,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
29479
29510
  exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
29480
29511
  exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
29481
29512
  exports.warmTemplateFromForm = warmTemplateFromForm;
29482
- //# sourceMappingURL=index-DM88x3tM.cjs.map
29513
+ //# sourceMappingURL=index-L5Rj-oYv.cjs.map