@pixldocs/canvas-renderer 0.5.452 → 0.5.454

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.
@@ -11693,6 +11693,28 @@ const angleDistanceDeg = (a, b) => {
11693
11693
  const delta = Math.abs(((a - b) % 360 + 540) % 360 - 180);
11694
11694
  return Number.isFinite(delta) ? delta : Number.POSITIVE_INFINITY;
11695
11695
  };
11696
+ const normalizeSignedAngleDeg = (angle) => {
11697
+ if (!Number.isFinite(angle)) return 0;
11698
+ const normalized = (angle % 360 + 540) % 360 - 180;
11699
+ return Math.abs(normalized) < 1e-9 ? 0 : normalized;
11700
+ };
11701
+ const resolveActiveSelectionLocalAngle = (obj, sourceElement, activeSelection) => {
11702
+ var _a2;
11703
+ const objectAngle = Number.isFinite(obj.angle) ? obj.angle ?? 0 : 0;
11704
+ const isImageLike = obj instanceof fabric.FabricImage || obj instanceof fabric.Group && (obj.__cropGroup || ((_a2 = obj._ct) == null ? void 0 : _a2.isCropGroup));
11705
+ const hasPersistedFlip = !!((sourceElement == null ? void 0 : sourceElement.flipX) || (sourceElement == null ? void 0 : sourceElement.flipY) || obj.flipX || obj.flipY);
11706
+ if (!isImageLike || !hasPersistedFlip || !Number.isFinite(sourceElement == null ? void 0 : sourceElement.angle)) {
11707
+ return normalizeSignedAngleDeg(objectAngle);
11708
+ }
11709
+ return normalizeSignedAngleDeg((sourceElement.angle ?? 0) - ((activeSelection == null ? void 0 : activeSelection.angle) ?? 0));
11710
+ };
11711
+ const resolveStableFlippedAngle = (fabricAngle, sourceAngle, hasFlip, isRotationGesture = false) => {
11712
+ const current = Number.isFinite(fabricAngle) ? fabricAngle : sourceAngle ?? 0;
11713
+ if (!hasFlip || isRotationGesture || !Number.isFinite(sourceAngle)) return current;
11714
+ const src = sourceAngle;
11715
+ const isFabricFlipEncoding = angleDistanceDeg(current, src + 180) < 2 && angleDistanceDeg(current, src) > 90;
11716
+ return isFabricFlipEncoding ? src : current;
11717
+ };
11696
11718
  const stripPersistedFlipForStableAngle = (matrix, persistedFlipX, persistedFlipY, expectedCleanAngle) => {
11697
11719
  if (!persistedFlipX && !persistedFlipY) return matrix;
11698
11720
  const toggled = toggleLogicalFlipInMatrix(matrix, persistedFlipX, persistedFlipY);
@@ -14644,7 +14666,7 @@ const PageCanvas = forwardRef(
14644
14666
  fabricCanvas.on("selection:cleared", () => {
14645
14667
  });
14646
14668
  fabricCanvas.on("object:scaling", (e) => {
14647
- var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
14669
+ var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
14648
14670
  if (!isActiveRef.current) return;
14649
14671
  const t = e.target;
14650
14672
  if (t) lastResizeScaleTargetRef.current = t;
@@ -14941,15 +14963,18 @@ const PageCanvas = forwardRef(
14941
14963
  const sourceChildForAngle = childIdForAngle ? elementsRef.current.find((el) => el.id === childIdForAngle) : null;
14942
14964
  const persistedChildFlipX = (sourceChildForAngle == null ? void 0 : sourceChildForAngle.flipX) ?? child.flipX ?? false;
14943
14965
  const persistedChildFlipY = (sourceChildForAngle == null ? void 0 : sourceChildForAngle.flipY) ?? child.flipY ?? false;
14944
- const isFlippedImageLikeChild = (child instanceof fabric.FabricImage || child instanceof fabric.Group && (child.__cropGroup || ((_m = child._ct) == null ? void 0 : _m.isCropGroup))) && !!(persistedChildFlipX || persistedChildFlipY) && Number.isFinite(sourceChildForAngle == null ? void 0 : sourceChildForAngle.angle);
14945
- if (child instanceof fabric.FabricImage || child instanceof fabric.Group && (child.__cropGroup || ((_n = child._ct) == null ? void 0 : _n.isCropGroup))) {
14966
+ if (child instanceof fabric.FabricImage || child instanceof fabric.Group && (child.__cropGroup || ((_m = child._ct) == null ? void 0 : _m.isCropGroup))) {
14946
14967
  child.set({ flipX: persistedChildFlipX, flipY: persistedChildFlipY });
14947
14968
  child.__asLivePersistedFlipX = persistedChildFlipX;
14948
14969
  child.__asLivePersistedFlipY = persistedChildFlipY;
14949
14970
  }
14950
- child.__asLiveOrigAngle = isFlippedImageLikeChild ? sourceChildForAngle.angle ?? 0 : Number.isFinite(child.angle) ? child.angle ?? 0 : 0;
14971
+ child.__asLiveOrigAngle = resolveActiveSelectionLocalAngle(
14972
+ child,
14973
+ sourceChildForAngle,
14974
+ obj
14975
+ );
14951
14976
  }
14952
- if (child instanceof fabric.Group && (child.__cropGroup || ((_o = child._ct) == null ? void 0 : _o.isCropGroup))) {
14977
+ if (child instanceof fabric.Group && (child.__cropGroup || ((_n = child._ct) == null ? void 0 : _n.isCropGroup))) {
14953
14978
  const ct = child.__cropData;
14954
14979
  if (!ct) continue;
14955
14980
  if (child.__asLiveOrigAngle == null) {
@@ -15122,7 +15147,7 @@ const PageCanvas = forwardRef(
15122
15147
  child.dirty = true;
15123
15148
  didReflowTextChild = true;
15124
15149
  }
15125
- if (isXSide && ((_p = groupShiftReflowSnapshotRef.current) == null ? void 0 : _p.selection) === obj) {
15150
+ if (isXSide && ((_o = groupShiftReflowSnapshotRef.current) == null ? void 0 : _o.selection) === obj) {
15126
15151
  const snap = groupShiftReflowSnapshotRef.current;
15127
15152
  const anchorEntry = snap.children[0];
15128
15153
  const anchorTopLive = anchorEntry.obj.top ?? 0;
@@ -15284,7 +15309,7 @@ const PageCanvas = forwardRef(
15284
15309
  setGuides(gridGuidesForScale.length ? [...scaleGuides, ...gridGuidesForScale] : scaleGuides);
15285
15310
  if (drilledGroupIdRef.current) {
15286
15311
  try {
15287
- (_q = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _q.call(fabricCanvas);
15312
+ (_p = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _p.call(fabricCanvas);
15288
15313
  } catch {
15289
15314
  }
15290
15315
  }
@@ -16085,7 +16110,7 @@ const PageCanvas = forwardRef(
16085
16110
  if (obj instanceof fabric.Group && obj.__cropGroup) {
16086
16111
  const ct = obj.__cropData;
16087
16112
  if (ct) {
16088
- const cropChildLocalAngle = obj.__asLiveOrigAngle != null ? obj.__asLiveOrigAngle : obj.angle ?? 0;
16113
+ const cropChildLocalAngle = obj.__asLiveOrigAngle != null ? obj.__asLiveOrigAngle : resolveActiveSelectionLocalAngle(obj, sourceElement, activeObj instanceof fabric.ActiveSelection ? activeObj : null);
16089
16114
  const cropChildNormAngle = (cropChildLocalAngle % 360 + 360) % 360;
16090
16115
  const cropChildIsRotated = Math.abs(cropChildNormAngle) > 0.5 && Math.abs(cropChildNormAngle - 360) > 0.5;
16091
16116
  const cropHandle = activeSelectionResizeHandle;
@@ -16204,7 +16229,7 @@ const PageCanvas = forwardRef(
16204
16229
  useEditorStore.getState().updateElement(objId, { src: newSrc }, { recordHistory: false, skipLayoutRecalc: true });
16205
16230
  }
16206
16231
  } else if (isActiveSelection && (Math.abs((decomposed.scaleX ?? 1) - 1) > 1e-3 || Math.abs((decomposed.scaleY ?? 1) - 1) > 1e-3)) {
16207
- 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;
16232
+ const imgChildLocalAngle = obj.__asLiveOrigAngle != null ? obj.__asLiveOrigAngle : resolveActiveSelectionLocalAngle(obj, sourceElement, activeObj instanceof fabric.ActiveSelection ? activeObj : null);
16208
16233
  const imgChildNormAngle = (imgChildLocalAngle % 360 + 360) % 360;
16209
16234
  const imgChildIsRotated = Math.abs(imgChildNormAngle) > 0.5 && Math.abs(imgChildNormAngle - 360) > 0.5;
16210
16235
  const imgHandle = activeSelectionResizeHandle;
@@ -16535,6 +16560,18 @@ const PageCanvas = forwardRef(
16535
16560
  expectedCleanAngle
16536
16561
  );
16537
16562
  const persistedDecomposed = fabric.util.qrDecompose(cleanTransformMatrix);
16563
+ const hasPersistedFlipForAngle = !!(persistedFlipX || persistedFlipY);
16564
+ const isRotationGestureForStableAngle = isActiveSelection && activeObj instanceof fabric.ActiveSelection ? (() => {
16565
+ var _a3;
16566
+ const startAngle = ((_a3 = groupSelectionTransformStartRef.current) == null ? void 0 : _a3.selection) === activeObj ? groupSelectionTransformStartRef.current.selectionAngle ?? activeObj.angle ?? 0 : activeObj.angle ?? 0;
16567
+ return angleDistanceDeg(activeObj.angle ?? 0, startAngle) > 0.01;
16568
+ })() : !isActiveSelection && modifiedTarget === obj && angleDistanceDeg(obj.angle ?? 0, (sourceElement == null ? void 0 : sourceElement.angle) ?? obj.angle ?? 0) > 0.01;
16569
+ const stablePersistedAngle = resolveStableFlippedAngle(
16570
+ persistedDecomposed.angle,
16571
+ sourceElement == null ? void 0 : sourceElement.angle,
16572
+ hasPersistedFlipForAngle,
16573
+ isRotationGestureForStableAngle
16574
+ );
16538
16575
  const elementUpdate = {
16539
16576
  left: storePos.left,
16540
16577
  top: storePos.top,
@@ -16543,7 +16580,7 @@ const PageCanvas = forwardRef(
16543
16580
  // so finalWidth already reflects the new width chosen by the user.
16544
16581
  width: finalWidth,
16545
16582
  height: isLineObj ? 0 : isAutoShrinkText ? typeof autoShrinkStoredHeight === "number" ? autoShrinkStoredHeight : finalHeight : finalHeight,
16546
- angle: persistedDecomposed.angle,
16583
+ angle: stablePersistedAngle,
16547
16584
  skewX: isLineObj ? 0 : persistedDecomposed.skewX,
16548
16585
  skewY: isLineObj ? 0 : persistedDecomposed.skewY,
16549
16586
  scaleX: finalScaleX,
@@ -16615,7 +16652,7 @@ const PageCanvas = forwardRef(
16615
16652
  const isCropGroupObj = obj instanceof fabric.Group && obj.__cropGroup;
16616
16653
  const isPlainImageObj = obj instanceof fabric.FabricImage && !obj.__cropGroup && !obj.smartElementType;
16617
16654
  if (isActiveSelection && isActiveSelectionSideHandle && (isCropGroupObj || isPlainImageObj)) {
16618
- 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;
16655
+ const childLocalAngleSrc = obj.__asLiveOrigAngle != null ? obj.__asLiveOrigAngle : resolveActiveSelectionLocalAngle(obj, sourceElement, activeObj instanceof fabric.ActiveSelection ? activeObj : null);
16619
16656
  const normAng = (childLocalAngleSrc % 360 + 360) % 360;
16620
16657
  const isRotatedImg = Math.min(normAng, 360 - normAng) > 0.5;
16621
16658
  if (isRotatedImg && activeObj instanceof fabric.ActiveSelection) {
@@ -20936,6 +20973,20 @@ function flattenSectionStateToFormData(sectionState, sections) {
20936
20973
  }
20937
20974
  return flat;
20938
20975
  }
20976
+ function gradientSiblingForTarget(targetProperty) {
20977
+ switch (targetProperty) {
20978
+ case "fill":
20979
+ return "fillGradient";
20980
+ case "stroke":
20981
+ return "strokeGradient";
20982
+ case "textBgColor":
20983
+ return "textBgGradient";
20984
+ case "backgroundColor":
20985
+ return "backgroundGradient";
20986
+ default:
20987
+ return null;
20988
+ }
20989
+ }
20939
20990
  const CLONE_SUFFIX = /_\d+$/;
20940
20991
  function baseId(id) {
20941
20992
  let s = id;
@@ -21036,7 +21087,18 @@ function setInTree(nodes, elementId, targetProperty, value) {
21036
21087
  delete node.cropZoom;
21037
21088
  }
21038
21089
  } else {
21039
- node[targetProperty] = value;
21090
+ const gradSibling = gradientSiblingForTarget(targetProperty);
21091
+ if (gradSibling) {
21092
+ if (isGradientConfig(value)) {
21093
+ node[gradSibling] = value;
21094
+ node[targetProperty] = targetProperty === "textBgColor" ? "transparent" : "";
21095
+ } else {
21096
+ if (gradSibling in node) delete node[gradSibling];
21097
+ node[targetProperty] = value;
21098
+ }
21099
+ } else {
21100
+ node[targetProperty] = value;
21101
+ }
21040
21102
  }
21041
21103
  if (targetProperty === "text" && node.type === "text") {
21042
21104
  const overflowPolicy = String(node.overflowPolicy ?? "grow-and-push");
@@ -21708,10 +21770,19 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
21708
21770
  effectiveValue = formatTimeForDisplay(effectiveValue);
21709
21771
  }
21710
21772
  }
21711
- if (elementId === PAGE_BACKGROUND_ELEMENT_ID && targetProperty === "backgroundColor" && typeof effectiveValue === "string") {
21773
+ if (elementId === PAGE_BACKGROUND_ELEMENT_ID && targetProperty === "backgroundColor") {
21712
21774
  if ((_a3 = pages[0]) == null ? void 0 : _a3.settings) {
21713
- pages[0].settings.backgroundColor = effectiveValue;
21714
- return true;
21775
+ const settings = pages[0].settings;
21776
+ if (isGradientConfig(effectiveValue)) {
21777
+ settings.backgroundGradient = effectiveValue;
21778
+ settings.backgroundColor = "";
21779
+ return true;
21780
+ }
21781
+ if (typeof effectiveValue === "string") {
21782
+ if ("backgroundGradient" in settings) delete settings.backgroundGradient;
21783
+ settings.backgroundColor = effectiveValue;
21784
+ return true;
21785
+ }
21715
21786
  }
21716
21787
  }
21717
21788
  for (const page of pages) {
@@ -25959,9 +26030,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
25959
26030
  }
25960
26031
  return svgString;
25961
26032
  }
25962
- const resolvedPackageVersion = "0.5.452";
26033
+ const resolvedPackageVersion = "0.5.454";
25963
26034
  const PACKAGE_VERSION = resolvedPackageVersion;
25964
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.452";
26035
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.454";
25965
26036
  const roundParityValue = (value) => {
25966
26037
  if (typeof value !== "number") return value;
25967
26038
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -26775,7 +26846,7 @@ class PixldocsRenderer {
26775
26846
  await this.waitForCanvasScene(container, cloned, i);
26776
26847
  }
26777
26848
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
26778
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-IArzJ4nC.js");
26849
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-xz20N_5g.js");
26779
26850
  const prepared = preparePagesForExport(
26780
26851
  cloned.pages,
26781
26852
  canvasWidth,
@@ -29095,7 +29166,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
29095
29166
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
29096
29167
  sanitizeSvgTreeForPdf(svgToDraw);
29097
29168
  try {
29098
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-IArzJ4nC.js");
29169
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-xz20N_5g.js");
29099
29170
  try {
29100
29171
  await logTextMeasurementDiagnostic(svgToDraw);
29101
29172
  } catch {
@@ -29495,4 +29566,4 @@ export {
29495
29566
  buildTeaserBlurFlatKeys as y,
29496
29567
  collectFontDescriptorsFromConfig as z
29497
29568
  };
29498
- //# sourceMappingURL=index-B4jCHYd5.js.map
29569
+ //# sourceMappingURL=index-CeVp5eqp.js.map