@pixldocs/canvas-renderer 0.5.271 → 0.5.273

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.
@@ -12704,7 +12704,9 @@ const PageCanvas = forwardRef(
12704
12704
  const selection = new fabric.ActiveSelection(members, { canvas: fc });
12705
12705
  restoreGroupSelectionVisualState(selection, groupId);
12706
12706
  fc.setActiveObject(selection);
12707
- selection.setCoords();
12707
+ if (!selection.getObjects().every((obj) => !(obj instanceof fabric.Group))) {
12708
+ selection.setCoords();
12709
+ }
12708
12710
  fc.requestRenderAll();
12709
12711
  } finally {
12710
12712
  requestAnimationFrame(() => {
@@ -14338,7 +14340,9 @@ const PageCanvas = forwardRef(
14338
14340
  const bakedSelection = reselectionObjects.length > 1 ? new fabric.ActiveSelection(reselectionObjects, { canvas: fabricCanvas }) : activeObj;
14339
14341
  restoreGroupSelectionVisualState(bakedSelection, groupSelectionId);
14340
14342
  fabricCanvas.setActiveObject(bakedSelection);
14341
- bakedSelection.setCoords();
14343
+ if (!(bakedSelection instanceof fabric.ActiveSelection && bakedSelection.getObjects().every((obj) => !(obj instanceof fabric.Group)))) {
14344
+ bakedSelection.setCoords();
14345
+ }
14342
14346
  }
14343
14347
  selectElements([groupSelectionId], false, false);
14344
14348
  fabricCanvas.requestRenderAll();
@@ -14982,6 +14986,22 @@ const PageCanvas = forwardRef(
14982
14986
  fc.discardActiveObject();
14983
14987
  }
14984
14988
  }
14989
+ const forceLogicalGroupStorePositionSyncIds = /* @__PURE__ */ new Set();
14990
+ const needsLooseLogicalGroupPositionSync = !!((activeSelectionSnapshot == null ? void 0 : activeSelectionSnapshot.groupSelectionId) && !syncTriggeredByPanelRef.current && !shouldSkipUpdates2 && !isTransforming2 && activeSelectionSnapshot.memberIds.some((id) => justModifiedIdsRef.current.has(id)));
14991
+ if (needsLooseLogicalGroupPositionSync) {
14992
+ activeSelectionSnapshot.memberIds.forEach((id) => forceLogicalGroupStorePositionSyncIds.add(id));
14993
+ const activeForLooseSync = fc.getActiveObject();
14994
+ if (activeForLooseSync instanceof fabric.ActiveSelection && activeForLooseSync.__pixldocsGroupSelection === activeSelectionSnapshot.groupSelectionId) {
14995
+ try {
14996
+ skipSelectionClearOnDiscardRef.current = true;
14997
+ skipActiveSelectionBakeOnClearRef.current = true;
14998
+ fc.discardActiveObject();
14999
+ } finally {
15000
+ skipActiveSelectionBakeOnClearRef.current = false;
15001
+ skipSelectionClearOnDiscardRef.current = false;
15002
+ }
15003
+ }
15004
+ }
14985
15005
  const currentFabricObjects = /* @__PURE__ */ new Map();
14986
15006
  fc.getObjects().forEach((obj) => {
14987
15007
  const id = getObjectId(obj);
@@ -14995,7 +15015,7 @@ const PageCanvas = forwardRef(
14995
15015
  const replacementById = !activeStillOnCanvas && activeId ? fc.getObjects().find((o) => getObjectId(o) === activeId) ?? null : null;
14996
15016
  const restoreTarget = activeStillOnCanvas ? activeBeforeSync : replacementById;
14997
15017
  const isActiveTextBeingEdited = activeId && editingTextIdRef.current === activeId && activeBeforeSync instanceof fabric.Textbox;
14998
- if (!skipRestoreSelection && activeSelectionSnapshot && !isActiveTextBeingEdited && !shouldSkipUpdates2) {
15018
+ if (!skipRestoreSelection && activeSelectionSnapshot && !isActiveTextBeingEdited && !shouldSkipUpdates2 && !needsLooseLogicalGroupPositionSync) {
14999
15019
  const freshMembers = activeSelectionSnapshot.memberIds.map((id) => fc.getObjects().find((o) => getObjectId(o) === id)).filter((o) => !!o);
15000
15020
  if (freshMembers.length > 1) {
15001
15021
  isSyncingSelectionToFabricRef.current = true;
@@ -15120,9 +15140,42 @@ const PageCanvas = forwardRef(
15120
15140
  };
15121
15141
  fc.add(sectionGroup);
15122
15142
  }
15143
+ const getActiveSelectionContainingObject = (obj) => {
15144
+ const active = fc.getActiveObject();
15145
+ return active instanceof fabric.ActiveSelection && active.getObjects().includes(obj) ? active : null;
15146
+ };
15147
+ const shouldPreserveActiveSelectionMemberPosition = (obj) => {
15148
+ if (syncTriggeredByPanelRef.current) return false;
15149
+ const activeSelection = getActiveSelectionContainingObject(obj);
15150
+ if (!activeSelection) return false;
15151
+ const logicalActiveSelection = activeSelection;
15152
+ const logicalGroupId = logicalActiveSelection.__pixldocsGroupSelection;
15153
+ const logicalGroupIds = logicalActiveSelection.__pixldocsLogicalGroupIds;
15154
+ if (logicalGroupId || Array.isArray(logicalGroupIds)) return true;
15155
+ const id = getObjectId(obj);
15156
+ const preserved = preserveActiveSelectionAfterTransformRef.current;
15157
+ return !!(id && (preserved == null ? void 0 : preserved.memberIds.includes(id)) && (!preserved.expiresAt || preserved.expiresAt > Date.now()));
15158
+ };
15159
+ const getObjectSyncComparePosition = (obj) => {
15160
+ const activeSelection = getActiveSelectionContainingObject(obj);
15161
+ if (!activeSelection) return { left: obj.left ?? 0, top: obj.top ?? 0 };
15162
+ const point = fabric.util.transformPoint({ x: obj.left ?? 0, y: obj.top ?? 0 }, activeSelection.calcTransformMatrix());
15163
+ let left = point.x;
15164
+ let top = point.y;
15165
+ const cropObj = obj;
15166
+ if (obj instanceof fabric.Group && cropObj.__cropGroup) {
15167
+ const ct = cropObj.__cropData;
15168
+ left -= ((ct == null ? void 0 : ct.frameW) ?? obj.width ?? 0) * Math.abs(obj.scaleX ?? 1) / 2;
15169
+ top -= ((ct == null ? void 0 : ct.frameH) ?? obj.height ?? 0) * Math.abs(obj.scaleY ?? 1) / 2;
15170
+ } else if (obj instanceof fabric.FabricImage && (obj.originX === "center" || obj.originY === "center")) {
15171
+ left -= (obj.width ?? 0) * Math.abs(obj.scaleX ?? 1) / 2;
15172
+ top -= (obj.height ?? 0) * Math.abs(obj.scaleY ?? 1) / 2;
15173
+ }
15174
+ return { left, top };
15175
+ };
15123
15176
  for (const element of elementsToSync) {
15124
15177
  if (sectionDescendantIds.has(element.id)) continue;
15125
- let existingObj = currentFabricObjects.get(element.id);
15178
+ const existingObj = currentFabricObjects.get(element.id);
15126
15179
  const isHidden = !element.visible;
15127
15180
  if (existingObj) {
15128
15181
  const isBeingTransformed = transformingIdsRef.current.has(element.id);
@@ -15387,7 +15440,8 @@ const PageCanvas = forwardRef(
15387
15440
  continue;
15388
15441
  }
15389
15442
  if (existingObj instanceof fabric.Group && existingObj.__cropGroup) {
15390
- updateFabricObject(existingObj, element, wasJustModified);
15443
+ const forceStorePositionSync2 = forceLogicalGroupStorePositionSyncIds.has(element.id);
15444
+ updateFabricObject(existingObj, element, wasJustModified && !forceStorePositionSync2);
15391
15445
  existingObj.set({
15392
15446
  flipX: element.flipX ?? false,
15393
15447
  flipY: element.flipY ?? false,
@@ -15398,7 +15452,7 @@ const PageCanvas = forwardRef(
15398
15452
  if (wasJustModified) justModifiedIdsRef.current.delete(element.id);
15399
15453
  continue;
15400
15454
  }
15401
- if (existingObj instanceof fabric.Textbox && wasJustModified && !syncTriggeredByPanelRef.current) {
15455
+ if (existingObj instanceof fabric.Textbox && wasJustModified && !syncTriggeredByPanelRef.current && !forceLogicalGroupStorePositionSyncIds.has(element.id)) {
15402
15456
  justModifiedIdsRef.current.delete(element.id);
15403
15457
  continue;
15404
15458
  }
@@ -15416,7 +15470,10 @@ const PageCanvas = forwardRef(
15416
15470
  const node = findNodeById(pageTree, element.id);
15417
15471
  return node ? getAbsoluteBounds(node, pageTree) : { left: element.left ?? 0, top: element.top ?? 0 };
15418
15472
  })() : { left: element.left ?? 0, top: element.top ?? 0 };
15419
- const positionChanged = Math.abs((existingObj.left ?? 0) - storePosForImg.left) > 0.1 || Math.abs((existingObj.top ?? 0) - storePosForImg.top) > 0.1;
15473
+ const comparePosForImg = getObjectSyncComparePosition(existingObj);
15474
+ const forceStorePositionSync = forceLogicalGroupStorePositionSyncIds.has(element.id);
15475
+ const preserveSelectionMemberPosition = !forceStorePositionSync && shouldPreserveActiveSelectionMemberPosition(existingObj);
15476
+ const positionChanged = !preserveSelectionMemberPosition && (Math.abs(comparePosForImg.left - storePosForImg.left) > 0.1 || Math.abs(comparePosForImg.top - storePosForImg.top) > 0.1);
15420
15477
  if (visibilityChanged && !positionChanged || visibilityUpdateInProgressRef.current) {
15421
15478
  const isDynamicField = dynamicFieldIds.includes(element.id);
15422
15479
  const canBeEvented = isEditorMode || isPreviewMode && isDynamicField;
@@ -15431,7 +15488,7 @@ const PageCanvas = forwardRef(
15431
15488
  previousVisibilityRef.current.set(element.id, currentVisible);
15432
15489
  } else {
15433
15490
  if (!visibilityUpdateInProgressRef.current) {
15434
- updateFabricObject(existingObj, element, wasJustModified);
15491
+ updateFabricObject(existingObj, element, wasJustModified && !forceStorePositionSync || preserveSelectionMemberPosition);
15435
15492
  }
15436
15493
  const isDynamicField = dynamicFieldIds.includes(element.id);
15437
15494
  const canBeEvented = isEditorMode || isPreviewMode && isDynamicField;
@@ -15453,8 +15510,9 @@ const PageCanvas = forwardRef(
15453
15510
  if (!isBeingTransformed && !isBeingTextEdited && !shouldSkipUpdates2) {
15454
15511
  previousVisibilityRef.current.get(element.id) ?? true;
15455
15512
  const currentVisible = element.visible !== false;
15456
- const fabricLeft = existingObj.left ?? 0;
15457
- const fabricTop = existingObj.top ?? 0;
15513
+ const comparePos = getObjectSyncComparePosition(existingObj);
15514
+ const fabricLeft = comparePos.left;
15515
+ const fabricTop = comparePos.top;
15458
15516
  const storePos = pageTree.length ? (() => {
15459
15517
  const node = findNodeById(pageTree, element.id);
15460
15518
  return node ? getAbsoluteBounds(node, pageTree) : { left: element.left ?? 0, top: element.top ?? 0 };
@@ -15463,12 +15521,14 @@ const PageCanvas = forwardRef(
15463
15521
  const storeTop = storePos.top;
15464
15522
  const deltaX = Math.abs(fabricLeft - storeLeft);
15465
15523
  const deltaY = Math.abs(fabricTop - storeTop);
15466
- let positionChanged = deltaX > 0.1 || deltaY > 0.1;
15524
+ const forceStorePositionSync = forceLogicalGroupStorePositionSyncIds.has(element.id);
15525
+ const preserveSelectionMemberPosition = !forceStorePositionSync && shouldPreserveActiveSelectionMemberPosition(existingObj);
15526
+ let positionChanged = !preserveSelectionMemberPosition && (deltaX > 0.1 || deltaY > 0.1);
15467
15527
  const activeObj = fc.getActiveObject();
15468
15528
  const isInActiveSelection = activeObj && (activeObj instanceof fabric.ActiveSelection ? activeObj.getObjects().includes(existingObj) : activeObj === existingObj);
15469
15529
  const isInSelectedIds = selectedIdsFromStore.has(element.id);
15470
15530
  const isSelected = isInActiveSelection || isInSelectedIds;
15471
- if (positionChanged && isSelected && (wasJustModified || isBeingTransformed)) {
15531
+ if (positionChanged && isSelected && (wasJustModified || isBeingTransformed) && !forceStorePositionSync) {
15472
15532
  positionChanged = false;
15473
15533
  }
15474
15534
  const resolvedSizeForCompare = pageTree.length ? getNodeBounds(element, pageTree) : { width: typeof element.width === "number" ? element.width : 0, height: typeof element.height === "number" ? element.height : 0 };
@@ -15515,11 +15575,11 @@ const PageCanvas = forwardRef(
15515
15575
  });
15516
15576
  previousVisibilityRef.current.set(element.id, currentVisible);
15517
15577
  } else {
15518
- const skipPositionBecauseSelection = isSelected && (deltaX > 0.1 || deltaY > 0.1) && (wasJustModified || isBeingTransformed);
15578
+ const skipPositionBecauseSelection = preserveSelectionMemberPosition || !forceStorePositionSync && isSelected && (deltaX > 0.1 || deltaY > 0.1) && (wasJustModified || isBeingTransformed);
15519
15579
  const anyChange = positionChanged || otherPropsChanged || forceApplyFromPanel;
15520
15580
  if (!visibilityUpdateInProgressRef.current) {
15521
15581
  if (anyChange && !skipPositionBecauseSelection) {
15522
- updateFabricObject(existingObj, element, wasJustModified);
15582
+ updateFabricObject(existingObj, element, wasJustModified && !forceStorePositionSync);
15523
15583
  if (wasJustModified) justModifiedIdsRef.current.delete(element.id);
15524
15584
  } else if (skipPositionBecauseSelection && anyChange) {
15525
15585
  const savedLeft = existingObj.left;
@@ -23697,9 +23757,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
23697
23757
  }
23698
23758
  return svgString;
23699
23759
  }
23700
- const resolvedPackageVersion = "0.5.271";
23760
+ const resolvedPackageVersion = "0.5.273";
23701
23761
  const PACKAGE_VERSION = resolvedPackageVersion;
23702
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.271";
23762
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.273";
23703
23763
  const roundParityValue = (value) => {
23704
23764
  if (typeof value !== "number") return value;
23705
23765
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -24513,7 +24573,7 @@ class PixldocsRenderer {
24513
24573
  await this.waitForCanvasScene(container, cloned, i);
24514
24574
  }
24515
24575
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
24516
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-0BizqdiS.js");
24576
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-D4O4QFHJ.js");
24517
24577
  const prepared = preparePagesForExport(
24518
24578
  cloned.pages,
24519
24579
  canvasWidth,
@@ -26833,7 +26893,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
26833
26893
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
26834
26894
  sanitizeSvgTreeForPdf(svgToDraw);
26835
26895
  try {
26836
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-0BizqdiS.js");
26896
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-D4O4QFHJ.js");
26837
26897
  try {
26838
26898
  await logTextMeasurementDiagnostic(svgToDraw);
26839
26899
  } catch {
@@ -27233,4 +27293,4 @@ export {
27233
27293
  buildTeaserBlurFlatKeys as y,
27234
27294
  collectFontDescriptorsFromConfig as z
27235
27295
  };
27236
- //# sourceMappingURL=index-BpY8sZ_v.js.map
27296
+ //# sourceMappingURL=index-DCqQEnix.js.map