@pixldocs/canvas-renderer 0.5.353 → 0.5.355

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.
@@ -10518,105 +10518,6 @@ function bakeEdgeFade(source, fade) {
10518
10518
  }
10519
10519
  return canvas;
10520
10520
  }
10521
- const normalizeSignedAngle = (angle) => (angle % 360 + 540) % 360 - 180;
10522
- const rotatedTopLeftToCenter = (left, top, width, height, angleDeg = 0) => {
10523
- const angle = angleDeg * Math.PI / 180;
10524
- const cos = Math.cos(angle);
10525
- const sin = Math.sin(angle);
10526
- return {
10527
- x: left + width / 2 * cos - height / 2 * sin,
10528
- y: top + width / 2 * sin + height / 2 * cos
10529
- };
10530
- };
10531
- const centerToRotatedTopLeft = (centerX, centerY, width, height, angleDeg = 0) => {
10532
- const angle = angleDeg * Math.PI / 180;
10533
- const cos = Math.cos(angle);
10534
- const sin = Math.sin(angle);
10535
- return {
10536
- left: centerX - width / 2 * cos + height / 2 * sin,
10537
- top: centerY - width / 2 * sin - height / 2 * cos
10538
- };
10539
- };
10540
- const getGroupTransformFrame = (group, pageChildren, options) => {
10541
- const bounds = getNodeBounds(group, pageChildren);
10542
- const width = Math.max(1, Number(group.width ?? bounds.width) || bounds.width || 1);
10543
- const height = Math.max(1, Number(group.height ?? bounds.height) || bounds.height || 1);
10544
- return {
10545
- left: Number(group.left ?? bounds.left ?? 0) || 0,
10546
- top: Number(group.top ?? bounds.top ?? 0) || 0,
10547
- width,
10548
- height,
10549
- angle: Number(group.angle ?? 0) || 0
10550
- };
10551
- };
10552
- const getGroupLocalToParentMatrix = (group, pageChildren, options) => {
10553
- const frame = getGroupTransformFrame(group, pageChildren);
10554
- const rad = frame.angle * Math.PI / 180;
10555
- const cos = Math.cos(rad);
10556
- const sin = Math.sin(rad);
10557
- return [
10558
- cos,
10559
- sin,
10560
- -sin,
10561
- cos,
10562
- frame.left,
10563
- frame.top
10564
- ];
10565
- };
10566
- const getAncestorGroupTransform = (nodeId, pageChildren, fabric2, options) => {
10567
- let matrix = [1, 0, 0, 1, 0, 0];
10568
- let angle = 0;
10569
- const chain = [];
10570
- let currentId = nodeId;
10571
- for (let guard = 0; guard < 32; guard++) {
10572
- const parent = findParentGroup(pageChildren, currentId);
10573
- if (!parent) break;
10574
- chain.unshift(parent);
10575
- currentId = parent.id;
10576
- }
10577
- for (const group of chain) {
10578
- matrix = fabric2.util.multiplyTransformMatrices(
10579
- matrix,
10580
- getGroupLocalToParentMatrix(group, pageChildren)
10581
- );
10582
- angle += Number(group.angle ?? 0) || 0;
10583
- }
10584
- return { matrix, angle: normalizeSignedAngle(angle) };
10585
- };
10586
- const getElementFabricPlacement$1 = (element, pageChildren, fabric2, options) => {
10587
- if (!pageChildren.length) {
10588
- return { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
10589
- }
10590
- const ancestor = getAncestorGroupTransform(element.id, pageChildren, fabric2);
10591
- const point = fabric2.util.transformPoint(
10592
- new fabric2.Point(element.left ?? 0, element.top ?? 0),
10593
- ancestor.matrix
10594
- );
10595
- return {
10596
- left: point.x,
10597
- top: point.y,
10598
- angle: normalizeSignedAngle(ancestor.angle + Number(element.angle ?? 0))
10599
- };
10600
- };
10601
- const getGroupAbsoluteTransformFrame$1 = (group, pageChildren, fabric2, options) => {
10602
- const frame = getGroupTransformFrame(group, pageChildren);
10603
- const ancestor = getAncestorGroupTransform(group.id, pageChildren, fabric2);
10604
- const centerLocal = rotatedTopLeftToCenter(frame.left, frame.top, frame.width, frame.height, frame.angle);
10605
- const center = fabric2.util.transformPoint(new fabric2.Point(centerLocal.x, centerLocal.y), ancestor.matrix);
10606
- const topLeft = fabric2.util.transformPoint(new fabric2.Point(frame.left, frame.top), ancestor.matrix);
10607
- return {
10608
- left: topLeft.x,
10609
- top: topLeft.y,
10610
- width: frame.width,
10611
- height: frame.height,
10612
- centerX: center.x,
10613
- centerY: center.y,
10614
- angle: normalizeSignedAngle(ancestor.angle + frame.angle)
10615
- };
10616
- };
10617
- function preserveLogicalGroupTagDuringMove(selection, groupId) {
10618
- selection.__pixldocsGroupSelection = groupId;
10619
- }
10620
10521
  const SELECTION_PRIMARY = "hsl(217, 91%, 60%)";
10621
10522
  const SELECTION_BORDER_SCALE = 2;
10622
10523
  let ensureCanvaControlRenders = () => {
@@ -11070,18 +10971,12 @@ try {
11070
10971
  } catch (e) {
11071
10972
  }
11072
10973
  };
11073
- const wrapControlsFactory = (key) => {
11074
- if (typeof cu[key] !== "function") return;
11075
- const descriptor = Object.getOwnPropertyDescriptor(cu, key);
11076
- if (descriptor && descriptor.writable === false && !descriptor.set) return;
11077
- const original = cu[key].bind(cu);
11078
- try {
11079
- cu[key] = () => installPillRenders(original());
11080
- } catch {
11081
- }
11082
- };
11083
- wrapControlsFactory("createObjectDefaultControls");
11084
- wrapControlsFactory("createTextboxDefaultControls");
10974
+ const origObj = cu.createObjectDefaultControls.bind(cu);
10975
+ cu.createObjectDefaultControls = () => installPillRenders(origObj());
10976
+ if (typeof cu.createTextboxDefaultControls === "function") {
10977
+ const origTb = cu.createTextboxDefaultControls.bind(cu);
10978
+ cu.createTextboxDefaultControls = () => installPillRenders(origTb());
10979
+ }
11085
10980
  const wrapClassCreateControls = (Klass) => {
11086
10981
  if (!Klass || typeof Klass.createControls !== "function") return;
11087
10982
  const orig = Klass.createControls.bind(Klass);
@@ -11148,8 +11043,6 @@ const scaleUpdateNumber = (updates, source, key, factor) => {
11148
11043
  };
11149
11044
  const GROUP_TEXT_RESIZE_DEBUG_PREFIX = "[Pixldocs][group-text-corner-resize]";
11150
11045
  const GROUP_TEXT_RESIZE_DEBUG_MAX_ENTRIES = 200;
11151
- const GROUP_IMAGE_RESIZE_DEBUG_PREFIX = "[Pixldocs][group-image-side-resize]";
11152
- const GROUP_IMAGE_RESIZE_DEBUG_MAX_ENTRIES = 300;
11153
11046
  const isCornerResizeHandle = (handle) => handle === "tl" || handle === "tr" || handle === "bl" || handle === "br";
11154
11047
  const summarizeFabricObjectForResizeDebug = (obj) => {
11155
11048
  var _a2;
@@ -11212,43 +11105,6 @@ const logGroupTextResizeDebug = (phase, payload) => {
11212
11105
  console.log(GROUP_TEXT_RESIZE_DEBUG_PREFIX, phase, payload);
11213
11106
  }
11214
11107
  };
11215
- const isGroupResizeImageLikeObject = (obj) => {
11216
- var _a2;
11217
- return !!obj && (obj instanceof fabric__namespace.FabricImage || obj instanceof fabric__namespace.Group && (obj.__cropGroup || ((_a2 = obj._ct) == null ? void 0 : _a2.isCropGroup)));
11218
- };
11219
- const logGroupImageResizeDebug = (phase, payload) => {
11220
- if (typeof console === "undefined") return;
11221
- try {
11222
- const seen = /* @__PURE__ */ new WeakSet();
11223
- const normalize = (value) => {
11224
- if (value == null) return value;
11225
- const valueType = typeof value;
11226
- if (valueType === "number") return Number.isFinite(value) ? Math.round(value * 1e3) / 1e3 : String(value);
11227
- if (valueType === "string" || valueType === "boolean") return value;
11228
- if (valueType === "function") return `[Function ${value.name || "anonymous"}]`;
11229
- if (Array.isArray(value)) return value.map((entry) => normalize(entry));
11230
- if (valueType === "object") {
11231
- if (seen.has(value)) return "[Circular]";
11232
- seen.add(value);
11233
- if (value instanceof fabric__namespace.FabricObject) return normalize(summarizeFabricObjectForResizeDebug(value));
11234
- const output = {};
11235
- Object.entries(value).forEach(([key, entry]) => {
11236
- output[key] = normalize(entry);
11237
- });
11238
- return output;
11239
- }
11240
- return String(value);
11241
- };
11242
- const normalizedPayload = normalize(payload);
11243
- const line = `${GROUP_IMAGE_RESIZE_DEBUG_PREFIX} ${phase} ${JSON.stringify(normalizedPayload)}`;
11244
- const debugWindow = window;
11245
- debugWindow.__pixldocsGroupImageResizeLogs = Array.isArray(debugWindow.__pixldocsGroupImageResizeLogs) ? debugWindow.__pixldocsGroupImageResizeLogs.slice(-GROUP_IMAGE_RESIZE_DEBUG_MAX_ENTRIES + 1) : [];
11246
- debugWindow.__pixldocsGroupImageResizeLogs.push(line);
11247
- console.log(line);
11248
- } catch {
11249
- console.log(GROUP_IMAGE_RESIZE_DEBUG_PREFIX, phase, payload);
11250
- }
11251
- };
11252
11108
  const bakeTextboxScaleIntoTypography = (obj, sourceElement) => {
11253
11109
  const sx = Math.abs(obj.scaleX ?? 1) || 1;
11254
11110
  const sy = Math.abs(obj.scaleY ?? 1) || 1;
@@ -11322,8 +11178,6 @@ const bakeTextboxScaleIntoTypography = (obj, sourceElement) => {
11322
11178
  };
11323
11179
  return updates;
11324
11180
  };
11325
- const getElementFabricPlacement = (element, pageChildren, options) => getElementFabricPlacement$1(element, pageChildren, fabric__namespace);
11326
- const getGroupAbsoluteTransformFrame = (group, pageChildren, options) => getGroupAbsoluteTransformFrame$1(group, pageChildren, fabric__namespace);
11327
11181
  function applyWarpAwareSelectionBorders(selection) {
11328
11182
  var _a2;
11329
11183
  if (selection.__pixldocsOrigASHasBorders !== void 0) {
@@ -11332,7 +11186,6 @@ function applyWarpAwareSelectionBorders(selection) {
11332
11186
  }
11333
11187
  selection.hasBorders = true;
11334
11188
  selection.hasControls = true;
11335
- if (selection.__pixldocsGroupSelection) return;
11336
11189
  try {
11337
11190
  if (selection.__pixldocsAlignedAngle == null) {
11338
11191
  const kids = selection.getObjects();
@@ -11459,46 +11312,10 @@ const PageCanvas = react.forwardRef(
11459
11312
  const [ready, setReady] = react.useState(false);
11460
11313
  const [unlockRequestId, setUnlockRequestId] = react.useState(0);
11461
11314
  const applyLogicalGroupSelectionVisualState = react.useCallback((selection, groupId) => {
11462
- var _a2, _b2;
11315
+ var _a2;
11463
11316
  selection.__pixldocsGroupSelection = groupId;
11464
11317
  delete selection.__pixldocsLogicalGroupIds;
11465
11318
  selection.hasBorders = true;
11466
- try {
11467
- const membersBeforeFrame = selection.getObjects();
11468
- const selectionMatrixBefore = selection.calcTransformMatrix();
11469
- const memberWorldMatrices = membersBeforeFrame.map((member) => fabric__namespace.util.multiplyTransformMatrices(
11470
- selectionMatrixBefore,
11471
- member.calcOwnMatrix()
11472
- ));
11473
- const pageChildren2 = ((_a2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
11474
- const groupNode = findNodeById(pageChildren2, groupId);
11475
- const groupFrame = groupNode && isGroup(groupNode) ? getGroupAbsoluteTransformFrame(groupNode, pageChildren2, pageBoundsOptions) : null;
11476
- const groupAngle = groupFrame ? groupFrame.angle : 0;
11477
- if (Number.isFinite(groupAngle)) {
11478
- selection.set({ angle: groupAngle, scaleX: 1, scaleY: 1, skewX: 0, skewY: 0 });
11479
- if (groupFrame) {
11480
- selection.setPositionByOrigin(
11481
- new fabric__namespace.Point(groupFrame.centerX, groupFrame.centerY),
11482
- "center",
11483
- "center"
11484
- );
11485
- }
11486
- const invSelectionAfter = fabric__namespace.util.invertTransform(
11487
- selection.calcTransformMatrix()
11488
- );
11489
- membersBeforeFrame.forEach((member, index) => {
11490
- const localMatrix = fabric__namespace.util.multiplyTransformMatrices(
11491
- invSelectionAfter,
11492
- memberWorldMatrices[index]
11493
- );
11494
- fabric__namespace.util.applyTransformToObject(member, localMatrix);
11495
- member.setCoords();
11496
- member.dirty = true;
11497
- });
11498
- selection.setCoords();
11499
- }
11500
- } catch {
11501
- }
11502
11319
  const members = selection.getObjects();
11503
11320
  for (const prev of suppressGroupMemberBordersRef.current) {
11504
11321
  if (members.includes(prev)) continue;
@@ -11522,7 +11339,7 @@ const PageCanvas = react.forwardRef(
11522
11339
  if (m.__pixldocsOrigHasControls === void 0) m.__pixldocsOrigHasControls = m.hasControls;
11523
11340
  m.hasBorders = false;
11524
11341
  m.hasControls = false;
11525
- if (m.__cropGroup || ((_b2 = m._ct) == null ? void 0 : _b2.isCropGroup)) {
11342
+ if (m.__cropGroup || ((_a2 = m._ct) == null ? void 0 : _a2.isCropGroup)) {
11526
11343
  if (m.__pixldocsOrigLockScalingX === void 0) {
11527
11344
  m.__pixldocsOrigLockScalingX = m.lockScalingX;
11528
11345
  m.__pixldocsOrigLockScalingY = m.lockScalingY;
@@ -11532,7 +11349,7 @@ const PageCanvas = react.forwardRef(
11532
11349
  }
11533
11350
  }
11534
11351
  applyWarpAwareSelectionBorders(selection);
11535
- }, [pageId]);
11352
+ }, []);
11536
11353
  const pageBoundsOptions = react.useMemo(
11537
11354
  () => ({ pageContentWidth: canvasWidth, pageContentHeight: canvasHeight }),
11538
11355
  [canvasWidth, canvasHeight]
@@ -11606,6 +11423,7 @@ const PageCanvas = react.forwardRef(
11606
11423
  const preserveSelectionAfterTransformIdRef = react.useRef(null);
11607
11424
  const groupSelectionTransformStartRef = react.useRef(null);
11608
11425
  const activeSelectionMoveStartRef = react.useRef(null);
11426
+ const sectionGroupTransientImagesRef = react.useRef(null);
11609
11427
  setGroupOverlayLiveBoundsRef.current = setGroupOverlayLiveBounds;
11610
11428
  const {
11611
11429
  selectElements,
@@ -12451,6 +12269,7 @@ const PageCanvas = react.forwardRef(
12451
12269
  fabricCanvas.__fontCleanup = fontCleanup;
12452
12270
  fabricCanvas.__isUserTransforming = false;
12453
12271
  fabricCanvas.on("mouse:down", () => {
12272
+ groupSelectionTransformStartRef.current = null;
12454
12273
  activeSelectionMoveStartRef.current = null;
12455
12274
  activeSelectionResizeHandleRef.current = null;
12456
12275
  const active = fabricCanvas.getActiveObject();
@@ -12461,7 +12280,6 @@ const PageCanvas = react.forwardRef(
12461
12280
  selectionLeft: rect.left,
12462
12281
  selectionTop: rect.top
12463
12282
  };
12464
- prepareGroupSelectionTransformStart(active);
12465
12283
  }
12466
12284
  if (fabricCanvas._currentTransform) {
12467
12285
  fabricCanvas.__isUserTransforming = true;
@@ -12523,8 +12341,101 @@ const PageCanvas = react.forwardRef(
12523
12341
  });
12524
12342
  }
12525
12343
  });
12526
- fabricCanvas.on("object:moving", () => {
12344
+ const collectSectionGroupImageDescendantObjects = (groupNode) => {
12345
+ const ids = getAllElementIds(groupNode.children ?? []);
12346
+ if (ids.length === 0) return [];
12347
+ const elementById = new Map(elementsRef.current.map((el) => [el.id, el]));
12348
+ const out = [];
12349
+ for (const id of ids) {
12350
+ const el = elementById.get(id);
12351
+ if (!el || el.type !== "image") continue;
12352
+ const obj = fabricCanvas.getObjects().find((o) => getObjectId(o) === id);
12353
+ if (obj) out.push(obj);
12354
+ }
12355
+ return out;
12356
+ };
12357
+ const ensureSectionGroupTransientSnapshot = (group) => {
12358
+ var _a2;
12359
+ if (!group || !(group instanceof fabric__namespace.Group)) return false;
12360
+ if (!group.__docuforgeSectionGroup) return false;
12361
+ const groupId = getObjectId(group);
12362
+ if (!groupId) return false;
12363
+ const existing = sectionGroupTransientImagesRef.current;
12364
+ if (existing && existing.groupId === groupId && existing.group === group) return true;
12365
+ const pageChildrenLocal = ((_a2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
12366
+ const node = findNodeById(pageChildrenLocal, groupId);
12367
+ if (!node || !isGroup(node)) return false;
12368
+ const images = collectSectionGroupImageDescendantObjects(node);
12369
+ const gcx = group.left ?? 0;
12370
+ const gcy = group.top ?? 0;
12371
+ const gangle = group.angle ?? 0;
12372
+ const gsx = group.scaleX ?? 1;
12373
+ const gsy = group.scaleY ?? 1;
12374
+ const rad = -gangle * Math.PI / 180;
12375
+ const cos0 = Math.cos(rad);
12376
+ const sin0 = Math.sin(rad);
12377
+ const snap = images.map((obj) => {
12378
+ const icx = obj.left ?? 0;
12379
+ const icy = obj.top ?? 0;
12380
+ const dx = icx - gcx;
12381
+ const dy = icy - gcy;
12382
+ const rx = dx * cos0 - dy * sin0;
12383
+ const ry = dx * sin0 + dy * cos0;
12384
+ return {
12385
+ obj,
12386
+ localX: gsx ? rx / gsx : rx,
12387
+ localY: gsy ? ry / gsy : ry,
12388
+ relAngle: (obj.angle ?? 0) - gangle,
12389
+ relSx: (obj.scaleX ?? 1) / (gsx || 1),
12390
+ relSy: (obj.scaleY ?? 1) / (gsy || 1)
12391
+ };
12392
+ });
12393
+ sectionGroupTransientImagesRef.current = {
12394
+ groupId,
12395
+ group,
12396
+ group0: { cx: gcx, cy: gcy, angle: gangle, sx: gsx, sy: gsy },
12397
+ images: snap
12398
+ };
12399
+ return true;
12400
+ };
12401
+ const applySectionGroupTransientTransform = () => {
12402
+ const snap = sectionGroupTransientImagesRef.current;
12403
+ if (!snap || snap.images.length === 0) return;
12404
+ const group = snap.group;
12405
+ const gcx = group.left ?? 0;
12406
+ const gcy = group.top ?? 0;
12407
+ const gangle = group.angle ?? 0;
12408
+ const gsx = group.scaleX ?? 1;
12409
+ const gsy = group.scaleY ?? 1;
12410
+ const rad = gangle * Math.PI / 180;
12411
+ const cos = Math.cos(rad);
12412
+ const sin = Math.sin(rad);
12413
+ for (const entry of snap.images) {
12414
+ const lx = entry.localX * gsx;
12415
+ const ly = entry.localY * gsy;
12416
+ const wx = lx * cos - ly * sin;
12417
+ const wy = lx * sin + ly * cos;
12418
+ entry.obj.set({
12419
+ left: gcx + wx,
12420
+ top: gcy + wy,
12421
+ angle: entry.relAngle + gangle,
12422
+ scaleX: entry.relSx * gsx,
12423
+ scaleY: entry.relSy * gsy
12424
+ });
12425
+ entry.obj.setCoords();
12426
+ entry.obj.dirty = true;
12427
+ }
12428
+ };
12429
+ const clearSectionGroupTransientSnapshot = () => {
12430
+ sectionGroupTransientImagesRef.current = null;
12431
+ };
12432
+ const maybeFollowSectionGroupTransient = (target) => {
12433
+ if (!ensureSectionGroupTransientSnapshot(target)) return;
12434
+ applySectionGroupTransientTransform();
12435
+ };
12436
+ fabricCanvas.on("object:moving", (e) => {
12527
12437
  var _a2, _b2;
12438
+ maybeFollowSectionGroupTransient((e == null ? void 0 : e.target) ?? null);
12528
12439
  fabricCanvas.__isUserTransforming = true;
12529
12440
  didTransformRef.current = true;
12530
12441
  if (drilledGroupIdRef.current) {
@@ -12566,8 +12477,9 @@ const PageCanvas = react.forwardRef(
12566
12477
  });
12567
12478
  }
12568
12479
  });
12569
- fabricCanvas.on("object:rotating", () => {
12480
+ fabricCanvas.on("object:rotating", (e) => {
12570
12481
  var _a2;
12482
+ maybeFollowSectionGroupTransient((e == null ? void 0 : e.target) ?? null);
12571
12483
  fabricCanvas.__isUserTransforming = true;
12572
12484
  didTransformRef.current = true;
12573
12485
  if (drilledGroupIdRef.current) {
@@ -12577,6 +12489,12 @@ const PageCanvas = react.forwardRef(
12577
12489
  }
12578
12490
  }
12579
12491
  });
12492
+ fabricCanvas.on("object:scaling", (e) => {
12493
+ maybeFollowSectionGroupTransient((e == null ? void 0 : e.target) ?? null);
12494
+ });
12495
+ fabricCanvas.on("mouse:up", () => {
12496
+ clearSectionGroupTransientSnapshot();
12497
+ });
12580
12498
  const syncSelectionToStore = () => {
12581
12499
  var _a2, _b2, _c, _d;
12582
12500
  if (!isActiveRef.current || isRebuildingRef.current || isSyncingSelectionToFabricRef.current || !allowSelection) return;
@@ -12963,22 +12881,16 @@ const PageCanvas = react.forwardRef(
12963
12881
  const pageChildren2 = ((_b2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
12964
12882
  const groupNode = findNodeById(pageChildren2, groupId);
12965
12883
  if (!groupNode) return;
12966
- const groupFrame = isGroup(groupNode) ? getGroupAbsoluteTransformFrame(groupNode, pageChildren2) : null;
12967
- const groupAbs = groupFrame ?? getAbsoluteBounds(groupNode, pageChildren2);
12884
+ const groupAbs = getAbsoluteBounds(groupNode, pageChildren2);
12968
12885
  const rect = active.getBoundingRect();
12969
- const center = active.getCenterPoint();
12970
12886
  groupSelectionTransformStartRef.current = {
12971
12887
  groupId,
12972
12888
  selection: active,
12973
12889
  selectionLeft: rect.left,
12974
12890
  selectionTop: rect.top,
12975
- selectionCenterX: center.x,
12976
- selectionCenterY: center.y,
12977
12891
  groupLeft: groupAbs.left,
12978
12892
  groupTop: groupAbs.top,
12979
- groupWidth: groupAbs.width,
12980
- groupHeight: groupAbs.height,
12981
- selectionAngle: (((groupFrame == null ? void 0 : groupFrame.angle) ?? active.angle ?? 0) % 360 + 360) % 360
12893
+ selectionAngle: ((active.angle ?? 0) % 360 + 360) % 360
12982
12894
  };
12983
12895
  };
12984
12896
  const restoreGroupSelectionVisualState = (selection, groupId) => {
@@ -13315,9 +13227,6 @@ const PageCanvas = react.forwardRef(
13315
13227
  fabricCanvas.on("mouse:down:before", (opt) => {
13316
13228
  var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
13317
13229
  const activeBeforeMouseDown = fabricCanvas.getActiveObject();
13318
- if (activeBeforeMouseDown instanceof fabric__namespace.ActiveSelection && activeBeforeMouseDown.__pixldocsGroupSelection) {
13319
- prepareGroupSelectionTransformStart(activeBeforeMouseDown);
13320
- }
13321
13230
  if (editLockRef.current) {
13322
13231
  const active = fabricCanvas.getActiveObject();
13323
13232
  if (active && (((_a2 = active._ct) == null ? void 0 : _a2.isCropGroup) || active.__cropGroup)) {
@@ -13417,7 +13326,6 @@ const PageCanvas = react.forwardRef(
13417
13326
  restoreGroupSelectionVisualState(selection, parent.id);
13418
13327
  fabricCanvas.setActiveObject(selection);
13419
13328
  selection.setCoords();
13420
- prepareGroupSelectionTransformStart(selection);
13421
13329
  fabricCanvas._target = selection;
13422
13330
  opt.target = selection;
13423
13331
  pendingGroupPromotionRef.current = { groupId: parent.id, selection };
@@ -13460,7 +13368,6 @@ const PageCanvas = react.forwardRef(
13460
13368
  restoreGroupSelectionVisualState(selection, parent.id);
13461
13369
  fabricCanvas.setActiveObject(selection);
13462
13370
  selection.setCoords();
13463
- prepareGroupSelectionTransformStart(selection);
13464
13371
  fabricCanvas._target = selection;
13465
13372
  opt.target = selection;
13466
13373
  pendingGroupPromotionRef.current = { groupId: parent.id, selection };
@@ -13729,29 +13636,34 @@ const PageCanvas = react.forwardRef(
13729
13636
  });
13730
13637
  const markSimpleTransform = (e) => {
13731
13638
  if (!isActiveRef.current) return;
13732
- prepareGroupSelectionTransformStart(e.target);
13733
13639
  markTransforming(e.target);
13734
13640
  };
13735
13641
  const getObjectFrameBoundsInSelection = (selection, obj, frameWidth, frameHeight) => {
13736
13642
  const w = Math.max(1, frameWidth ?? obj.width ?? 1);
13737
13643
  const h = Math.max(1, frameHeight ?? obj.height ?? 1);
13644
+ const originX = obj.originX ?? "left";
13645
+ const originY = obj.originY ?? "top";
13646
+ const localLeft = originX === "center" ? -w / 2 : originX === "right" ? -w : 0;
13647
+ const localTop = originY === "center" ? -h / 2 : originY === "bottom" ? -h : 0;
13738
13648
  const matrix = fabric__namespace.util.multiplyTransformMatrices(
13739
13649
  selection.calcTransformMatrix(),
13740
13650
  obj.calcOwnMatrix()
13741
13651
  );
13742
- const decomposed = fabric__namespace.util.qrDecompose(matrix);
13743
- const scaledW = Math.max(1, w * Math.abs(decomposed.scaleX || 1));
13744
- const scaledH = Math.max(1, h * Math.abs(decomposed.scaleY || 1));
13745
- const angleRad = (decomposed.angle ?? 0) * Math.PI / 180;
13746
- const cos = Math.cos(angleRad);
13747
- const sin = Math.sin(angleRad);
13748
- const left = decomposed.translateX - scaledW / 2 * cos + scaledH / 2 * sin;
13749
- const top = decomposed.translateY - scaledW / 2 * sin - scaledH / 2 * cos;
13652
+ const points = [
13653
+ new fabric__namespace.Point(localLeft, localTop),
13654
+ new fabric__namespace.Point(localLeft + w, localTop),
13655
+ new fabric__namespace.Point(localLeft + w, localTop + h),
13656
+ new fabric__namespace.Point(localLeft, localTop + h)
13657
+ ].map((point) => fabric__namespace.util.transformPoint(point, matrix));
13658
+ const xs = points.map((p) => p.x);
13659
+ const ys = points.map((p) => p.y);
13660
+ const left = Math.min(...xs);
13661
+ const top = Math.min(...ys);
13750
13662
  return {
13751
13663
  left,
13752
13664
  top,
13753
- width: scaledW,
13754
- height: scaledH
13665
+ width: Math.max(1, Math.max(...xs) - left),
13666
+ height: Math.max(1, Math.max(...ys) - top)
13755
13667
  };
13756
13668
  };
13757
13669
  fabricCanvas.on("object:added", (e) => {
@@ -13766,30 +13678,10 @@ const PageCanvas = react.forwardRef(
13766
13678
  fabricCanvas.on("selection:cleared", () => {
13767
13679
  });
13768
13680
  fabricCanvas.on("object:scaling", (e) => {
13769
- var _a2, _b2, _c, _d, _e, _f, _g, _h;
13681
+ var _a2, _b2, _c, _d, _e, _f;
13770
13682
  if (!isActiveRef.current) return;
13771
13683
  const t = e.target;
13772
13684
  if (t) lastResizeScaleTargetRef.current = t;
13773
- try {
13774
- const transformDbg = e.transform;
13775
- const cornerDbg = (transformDbg == null ? void 0 : transformDbg.corner) || "";
13776
- const children = t instanceof fabric__namespace.Group || t instanceof fabric__namespace.ActiveSelection ? t.getObjects() : [];
13777
- logGroupImageResizeDebug("scaling-entry", {
13778
- time: Math.round(performance.now()),
13779
- corner: cornerDbg,
13780
- targetType: t == null ? void 0 : t.type,
13781
- targetCtor: (_a2 = t == null ? void 0 : t.constructor) == null ? void 0 : _a2.name,
13782
- isActiveSelection: t instanceof fabric__namespace.ActiveSelection,
13783
- isGroup: t instanceof fabric__namespace.Group,
13784
- isCropGroup: !!(t && (t.__cropGroup || ((_b2 = t._ct) == null ? void 0 : _b2.isCropGroup))),
13785
- childCount: children.length,
13786
- childTypes: children.map((c) => c == null ? void 0 : c.type),
13787
- hasImageChild: children.some((c) => isGroupResizeImageLikeObject(c)),
13788
- target: t ? summarizeFabricObjectForResizeDebug(t) : null
13789
- });
13790
- } catch (err) {
13791
- console.warn("[Pixldocs][group-image-side-resize] scaling-entry log failed", err);
13792
- }
13793
13685
  prepareGroupSelectionTransformStart(t);
13794
13686
  markTransforming(t);
13795
13687
  didTransformRef.current = true;
@@ -13953,7 +13845,7 @@ const PageCanvas = react.forwardRef(
13953
13845
  time: Math.round(performance.now()),
13954
13846
  corner,
13955
13847
  groupSelectionId: obj.__pixldocsGroupSelection,
13956
- currentTransformAction: (_c = fabricCanvas._currentTransform) == null ? void 0 : _c.action,
13848
+ currentTransformAction: (_a2 = fabricCanvas._currentTransform) == null ? void 0 : _a2.action,
13957
13849
  selection: summarizeFabricObjectForResizeDebug(obj),
13958
13850
  textChildren: obj.getObjects().filter((child) => child instanceof fabric__namespace.Textbox).map((child) => summarizeFabricObjectForResizeDebug(child))
13959
13851
  };
@@ -13963,43 +13855,19 @@ const PageCanvas = react.forwardRef(
13963
13855
  const isXSide = corner === "ml" || corner === "mr";
13964
13856
  const sAxis = isXSide ? Math.abs(obj.scaleX ?? 1) : Math.abs(obj.scaleY ?? 1);
13965
13857
  if (sAxis > 1e-3) {
13966
- const hasRotatedChild = obj.getObjects().some((c) => {
13967
- const a = ((c.angle ?? 0) % 180 + 180) % 180;
13968
- return !(a < 0.5 || a > 179.5);
13969
- });
13970
- const selectionAngle = ((obj.angle ?? 0) % 180 + 180) % 180;
13971
- const isSelectionRotated = !(selectionAngle < 0.5 || selectionAngle > 179.5);
13972
- const shouldPinNonTextChildren = hasRotatedChild || isSelectionRotated;
13973
- const shouldDebugGroupImageResize = obj.getObjects().some((child) => isGroupResizeImageLikeObject(child));
13974
- if (shouldDebugGroupImageResize) {
13975
- logGroupImageResizeDebug("live-start", {
13976
- time: Math.round(performance.now()),
13977
- corner,
13978
- isXSide,
13979
- sAxis,
13980
- hasRotatedChild,
13981
- isSelectionRotated,
13982
- shouldPinNonTextChildren,
13983
- groupSelectionId: obj.__pixldocsGroupSelection,
13984
- selection: summarizeFabricObjectForResizeDebug(obj),
13985
- children: obj.getObjects().map((child) => summarizeFabricObjectForResizeDebug(child))
13986
- });
13987
- }
13988
- if ((isXSide || shouldPinNonTextChildren) && ((_d = groupShiftReflowSnapshotRef.current) == null ? void 0 : _d.selection) !== obj) {
13858
+ if (isXSide && ((_b2 = groupShiftReflowSnapshotRef.current) == null ? void 0 : _b2.selection) !== obj) {
13989
13859
  groupShiftReflowSnapshotRef.current = null;
13990
13860
  const logicalGroupId = obj.__pixldocsGroupSelection;
13991
13861
  if (logicalGroupId) {
13992
13862
  try {
13993
13863
  const state = useEditorStore.getState();
13994
- const pageChildren2 = ((_e = state.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _e.children) ?? [];
13864
+ const pageChildren2 = ((_c = state.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _c.children) ?? [];
13995
13865
  const groupNode = findNodeById(pageChildren2, logicalGroupId);
13996
13866
  if (groupNode && isGroup(groupNode) && !isStackLayoutMode(groupNode.layoutMode)) {
13997
13867
  const entries = obj.getObjects().map((c) => ({
13998
13868
  obj: c,
13999
13869
  id: getObjectId(c) ?? "",
14000
- left0: c.left ?? 0,
14001
13870
  top0: c.top ?? 0,
14002
- width0: (c.width ?? 0) * Math.abs(c.scaleX ?? 1),
14003
13871
  height0: (c.height ?? 0) * Math.abs(c.scaleY ?? 1)
14004
13872
  })).filter((e2) => e2.id).sort((a, b) => a.top0 - b.top0);
14005
13873
  if (entries.length > 1) {
@@ -14022,150 +13890,78 @@ const PageCanvas = react.forwardRef(
14022
13890
  const asTop0 = obj.top ?? 0;
14023
13891
  const asRect0 = obj.getBoundingRect();
14024
13892
  let didReflowTextChild = false;
14025
- if (hasRotatedChild) {
14026
- if (isXSide) {
14027
- obj._set("width", asW0 * sAxis);
14028
- obj._set("scaleX", 1);
14029
- } else {
14030
- obj._set("height", asH0 * sAxis);
14031
- obj._set("scaleY", 1);
14032
- }
14033
- }
14034
- const childCounterScale = hasRotatedChild ? 1 : 1 / sAxis;
14035
- let restoredNonTextAfterLayout = false;
14036
- const restoreNonTextChildren = (pins) => {
14037
- var _a3, _b3;
14038
- if (!shouldPinNonTextChildren || ((_a3 = groupShiftReflowSnapshotRef.current) == null ? void 0 : _a3.selection) !== obj) return;
14039
- for (const entry of groupShiftReflowSnapshotRef.current.children) {
14040
- const child = entry.obj;
14041
- if (child instanceof fabric__namespace.Textbox) continue;
14042
- if (child instanceof fabric__namespace.FabricImage || child instanceof fabric__namespace.Group && (child.__cropGroup || ((_b3 = child._ct) == null ? void 0 : _b3.isCropGroup))) {
14043
- const pin = pins == null ? void 0 : pins.get(child);
14044
- let targetLeft = hasRotatedChild && isXSide ? entry.left0 * sAxis : entry.left0;
14045
- let targetTop = hasRotatedChild && !isXSide ? entry.top0 * sAxis : entry.top0;
14046
- if (pin == null ? void 0 : pin.worldCenter) {
14047
- try {
14048
- const invSelectionMatrix = fabric__namespace.util.invertTransform(obj.calcTransformMatrix());
14049
- const localCenter = fabric__namespace.util.transformPoint(pin.worldCenter, invSelectionMatrix);
14050
- targetLeft = localCenter.x;
14051
- targetTop = localCenter.y;
14052
- } catch {
14053
- targetLeft = pin.left ?? targetLeft;
14054
- targetTop = pin.top ?? targetTop;
14055
- }
14056
- } else {
14057
- targetLeft = (pin == null ? void 0 : pin.left) ?? targetLeft;
14058
- targetTop = (pin == null ? void 0 : pin.top) ?? targetTop;
14059
- }
14060
- const beforeRestore = shouldDebugGroupImageResize ? summarizeFabricObjectForResizeDebug(child) : null;
14061
- if (Math.abs((child.left ?? 0) - targetLeft) > 0.01) child._set("left", targetLeft);
14062
- if (Math.abs((child.top ?? 0) - targetTop) > 0.01) child._set("top", targetTop);
14063
- if (isXSide) child._set("scaleX", childCounterScale);
14064
- else child._set("scaleY", childCounterScale);
14065
- child.setCoords();
14066
- child.dirty = true;
14067
- if (shouldDebugGroupImageResize) {
14068
- logGroupImageResizeDebug("restore-non-text", {
14069
- time: Math.round(performance.now()),
14070
- corner,
14071
- childId: getObjectId(child),
14072
- targetLeft,
14073
- targetTop,
14074
- pin,
14075
- before: beforeRestore,
14076
- after: summarizeFabricObjectForResizeDebug(child)
14077
- });
14078
- }
14079
- }
14080
- }
14081
- };
14082
- const projectRotatedTextPosition = (child) => {
14083
- var _a3;
14084
- if (!hasRotatedChild || ((_a3 = groupShiftReflowSnapshotRef.current) == null ? void 0 : _a3.selection) !== obj) return;
14085
- const entry = groupShiftReflowSnapshotRef.current.children.find((candidate) => candidate.obj === child);
14086
- if (!entry) return;
14087
- if (isXSide) child._set("left", entry.left0 * sAxis);
14088
- else child._set("top", entry.top0 * sAxis);
14089
- };
14090
13893
  for (const child of obj.getObjects()) {
14091
- if (child instanceof fabric__namespace.Group && (child.__cropGroup || ((_f = child._ct) == null ? void 0 : _f.isCropGroup))) {
14092
- const beforeImageChildResize = shouldDebugGroupImageResize ? summarizeFabricObjectForResizeDebug(child) : null;
13894
+ if (child instanceof fabric__namespace.Group && (child.__cropGroup || ((_d = child._ct) == null ? void 0 : _d.isCropGroup))) {
14093
13895
  const ct = child.__cropData;
14094
- if (ct) {
13896
+ if (!ct) continue;
13897
+ if (isXSide) {
14095
13898
  if (child.__asLiveOrigW == null) {
14096
- child.__asLiveOrigW = ct.frameW ?? child.width ?? 1;
14097
- }
14098
- if (child.__asLiveOrigH == null) {
14099
- child.__asLiveOrigH = ct.frameH ?? child.height ?? 1;
13899
+ const baseW = child.width ?? ct.frameW ?? 0;
13900
+ child.__asLiveOrigW = baseW * (child.scaleX ?? 1);
14100
13901
  }
14101
- if (isXSide) {
14102
- const newW = Math.max(1, Number(child.__asLiveOrigW) * sAxis);
13902
+ const origW = child.__asLiveOrigW;
13903
+ const newW = Math.max(20, origW * sAxis);
13904
+ if (Math.abs((child.width ?? 0) - newW) > 0.5) {
14103
13905
  ct.frameW = newW;
14104
13906
  child._set("width", newW);
14105
- } else {
14106
- const newH = Math.max(1, Number(child.__asLiveOrigH) * sAxis);
13907
+ child._set("scaleX", 1 / sAxis);
13908
+ try {
13909
+ updateCoverLayout(child);
13910
+ } catch {
13911
+ }
13912
+ child.setCoords();
13913
+ child.dirty = true;
13914
+ }
13915
+ } else {
13916
+ if (child.__asLiveOrigH == null) {
13917
+ const baseH = child.height ?? ct.frameH ?? 0;
13918
+ child.__asLiveOrigH = baseH * (child.scaleY ?? 1);
13919
+ }
13920
+ const origH = child.__asLiveOrigH;
13921
+ const newH = Math.max(20, origH * sAxis);
13922
+ if (Math.abs((child.height ?? 0) - newH) > 0.5) {
14107
13923
  ct.frameH = newH;
14108
13924
  child._set("height", newH);
13925
+ child._set("scaleY", 1 / sAxis);
13926
+ try {
13927
+ updateCoverLayout(child);
13928
+ } catch {
13929
+ }
13930
+ child.setCoords();
13931
+ child.dirty = true;
14109
13932
  }
14110
- try {
14111
- updateCoverLayout(child);
14112
- } catch {
14113
- }
14114
- }
14115
- if (isXSide) child._set("scaleX", childCounterScale);
14116
- else child._set("scaleY", childCounterScale);
14117
- child.setCoords();
14118
- child.dirty = true;
14119
- if (shouldDebugGroupImageResize) {
14120
- logGroupImageResizeDebug("live-crop-child-resized", {
14121
- time: Math.round(performance.now()),
14122
- corner,
14123
- sAxis,
14124
- childCounterScale,
14125
- before: beforeImageChildResize,
14126
- after: summarizeFabricObjectForResizeDebug(child),
14127
- cropData: ct ? { frameW: ct.frameW, frameH: ct.frameH } : null
14128
- });
14129
13933
  }
14130
- didReflowTextChild = true;
14131
13934
  continue;
14132
13935
  }
14133
13936
  if (child instanceof fabric__namespace.FabricImage && !child.__cropGroup && !child.smartElementType) {
14134
- const beforeImageChildResize = shouldDebugGroupImageResize ? summarizeFabricObjectForResizeDebug(child) : null;
14135
13937
  if (isXSide) {
14136
13938
  if (child.__asLiveOrigW == null) {
14137
- child.__asLiveOrigW = (child.width ?? 0) * Math.abs(child.scaleX ?? 1);
13939
+ child.__asLiveOrigW = (child.width ?? 0) * (child.scaleX ?? 1);
13940
+ }
13941
+ const origW = child.__asLiveOrigW;
13942
+ const newW = Math.max(1, origW * sAxis);
13943
+ if (Math.abs((child.width ?? 0) - newW) > 0.5) {
13944
+ child._set("width", newW);
13945
+ child._set("scaleX", 1 / sAxis);
13946
+ child.setCoords();
13947
+ child.dirty = true;
14138
13948
  }
14139
- const newW = Math.max(1, Number(child.__asLiveOrigW) * sAxis);
14140
- child._set("width", newW);
14141
13949
  } else {
14142
13950
  if (child.__asLiveOrigH == null) {
14143
- child.__asLiveOrigH = (child.height ?? 0) * Math.abs(child.scaleY ?? 1);
13951
+ child.__asLiveOrigH = (child.height ?? 0) * (child.scaleY ?? 1);
13952
+ }
13953
+ const origH = child.__asLiveOrigH;
13954
+ const newH = Math.max(1, origH * sAxis);
13955
+ if (Math.abs((child.height ?? 0) - newH) > 0.5) {
13956
+ child._set("height", newH);
13957
+ child._set("scaleY", 1 / sAxis);
13958
+ child.setCoords();
13959
+ child.dirty = true;
14144
13960
  }
14145
- const newH = Math.max(1, Number(child.__asLiveOrigH) * sAxis);
14146
- child._set("height", newH);
14147
- }
14148
- if (isXSide) child._set("scaleX", childCounterScale);
14149
- else child._set("scaleY", childCounterScale);
14150
- child.setCoords();
14151
- child.dirty = true;
14152
- if (shouldDebugGroupImageResize) {
14153
- logGroupImageResizeDebug("live-image-child-resized", {
14154
- time: Math.round(performance.now()),
14155
- corner,
14156
- sAxis,
14157
- childCounterScale,
14158
- liveOrigW: child.__asLiveOrigW,
14159
- liveOrigH: child.__asLiveOrigH,
14160
- before: beforeImageChildResize,
14161
- after: summarizeFabricObjectForResizeDebug(child)
14162
- });
14163
13961
  }
14164
- didReflowTextChild = true;
14165
13962
  continue;
14166
13963
  }
14167
13964
  if (!(child instanceof fabric__namespace.Textbox)) continue;
14168
- projectRotatedTextPosition(child);
14169
13965
  if (isXSide) {
14170
13966
  if (child.__asLiveOrigW == null) {
14171
13967
  child.__asLiveOrigW = (child.width ?? 0) * (child.scaleX ?? 1);
@@ -14174,7 +13970,7 @@ const PageCanvas = react.forwardRef(
14174
13970
  const newW = Math.max(20, origW * sAxis);
14175
13971
  if (Math.abs((child.width ?? 0) - newW) > 0.5) {
14176
13972
  child._set("width", newW);
14177
- child._set("scaleX", childCounterScale);
13973
+ child._set("scaleX", 1 / sAxis);
14178
13974
  try {
14179
13975
  child.initDimensions();
14180
13976
  } catch {
@@ -14187,14 +13983,10 @@ const PageCanvas = react.forwardRef(
14187
13983
  if (child.__asLiveOrigH == null) {
14188
13984
  child.__asLiveOrigH = (child.height ?? 0) * (child.scaleY ?? 1);
14189
13985
  }
14190
- if (child.__asLiveOrigMinH == null) {
14191
- const m = Number(child.minBoxHeight);
14192
- if (Number.isFinite(m) && m > 0) child.__asLiveOrigMinH = m;
14193
- }
14194
13986
  const origH = child.__asLiveOrigH;
14195
13987
  const newH = Math.max(20, origH * sAxis);
14196
13988
  child.minBoxHeight = newH;
14197
- child._set("scaleY", childCounterScale);
13989
+ child._set("scaleY", 1 / sAxis);
14198
13990
  try {
14199
13991
  child.initDimensions();
14200
13992
  } catch {
@@ -14204,7 +13996,7 @@ const PageCanvas = react.forwardRef(
14204
13996
  didReflowTextChild = true;
14205
13997
  }
14206
13998
  }
14207
- if (isXSide && !shouldPinNonTextChildren && ((_g = groupShiftReflowSnapshotRef.current) == null ? void 0 : _g.selection) === obj) {
13999
+ if (isXSide && ((_e = groupShiftReflowSnapshotRef.current) == null ? void 0 : _e.selection) === obj) {
14208
14000
  const snap = groupShiftReflowSnapshotRef.current;
14209
14001
  const anchorEntry = snap.children[0];
14210
14002
  const anchorTopLive = anchorEntry.obj.top ?? 0;
@@ -14237,26 +14029,10 @@ const PageCanvas = react.forwardRef(
14237
14029
  if (cornersBefore) {
14238
14030
  fixedMidBefore = corner === "ml" ? { x: (cornersBefore.tr.x + cornersBefore.br.x) / 2, y: (cornersBefore.tr.y + cornersBefore.br.y) / 2 } : { x: (cornersBefore.tl.x + cornersBefore.bl.x) / 2, y: (cornersBefore.tl.y + cornersBefore.bl.y) / 2 };
14239
14031
  }
14240
- const nonTextPinsBeforeLayout = shouldPinNonTextChildren ? new Map(obj.getObjects().map((child) => [child, {
14241
- left: child.left ?? 0,
14242
- top: child.top ?? 0,
14243
- worldCenter: child instanceof fabric__namespace.Textbox ? void 0 : child.getCenterPoint()
14244
- }])) : void 0;
14245
14032
  try {
14246
14033
  obj.triggerLayout();
14247
14034
  } catch {
14248
14035
  }
14249
- restoreNonTextChildren(nonTextPinsBeforeLayout);
14250
- restoredNonTextAfterLayout = !!nonTextPinsBeforeLayout;
14251
- if (shouldDebugGroupImageResize) {
14252
- logGroupImageResizeDebug("after-trigger-layout", {
14253
- time: Math.round(performance.now()),
14254
- corner,
14255
- selection: summarizeFabricObjectForResizeDebug(obj),
14256
- nonTextPinsBeforeLayout,
14257
- children: obj.getObjects().map((child) => summarizeFabricObjectForResizeDebug(child))
14258
- });
14259
- }
14260
14036
  obj._set("width", asW0);
14261
14037
  obj._set("scaleX", asSx0);
14262
14038
  obj._set("scaleY", asSy0);
@@ -14282,19 +14058,9 @@ const PageCanvas = react.forwardRef(
14282
14058
  obj._set("left", asLeft0);
14283
14059
  obj._set("top", asTop0);
14284
14060
  }
14285
- if (!restoredNonTextAfterLayout) restoreNonTextChildren();
14286
14061
  obj._set("width", asW0);
14287
14062
  obj._set("scaleX", asSx0);
14288
14063
  obj._set("scaleY", asSy0);
14289
- if (hasRotatedChild) {
14290
- if (isXSide) {
14291
- obj._set("width", asW0 * sAxis);
14292
- obj._set("scaleX", 1);
14293
- } else {
14294
- obj._set("height", asH0 * sAxis);
14295
- obj._set("scaleY", 1);
14296
- }
14297
- }
14298
14064
  obj.setCoords();
14299
14065
  obj.dirty = true;
14300
14066
  }
@@ -14386,7 +14152,7 @@ const PageCanvas = react.forwardRef(
14386
14152
  setGuides(gridGuidesForScale.length ? [...scaleGuides, ...gridGuidesForScale] : scaleGuides);
14387
14153
  if (drilledGroupIdRef.current) {
14388
14154
  try {
14389
- (_h = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _h.call(fabricCanvas);
14155
+ (_f = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _f.call(fabricCanvas);
14390
14156
  } catch {
14391
14157
  }
14392
14158
  }
@@ -14477,37 +14243,9 @@ const PageCanvas = react.forwardRef(
14477
14243
  }
14478
14244
  });
14479
14245
  fabricCanvas.on("object:rotating", (e) => {
14480
- var _a2, _b2;
14481
- prepareGroupSelectionTransformStart(e.target);
14482
14246
  markSimpleTransform(e);
14483
14247
  didTransformRef.current = true;
14484
14248
  const tr = e.target;
14485
- try {
14486
- const children = tr instanceof fabric__namespace.Group || tr instanceof fabric__namespace.ActiveSelection ? tr.getObjects() : [];
14487
- logGroupImageResizeDebug("rotating-entry", {
14488
- time: Math.round(performance.now()),
14489
- angle: tr == null ? void 0 : tr.angle,
14490
- targetType: tr == null ? void 0 : tr.type,
14491
- targetCtor: (_a2 = tr == null ? void 0 : tr.constructor) == null ? void 0 : _a2.name,
14492
- isActiveSelection: tr instanceof fabric__namespace.ActiveSelection,
14493
- isGroup: tr instanceof fabric__namespace.Group,
14494
- isCropGroup: !!(tr && (tr.__cropGroup || ((_b2 = tr._ct) == null ? void 0 : _b2.isCropGroup))),
14495
- childCount: children.length,
14496
- childTypes: children.map((c) => c == null ? void 0 : c.type),
14497
- hasImageChild: children.some((c) => isGroupResizeImageLikeObject(c)),
14498
- target: tr ? summarizeFabricObjectForResizeDebug(tr) : null,
14499
- children: children.map((c) => {
14500
- var _a3;
14501
- return {
14502
- type: c == null ? void 0 : c.type,
14503
- ctor: (_a3 = c == null ? void 0 : c.constructor) == null ? void 0 : _a3.name,
14504
- summary: summarizeFabricObjectForResizeDebug(c)
14505
- };
14506
- })
14507
- });
14508
- } catch (err) {
14509
- console.warn("[Pixldocs][group-image-side-resize] rotating-entry log failed", err);
14510
- }
14511
14249
  try {
14512
14250
  const getCursor = fabricCanvas.__pixldocsGetRotateCursor;
14513
14251
  const upper = fabricCanvas.upperCanvasEl;
@@ -14550,7 +14288,7 @@ const PageCanvas = react.forwardRef(
14550
14288
  setDrilledGroupBounds(null);
14551
14289
  drilledGroupIdRef.current = null;
14552
14290
  if (activeDuringMove instanceof fabric__namespace.ActiveSelection && groupIdToKeep) {
14553
- preserveLogicalGroupTagDuringMove(activeDuringMove, groupIdToKeep);
14291
+ restoreGroupSelectionVisualState(activeDuringMove, groupIdToKeep);
14554
14292
  }
14555
14293
  }
14556
14294
  if (e.target) e.target.__pixldocsDragMoved = true;
@@ -14603,7 +14341,7 @@ const PageCanvas = react.forwardRef(
14603
14341
  });
14604
14342
  let cropGroupSaveTimer = null;
14605
14343
  fabricCanvas.on("object:modified", (e) => {
14606
- var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k;
14344
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i;
14607
14345
  try {
14608
14346
  dragStarted = false;
14609
14347
  setGuides([]);
@@ -14612,43 +14350,18 @@ const PageCanvas = react.forwardRef(
14612
14350
  groupResizeActiveSnapRef.current = null;
14613
14351
  onDragEnd == null ? void 0 : onDragEnd();
14614
14352
  try {
14615
- const mt = e.target;
14616
- const children = mt instanceof fabric__namespace.Group || mt instanceof fabric__namespace.ActiveSelection ? mt.getObjects() : [];
14617
- logGroupImageResizeDebug("modified-entry", {
14618
- time: Math.round(performance.now()),
14619
- didTransform: didTransformRef.current,
14620
- targetType: mt == null ? void 0 : mt.type,
14621
- targetCtor: (_a2 = mt == null ? void 0 : mt.constructor) == null ? void 0 : _a2.name,
14622
- isActiveSelection: mt instanceof fabric__namespace.ActiveSelection,
14623
- isGroup: mt instanceof fabric__namespace.Group,
14624
- angle: mt == null ? void 0 : mt.angle,
14625
- childCount: children.length,
14626
- childTypes: children.map((c) => c == null ? void 0 : c.type),
14627
- hasImageChild: children.some((c) => isGroupResizeImageLikeObject(c)),
14628
- target: mt ? summarizeFabricObjectForResizeDebug(mt) : null,
14629
- children: children.map((c) => {
14630
- var _a3;
14631
- return {
14632
- type: c == null ? void 0 : c.type,
14633
- ctor: (_a3 = c == null ? void 0 : c.constructor) == null ? void 0 : _a3.name,
14634
- summary: summarizeFabricObjectForResizeDebug(c)
14635
- };
14636
- })
14637
- });
14638
- } catch (err) {
14639
- console.warn("[Pixldocs][group-image-side-resize] modified-entry log failed", err);
14640
- }
14641
- const modifiedTarget = e.target;
14642
- if (modifiedTarget instanceof fabric__namespace.ActiveSelection && modifiedTarget.getObjects().length === 0) {
14643
- didTransformRef.current = false;
14644
- groupSelectionTransformStartRef.current = null;
14645
- activeSelectionMoveStartRef.current = null;
14646
- activeSelectionResizeHandleRef.current = null;
14647
- unlockEditsSoon();
14648
- return;
14353
+ const t = e.target;
14354
+ if (t instanceof fabric__namespace.ActiveSelection) {
14355
+ for (const child of t.getObjects()) {
14356
+ delete child.__asLiveOrigW;
14357
+ delete child.__asLiveOrigH;
14358
+ }
14359
+ }
14360
+ } catch {
14649
14361
  }
14650
14362
  groupShiftReflowSnapshotRef.current = null;
14651
14363
  lockEdits();
14364
+ const modifiedTarget = e.target;
14652
14365
  const modifiedTargetId = modifiedTarget ? getObjectId(modifiedTarget) : null;
14653
14366
  const modifiedTargetElement = modifiedTargetId ? elementsRef.current.find((el) => el.id === modifiedTargetId) : null;
14654
14367
  if (modifiedTarget && (modifiedTargetElement == null ? void 0 : modifiedTargetElement.type) === "shape") {
@@ -14673,7 +14386,7 @@ const PageCanvas = react.forwardRef(
14673
14386
  const active = fabricCanvas.getActiveObject();
14674
14387
  const activeId = active ? getObjectId(active) : null;
14675
14388
  if (active && activeId && activeId !== "__background__" && !(active instanceof fabric__namespace.Group)) {
14676
- const pageChildrenForParent = ((_b2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
14389
+ const pageChildrenForParent = ((_a2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
14677
14390
  const parentGroup = findParentGroup(pageChildrenForParent, activeId);
14678
14391
  if (parentGroup && isGroup(parentGroup) && parentGroup.backgroundColor) {
14679
14392
  let fabricSectionGroup = active.group && active.group instanceof fabric__namespace.Group ? active.group : null;
@@ -14755,7 +14468,7 @@ const PageCanvas = react.forwardRef(
14755
14468
  useEditorStore.getState().reflowStackGroupInPage(pageId, groupId);
14756
14469
  }
14757
14470
  const stateAfter = useEditorStore.getState();
14758
- const pageAfter = ((_c = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _c.children) ?? [];
14471
+ const pageAfter = ((_b2 = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
14759
14472
  const groupNodeAfter = findNodeById(pageAfter, groupId);
14760
14473
  if (groupNodeAfter) {
14761
14474
  const abs = getAbsoluteBounds(groupNodeAfter, pageAfter);
@@ -14791,9 +14504,8 @@ const PageCanvas = react.forwardRef(
14791
14504
  const stateCrop = useEditorStore.getState();
14792
14505
  const pageCrop = stateCrop.canvas.pages.find((p) => p.id === pageId);
14793
14506
  const pageChildrenCrop = (pageCrop == null ? void 0 : pageCrop.children) ?? [];
14794
- const angleRad = (active.angle ?? 0) * Math.PI / 180;
14795
- const absLeft = (active.left ?? 0) - ct.frameW / 2 * Math.cos(angleRad) + ct.frameH / 2 * Math.sin(angleRad);
14796
- const absTop = (active.top ?? 0) - ct.frameW / 2 * Math.sin(angleRad) - ct.frameH / 2 * Math.cos(angleRad);
14507
+ const absLeft = (active.left ?? 0) - ct.frameW / 2;
14508
+ const absTop = (active.top ?? 0) - ct.frameH / 2;
14797
14509
  const storePosCrop = absoluteToStorePosition(absLeft, absTop, objId, pageChildrenCrop);
14798
14510
  updateElement2(objId, {
14799
14511
  width: ct.frameW,
@@ -14818,7 +14530,7 @@ const PageCanvas = react.forwardRef(
14818
14530
  }
14819
14531
  if (active && active instanceof fabric__namespace.Group && active.__docuforgeSectionGroup && getObjectId(active)) {
14820
14532
  const groupId = getObjectId(active);
14821
- const pageChildrenSec = ((_d = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _d.children) ?? [];
14533
+ const pageChildrenSec = ((_c = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _c.children) ?? [];
14822
14534
  const modifiedTarget2 = e == null ? void 0 : e.target;
14823
14535
  const resizeScaleTarget = lastResizeScaleTargetRef.current;
14824
14536
  lastResizeScaleTargetRef.current = null;
@@ -14849,7 +14561,7 @@ const PageCanvas = react.forwardRef(
14849
14561
  const node = findNodeById(pageChildrenSec, groupId);
14850
14562
  if (isChildModified && node && !groupMoved) {
14851
14563
  const stateAfter = useEditorStore.getState();
14852
- const pageAfter = ((_e = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _e.children) ?? [];
14564
+ const pageAfter = ((_d = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _d.children) ?? [];
14853
14565
  const groupNodeAfter = findNodeById(pageAfter, groupId);
14854
14566
  if (groupNodeAfter) {
14855
14567
  const abs = getAbsoluteBounds(groupNodeAfter, pageAfter);
@@ -14865,7 +14577,7 @@ const PageCanvas = react.forwardRef(
14865
14577
  }
14866
14578
  if (active && active instanceof fabric__namespace.Group && !(active instanceof fabric__namespace.ActiveSelection) && getObjectId(active)) {
14867
14579
  const groupId = getObjectId(active);
14868
- const pageChildren3 = ((_f = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _f.children) ?? [];
14580
+ const pageChildren3 = ((_e = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _e.children) ?? [];
14869
14581
  const w = (active.width ?? 0) * (active.scaleX ?? 1);
14870
14582
  const h = (active.height ?? 0) * (active.scaleY ?? 1);
14871
14583
  const centerX = active.left ?? 0;
@@ -14887,7 +14599,7 @@ const PageCanvas = react.forwardRef(
14887
14599
  }
14888
14600
  const activeObj = fabricCanvas.getActiveObject();
14889
14601
  let activeObjects = fabricCanvas.getActiveObjects();
14890
- const activeSelectionMoveStart = activeObj instanceof fabric__namespace.ActiveSelection && ((_g = activeSelectionMoveStartRef.current) == null ? void 0 : _g.selection) === activeObj ? activeSelectionMoveStartRef.current : null;
14602
+ const activeSelectionMoveStart = activeObj instanceof fabric__namespace.ActiveSelection && ((_f = activeSelectionMoveStartRef.current) == null ? void 0 : _f.selection) === activeObj ? activeSelectionMoveStartRef.current : null;
14891
14603
  const activeSelectionDelta = activeObj instanceof fabric__namespace.ActiveSelection && activeSelectionMoveStart ? (() => {
14892
14604
  const rect = activeObj.getBoundingRect();
14893
14605
  return {
@@ -14904,18 +14616,6 @@ const PageCanvas = react.forwardRef(
14904
14616
  const isActiveSelection = activeObj instanceof fabric__namespace.ActiveSelection || activeObjects.length > 1;
14905
14617
  const activeSelectionResizeHandle = isActiveSelection ? activeSelectionResizeHandleRef.current : null;
14906
14618
  const debugGroupTextCornerResize = activeObj instanceof fabric__namespace.ActiveSelection && isCornerResizeHandle(activeSelectionResizeHandle) && activeObjects.some((candidate) => candidate instanceof fabric__namespace.Textbox);
14907
- const debugGroupImageSideResize = activeObj instanceof fabric__namespace.ActiveSelection && (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb") && activeObjects.some((candidate) => isGroupResizeImageLikeObject(candidate));
14908
- if (debugGroupImageSideResize) {
14909
- logGroupImageResizeDebug("modified-start", {
14910
- time: Math.round(performance.now()),
14911
- handle: activeSelectionResizeHandle,
14912
- target: summarizeFabricObjectForResizeDebug(modifiedTarget),
14913
- selection: summarizeFabricObjectForResizeDebug(activeObj),
14914
- activeObjectIds: activeObjects.map((candidate) => getObjectId(candidate)),
14915
- selectedStoreIds: useEditorStore.getState().canvas.selectedIds,
14916
- members: activeObjects.map((candidate) => summarizeFabricObjectForResizeDebug(candidate))
14917
- });
14918
- }
14919
14619
  if (debugGroupTextCornerResize) {
14920
14620
  logGroupTextResizeDebug("modified-start", {
14921
14621
  time: Math.round(performance.now()),
@@ -14948,14 +14648,7 @@ const PageCanvas = react.forwardRef(
14948
14648
  const node = findNodeById(pageChildren2, id);
14949
14649
  return !!(node && isGroup(node));
14950
14650
  });
14951
- const activeSelectionHadTransform = activeObj instanceof fabric__namespace.ActiveSelection && (Math.abs((activeObj.scaleX ?? 1) - 1) > 0.01 || Math.abs((activeObj.scaleY ?? 1) - 1) > 0.01 || (() => {
14952
- var _a3;
14953
- const normAngle = (angle) => (angle % 360 + 360) % 360;
14954
- const startAngle = ((_a3 = groupSelectionTransformStartRef.current) == null ? void 0 : _a3.selection) === activeObj ? groupSelectionTransformStartRef.current.selectionAngle : 0;
14955
- const currentAngle = normAngle(activeObj.angle ?? 0);
14956
- const diff = Math.abs(currentAngle - normAngle(startAngle));
14957
- return Math.min(diff, 360 - diff) > 1;
14958
- })());
14651
+ const activeSelectionHadTransform = activeObj instanceof fabric__namespace.ActiveSelection && (Math.abs((activeObj.scaleX ?? 1) - 1) > 0.01 || Math.abs((activeObj.scaleY ?? 1) - 1) > 0.01 || Math.abs((activeObj.angle ?? 0) % 360) > 0.01);
14959
14652
  if (!anyCropGroup && activeSelectionDelta && !activeSelectionHadTransform && selectedLogicalGroupIds.length > 0) {
14960
14653
  const selectedStoreIds = useEditorStore.getState().canvas.selectedIds ?? [];
14961
14654
  const groupMemberIds = /* @__PURE__ */ new Set();
@@ -14996,13 +14689,7 @@ const PageCanvas = react.forwardRef(
14996
14689
  return;
14997
14690
  }
14998
14691
  }
14999
- const isActiveSelectionSideResize = isActiveSelection && (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb");
15000
- const normalizeAngle = (angle) => (angle % 360 + 360) % 360;
15001
- const shortestAngleDelta = (a, b) => {
15002
- const diff = Math.abs(normalizeAngle(a) - normalizeAngle(b));
15003
- return Math.min(diff, 360 - diff);
15004
- };
15005
- if (selectedElementIds.length > 0) {
14692
+ if (selectedElementIds.length > 0 && !anyCropGroup) {
15006
14693
  const firstObj = activeObjects[0];
15007
14694
  const firstId = getObjectId(firstObj);
15008
14695
  const parentGroups = selectedElementIds.map((id) => findParentGroup(pageChildren2, id)).filter((g) => g !== null);
@@ -15025,9 +14712,9 @@ const PageCanvas = react.forwardRef(
15025
14712
  let movedGroupLeft = groupAbs.left;
15026
14713
  let movedGroupTop = groupAbs.top;
15027
14714
  if (activeObj instanceof fabric__namespace.ActiveSelection && (transformStart == null ? void 0 : transformStart.groupId) === groupToMove.id) {
15028
- const selectionCenter = activeObj.getCenterPoint();
15029
- movedGroupLeft = transformStart.groupLeft + (selectionCenter.x - transformStart.selectionCenterX);
15030
- movedGroupTop = transformStart.groupTop + (selectionCenter.y - transformStart.selectionCenterY);
14715
+ const selectionRect = activeObj.getBoundingRect();
14716
+ movedGroupLeft = transformStart.groupLeft + (selectionRect.left - transformStart.selectionLeft);
14717
+ movedGroupTop = transformStart.groupTop + (selectionRect.top - transformStart.selectionTop);
15031
14718
  } else if (activeObj instanceof fabric__namespace.ActiveSelection && firstId && firstObj) {
15032
14719
  const firstNode = findNodeById(pageChildren2, firstId);
15033
14720
  if (firstNode) {
@@ -15063,58 +14750,19 @@ const PageCanvas = react.forwardRef(
15063
14750
  }
15064
14751
  const deltaX = movedGroupLeft - groupAbs.left;
15065
14752
  const deltaY = movedGroupTop - groupAbs.top;
15066
- const hadResizeHandle = isActiveSelection && !!activeSelectionResizeHandle;
15067
- const hadScale = isActiveSelection && activeObj && (hadResizeHandle || Math.abs((activeObj.scaleX ?? 1) - 1) > 0.01 || Math.abs((activeObj.scaleY ?? 1) - 1) > 0.01);
15068
- const startSelAngle = normalizeAngle((transformStart == null ? void 0 : transformStart.selectionAngle) ?? 0);
15069
- const currentSelAngle = isActiveSelection && activeObj ? normalizeAngle(activeObj.angle ?? 0) : 0;
15070
- const storedGroupAngle = normalizeAngle(Number(groupToMove.angle ?? 0));
15071
- const effectiveStartAngle = transformStart ? startSelAngle : storedGroupAngle;
15072
- const angleDelta = shortestAngleDelta(currentSelAngle, effectiveStartAngle);
15073
- const hadRotation = isActiveSelection && activeObj && angleDelta > 1;
15074
- if (activeGroupSelectionId === groupToMove.id && hadRotation && !hadScale && !activeSelectionResizeHandle && activeObj instanceof fabric__namespace.ActiveSelection) {
15075
- const { updateNode: updateNodeStore, commitHistory: commitHistoryStore, getCurrentElements } = useEditorStore.getState();
15076
- const center = activeObj.getCenterPoint();
15077
- const baseCenterX = (transformStart == null ? void 0 : transformStart.selectionCenterX) ?? groupAbs.left + groupAbs.width / 2;
15078
- const baseCenterY = (transformStart == null ? void 0 : transformStart.selectionCenterY) ?? groupAbs.top + groupAbs.height / 2;
15079
- const nextAbsLeft = groupAbs.left + (center.x - baseCenterX);
15080
- const nextAbsTop = groupAbs.top + (center.y - baseCenterY);
15081
- const storePos = absoluteToStorePosition(nextAbsLeft, nextAbsTop, groupToMove.id, pageChildren2);
15082
- updateNodeStore(groupToMove.id, {
15083
- left: storePos.left,
15084
- top: storePos.top,
15085
- angle: currentSelAngle
15086
- }, { recordHistory: false, skipLayoutRecalc: true });
15087
- commitHistoryStore();
15088
- restoreGroupSelectionVisualState(activeObj, groupToMove.id);
15089
- fabricCanvas.setActiveObject(activeObj);
15090
- activeObj.setCoords();
15091
- selectElements([groupToMove.id], false, false);
15092
- fabricCanvas.requestRenderAll();
15093
- elementsRef.current = getCurrentElements();
15094
- const restoreSnapshot = {
15095
- memberIds: activeObj.getObjects().map((obj) => getObjectId(obj)).filter((id) => !!id && id !== "__background__"),
15096
- groupSelectionId: groupToMove.id,
15097
- expiresAt: Date.now() + 1200
15098
- };
15099
- recentGroupSelectionRestoreRef.current = restoreSnapshot;
15100
- activeObj.getObjects().forEach((obj) => {
15101
- const objId = getObjectId(obj);
15102
- if (objId && objId !== "__background__") {
15103
- justModifiedIdsRef.current.add(objId);
15104
- modifiedIdsThisRound.add(objId);
15105
- }
15106
- });
15107
- setTimeout(() => modifiedIdsThisRound.forEach((id) => justModifiedIdsRef.current.delete(id)), 150);
15108
- groupSelectionTransformStartRef.current = null;
15109
- activeSelectionMoveStartRef.current = null;
15110
- activeSelectionResizeHandleRef.current = null;
15111
- unlockEditsSoon();
15112
- return;
15113
- }
15114
- if (!isActiveSelectionSideResize && !hadScale && !hadRotation && (Math.abs(deltaX) > 0.1 || Math.abs(deltaY) > 0.1)) {
14753
+ const hadScale = isActiveSelection && activeObj && (Math.abs((activeObj.scaleX ?? 1) - 1) > 0.01 || Math.abs((activeObj.scaleY ?? 1) - 1) > 0.01);
14754
+ const startSelAngle = (((transformStart == null ? void 0 : transformStart.selectionAngle) ?? 0) % 360 + 360) % 360;
14755
+ const currentSelAngle = isActiveSelection && activeObj ? ((activeObj.angle ?? 0) % 360 + 360) % 360 : 0;
14756
+ const angleDelta = Math.min(
14757
+ Math.abs(currentSelAngle - startSelAngle),
14758
+ 360 - Math.abs(currentSelAngle - startSelAngle)
14759
+ );
14760
+ const hadRotation = isActiveSelection && activeObj && angleDelta > 0.01;
14761
+ if (!hadScale && !hadRotation && (Math.abs(deltaX) > 0.1 || Math.abs(deltaY) > 0.1)) {
15115
14762
  const { updateNode: updateNodeStore, commitHistory: commitHistoryStore, getCurrentElements } = useEditorStore.getState();
15116
- const storePos = absoluteToStorePosition(movedGroupLeft, movedGroupTop, groupToMove.id, pageChildren2);
15117
- updateNodeStore(groupToMove.id, { left: storePos.left, top: storePos.top }, { recordHistory: false, skipLayoutRecalc: true });
14763
+ const newLeft = (groupToMove.left ?? 0) + deltaX;
14764
+ const newTop = (groupToMove.top ?? 0) + deltaY;
14765
+ updateNodeStore(groupToMove.id, { left: newLeft, top: newTop }, { recordHistory: false, skipLayoutRecalc: true });
15118
14766
  commitHistoryStore();
15119
14767
  pendingGroupDrillInRef.current = null;
15120
14768
  fabricCanvas.__activeEditingGroupId = null;
@@ -15139,8 +14787,6 @@ const PageCanvas = react.forwardRef(
15139
14787
  }
15140
14788
  setTimeout(() => modifiedIdsThisRound.forEach((id) => justModifiedIdsRef.current.delete(id)), 150);
15141
14789
  groupSelectionTransformStartRef.current = null;
15142
- activeSelectionMoveStartRef.current = null;
15143
- activeSelectionResizeHandleRef.current = null;
15144
14790
  const restoreSnapshot = {
15145
14791
  memberIds: targetObjects.map((obj) => getObjectId(obj)).filter((id) => !!id && id !== "__background__"),
15146
14792
  groupSelectionId,
@@ -15154,38 +14800,6 @@ const PageCanvas = react.forwardRef(
15154
14800
  }
15155
14801
  }
15156
14802
  const pendingCropGroupFrameBakes = [];
15157
- const logicalGroupSelectionId = activeObj instanceof fabric__namespace.ActiveSelection ? activeObj.__pixldocsGroupSelection : void 0;
15158
- const isLogicalGroupAS = !!logicalGroupSelectionId && !(activeObj == null ? void 0 : activeObj.__cropGroup) && !(activeObj == null ? void 0 : activeObj.__docuforgeSectionGroup);
15159
- const logicalGroupNodeForBake = logicalGroupSelectionId ? findNodeById(pageChildren2, logicalGroupSelectionId) : null;
15160
- const asAngleForBake = isLogicalGroupAS && activeObj ? normalizeAngle(Number(activeObj.angle ?? 0)) : 0;
15161
- const logicalGroupFinalFrame = (() => {
15162
- var _a3;
15163
- if (!isLogicalGroupAS || !logicalGroupSelectionId || !(activeObj instanceof fabric__namespace.ActiveSelection)) return null;
15164
- const baseline = ((_a3 = groupSelectionTransformStartRef.current) == null ? void 0 : _a3.groupId) === logicalGroupSelectionId ? groupSelectionTransformStartRef.current : null;
15165
- const localWidth = Math.max(1, (activeObj.width ?? (baseline == null ? void 0 : baseline.groupWidth) ?? 1) * Math.abs(activeObj.scaleX ?? 1));
15166
- const localHeight = Math.max(1, (activeObj.height ?? (baseline == null ? void 0 : baseline.groupHeight) ?? 1) * Math.abs(activeObj.scaleY ?? 1));
15167
- const center = activeObj.getCenterPoint();
15168
- const topLeft = centerToRotatedTopLeft(center.x, center.y, localWidth, localHeight, asAngleForBake);
15169
- return {
15170
- groupId: logicalGroupSelectionId,
15171
- left: topLeft.left,
15172
- top: topLeft.top,
15173
- width: localWidth,
15174
- height: localHeight,
15175
- centerX: center.x,
15176
- centerY: center.y,
15177
- angle: asAngleForBake,
15178
- matrix: fabric__namespace.util.composeMatrix({
15179
- translateX: center.x,
15180
- translateY: center.y,
15181
- angle: asAngleForBake,
15182
- scaleX: 1,
15183
- scaleY: 1,
15184
- skewX: 0,
15185
- skewY: 0
15186
- })
15187
- };
15188
- })();
15189
14803
  for (const obj of activeObjects) {
15190
14804
  const objId = getObjectId(obj);
15191
14805
  if (!objId || objId === "__background__") continue;
@@ -15231,15 +14845,16 @@ const PageCanvas = react.forwardRef(
15231
14845
  modifiedIdsThisRound.add(objId);
15232
14846
  let absoluteLeft;
15233
14847
  let absoluteTop;
15234
- const initialTopLeft = centerToRotatedTopLeft(
15235
- decomposed.translateX ?? (obj.left ?? 0),
15236
- decomposed.translateY ?? (obj.top ?? 0),
15237
- intrinsicWidth * Math.abs(decomposed.scaleX || 1),
15238
- intrinsicHeight * Math.abs(decomposed.scaleY || 1),
15239
- decomposed.angle ?? 0
15240
- );
15241
- absoluteLeft = initialTopLeft.left;
15242
- absoluteTop = initialTopLeft.top;
14848
+ if (isActiveSelection && activeObj) {
14849
+ const selectionMatrix = activeObj.calcTransformMatrix();
14850
+ const relativePoint = { x: obj.left ?? 0, y: obj.top ?? 0 };
14851
+ const absolutePoint = fabric__namespace.util.transformPoint(relativePoint, selectionMatrix);
14852
+ absoluteLeft = absolutePoint.x;
14853
+ absoluteTop = absolutePoint.y;
14854
+ } else {
14855
+ absoluteLeft = obj.left ?? 0;
14856
+ absoluteTop = obj.top ?? 0;
14857
+ }
15243
14858
  if (obj instanceof fabric__namespace.Group && obj.__cropGroup) {
15244
14859
  const ct = obj.__cropData;
15245
14860
  if (isActiveSelection && activeObj instanceof fabric__namespace.ActiveSelection) {
@@ -15249,22 +14864,14 @@ const PageCanvas = react.forwardRef(
15249
14864
  } else {
15250
14865
  const w = ((ct == null ? void 0 : ct.frameW) ?? obj.width ?? 0) * Math.abs(obj.scaleX ?? 1);
15251
14866
  const h = ((ct == null ? void 0 : ct.frameH) ?? obj.height ?? 0) * Math.abs(obj.scaleY ?? 1);
15252
- const angleRad = (decomposed.angle ?? obj.angle ?? 0) * Math.PI / 180;
15253
- absoluteLeft = (decomposed.translateX ?? absoluteLeft ?? 0) - w / 2 * Math.cos(angleRad) + h / 2 * Math.sin(angleRad);
15254
- absoluteTop = (decomposed.translateY ?? absoluteTop ?? 0) - w / 2 * Math.sin(angleRad) - h / 2 * Math.cos(angleRad);
14867
+ absoluteLeft = (absoluteLeft ?? 0) - w / 2;
14868
+ absoluteTop = (absoluteTop ?? 0) - h / 2;
15255
14869
  }
15256
14870
  } else if (obj instanceof fabric__namespace.FabricImage && (obj.originX === "center" || obj.originY === "center")) {
15257
- if (isActiveSelection && activeObj instanceof fabric__namespace.ActiveSelection) {
15258
- const frameBounds = getObjectFrameBoundsInSelection(activeObj, obj, obj.width ?? 0, obj.height ?? 0);
15259
- absoluteLeft = frameBounds.left;
15260
- absoluteTop = frameBounds.top;
15261
- } else {
15262
- const w = (obj.width ?? 0) * (obj.scaleX ?? 1);
15263
- const h = (obj.height ?? 0) * (obj.scaleY ?? 1);
15264
- const angleRad = (decomposed.angle ?? obj.angle ?? 0) * Math.PI / 180;
15265
- absoluteLeft = (decomposed.translateX ?? absoluteLeft ?? 0) - w / 2 * Math.cos(angleRad) + h / 2 * Math.sin(angleRad);
15266
- absoluteTop = (decomposed.translateY ?? absoluteTop ?? 0) - w / 2 * Math.sin(angleRad) - h / 2 * Math.cos(angleRad);
15267
- }
14871
+ const w = (obj.width ?? 0) * (obj.scaleX ?? 1);
14872
+ const h = (obj.height ?? 0) * (obj.scaleY ?? 1);
14873
+ absoluteLeft = (absoluteLeft ?? 0) - w / 2;
14874
+ absoluteTop = (absoluteTop ?? 0) - h / 2;
15268
14875
  }
15269
14876
  const preserveCornerGeometry = (sourceElement == null ? void 0 : sourceElement.type) === "shape" && (sourceElement.shapeType === "circle" || sourceElement.shapeType === "rounded-rect" || sourceElement.shapeType === "triangle");
15270
14877
  let finalWidth = intrinsicWidth;
@@ -15272,10 +14879,6 @@ const PageCanvas = react.forwardRef(
15272
14879
  let finalScaleX = decomposed.scaleX;
15273
14880
  let finalScaleY = decomposed.scaleY;
15274
14881
  let finalAbsoluteMatrix = absoluteMatrix;
15275
- let finalAngle = decomposed.angle;
15276
- let finalSkewX = decomposed.skewX;
15277
- let finalSkewY = decomposed.skewY;
15278
- let finalAngleFromDecomposed = true;
15279
14882
  if (obj instanceof fabric__namespace.Group && obj.__cropGroup) {
15280
14883
  const ct = obj.__cropData;
15281
14884
  if (ct) {
@@ -15292,14 +14895,12 @@ const PageCanvas = react.forwardRef(
15292
14895
  absoluteLeft = frameBounds.left;
15293
14896
  absoluteTop = frameBounds.top;
15294
14897
  } else {
15295
- const angleRad = (decomposed.angle ?? obj.angle ?? 0) * Math.PI / 180;
15296
- absoluteLeft = (decomposed.translateX ?? absoluteLeft) - finalWidth / 2 * Math.cos(angleRad) + finalHeight / 2 * Math.sin(angleRad);
15297
- absoluteTop = (decomposed.translateY ?? absoluteTop) - finalWidth / 2 * Math.sin(angleRad) - finalHeight / 2 * Math.cos(angleRad);
14898
+ absoluteLeft = (decomposed.translateX ?? absoluteLeft) - finalWidth / 2;
14899
+ absoluteTop = (decomposed.translateY ?? absoluteTop) - finalHeight / 2;
15298
14900
  }
15299
- const finalCenter = rotatedTopLeftToCenter(absoluteLeft, absoluteTop, finalWidth, finalHeight, decomposed.angle ?? (obj.angle ?? 0));
15300
14901
  finalAbsoluteMatrix = fabric__namespace.util.composeMatrix({
15301
- translateX: finalCenter.x,
15302
- translateY: finalCenter.y,
14902
+ translateX: absoluteLeft + finalWidth / 2,
14903
+ translateY: absoluteTop + finalHeight / 2,
15303
14904
  angle: decomposed.angle ?? (obj.angle ?? 0),
15304
14905
  scaleX: 1,
15305
14906
  scaleY: 1,
@@ -15334,12 +14935,6 @@ const PageCanvas = react.forwardRef(
15334
14935
  finalHeight = bakedH;
15335
14936
  finalScaleX = 1;
15336
14937
  finalScaleY = 1;
15337
- if (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb") {
15338
- finalAngle = (sourceElement == null ? void 0 : sourceElement.angle) ?? obj.angle ?? decomposed.angle;
15339
- finalSkewX = (sourceElement == null ? void 0 : sourceElement.skewX) ?? obj.skewX ?? 0;
15340
- finalSkewY = (sourceElement == null ? void 0 : sourceElement.skewY) ?? obj.skewY ?? 0;
15341
- if ((sourceElement == null ? void 0 : sourceElement.angle) !== void 0 || obj.angle !== void 0) finalAngleFromDecomposed = false;
15342
- }
15343
14938
  obj.set({ scaleX: 1, scaleY: 1 });
15344
14939
  const newSrc = renderSmartElementToDataUri(sourceElement.smartElementType, sourceElement.smartProps, bakedW, bakedH);
15345
14940
  if (newSrc) {
@@ -15355,7 +14950,6 @@ const PageCanvas = react.forwardRef(
15355
14950
  useEditorStore.getState().updateElement(objId, { src: newSrc }, { recordHistory: false, skipLayoutRecalc: true });
15356
14951
  }
15357
14952
  } else if (isActiveSelection && (Math.abs((decomposed.scaleX ?? 1) - 1) > 1e-3 || Math.abs((decomposed.scaleY ?? 1) - 1) > 1e-3)) {
15358
- const debugImageBeforeBake = debugGroupImageSideResize ? summarizeFabricObjectForResizeDebug(obj) : null;
15359
14953
  const sx = Math.abs(decomposed.scaleX || 1);
15360
14954
  const sy = Math.abs(decomposed.scaleY || 1);
15361
14955
  const handle = activeSelectionResizeHandle;
@@ -15389,9 +14983,22 @@ const PageCanvas = react.forwardRef(
15389
14983
  const localScaleX = 1 / sx;
15390
14984
  const localScaleY = 1 / sy;
15391
14985
  obj.set({ scaleX: localScaleX, scaleY: localScaleY });
15392
- const selectionMatrix = (_h = activeObj == null ? void 0 : activeObj.calcTransformMatrix) == null ? void 0 : _h.call(activeObj);
14986
+ const selectionMatrix = (_g = activeObj == null ? void 0 : activeObj.calcTransformMatrix) == null ? void 0 : _g.call(activeObj);
15393
14987
  const localCenter = selectionMatrix ? fabric__namespace.util.transformPoint(preBakeCenter, fabric__namespace.util.invertTransform(selectionMatrix)) : preBakeCenter;
15394
- obj.setPositionByOrigin(localCenter, "center", "center");
14988
+ const localWidth = bakedW * localScaleX;
14989
+ const localHeight = bakedH * localScaleY;
14990
+ const isCenterOrigin = obj.originX === "center" || obj.originY === "center";
14991
+ if (isCenterOrigin) {
14992
+ obj.set({
14993
+ left: localCenter.x,
14994
+ top: localCenter.y
14995
+ });
14996
+ } else {
14997
+ obj.set({
14998
+ left: localCenter.x - localWidth / 2,
14999
+ top: localCenter.y - localHeight / 2
15000
+ });
15001
+ }
15395
15002
  }
15396
15003
  obj.dirty = true;
15397
15004
  if (activeObj) activeObj.dirty = true;
@@ -15402,63 +15009,34 @@ const PageCanvas = react.forwardRef(
15402
15009
  finalHeight = bakedH;
15403
15010
  finalScaleX = 1;
15404
15011
  finalScaleY = 1;
15405
- if (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb") {
15406
- finalAngle = (sourceElement == null ? void 0 : sourceElement.angle) ?? obj.angle ?? decomposed.angle;
15407
- finalSkewX = (sourceElement == null ? void 0 : sourceElement.skewX) ?? obj.skewX ?? 0;
15408
- finalSkewY = (sourceElement == null ? void 0 : sourceElement.skewY) ?? obj.skewY ?? 0;
15409
- if ((sourceElement == null ? void 0 : sourceElement.angle) !== void 0 || obj.angle !== void 0) finalAngleFromDecomposed = false;
15410
- }
15411
15012
  try {
15412
- const angleRad = (finalAngle ?? 0) * Math.PI / 180;
15013
+ const angleRad = (decomposed.angle ?? 0) * Math.PI / 180;
15413
15014
  const cos = Math.cos(angleRad);
15414
15015
  const sin = Math.sin(angleRad);
15415
15016
  const hw = finalWidth / 2;
15416
15017
  const hh = finalHeight / 2;
15417
- absoluteLeft = decomposed.translateX - hw * cos + hh * sin;
15418
- absoluteTop = decomposed.translateY - hw * sin - hh * cos;
15018
+ const corners = [
15019
+ { x: -hw, y: -hh },
15020
+ { x: hw, y: -hh },
15021
+ { x: hw, y: hh },
15022
+ { x: -hw, y: hh }
15023
+ ].map((p) => ({
15024
+ x: decomposed.translateX + p.x * cos - p.y * sin,
15025
+ y: decomposed.translateY + p.x * sin + p.y * cos
15026
+ }));
15027
+ absoluteLeft = Math.min(...corners.map((p) => p.x));
15028
+ absoluteTop = Math.min(...corners.map((p) => p.y));
15419
15029
  } catch {
15420
15030
  }
15421
15031
  finalAbsoluteMatrix = fabric__namespace.util.composeMatrix({
15422
15032
  translateX: decomposed.translateX,
15423
15033
  translateY: decomposed.translateY,
15424
- angle: finalAngle ?? 0,
15034
+ angle: decomposed.angle ?? 0,
15425
15035
  scaleX: 1,
15426
15036
  scaleY: 1,
15427
- skewX: finalSkewX ?? 0,
15428
- skewY: finalSkewY ?? 0
15037
+ skewX: 0,
15038
+ skewY: 0
15429
15039
  });
15430
- if (debugGroupImageSideResize) {
15431
- logGroupImageResizeDebug("image-bake", {
15432
- time: Math.round(performance.now()),
15433
- handle: activeSelectionResizeHandle,
15434
- imageId: objId,
15435
- source: sourceElement ? {
15436
- left: sourceElement.left,
15437
- top: sourceElement.top,
15438
- width: sourceElement.width,
15439
- height: sourceElement.height,
15440
- angle: sourceElement.angle,
15441
- scaleX: sourceElement.scaleX,
15442
- scaleY: sourceElement.scaleY
15443
- } : null,
15444
- factors: { sx, sy, fx, fy, isCornerHandle },
15445
- beforeBake: debugImageBeforeBake,
15446
- afterBake: summarizeFabricObjectForResizeDebug(obj),
15447
- persistedGeometry: {
15448
- absoluteLeft,
15449
- absoluteTop,
15450
- finalWidth,
15451
- finalHeight,
15452
- finalScaleX,
15453
- finalScaleY,
15454
- finalAngle,
15455
- finalSkewX,
15456
- finalSkewY,
15457
- decomposed,
15458
- finalAbsoluteMatrix
15459
- }
15460
- });
15461
- }
15462
15040
  } else {
15463
15041
  finalWidth = intrinsicWidth;
15464
15042
  finalHeight = intrinsicHeight;
@@ -15468,33 +15046,16 @@ const PageCanvas = react.forwardRef(
15468
15046
  finalHeight = 0;
15469
15047
  finalScaleX = 1;
15470
15048
  finalScaleY = 1;
15471
- if (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb") {
15472
- finalAngle = (sourceElement == null ? void 0 : sourceElement.angle) ?? obj.angle ?? decomposed.angle;
15473
- finalSkewX = (sourceElement == null ? void 0 : sourceElement.skewX) ?? obj.skewX ?? 0;
15474
- finalSkewY = (sourceElement == null ? void 0 : sourceElement.skewY) ?? obj.skewY ?? 0;
15475
- if ((sourceElement == null ? void 0 : sourceElement.angle) !== void 0 || obj.angle !== void 0) finalAngleFromDecomposed = false;
15476
- }
15477
- } else if (obj instanceof fabric__namespace.Textbox && isActiveSelection && (activeSelectionResizeHandle != null || obj.__asLiveOrigW != null || obj.__asLiveOrigH != null || Math.abs((decomposed.scaleX ?? 1) - 1) > 1e-3 || Math.abs((decomposed.scaleY ?? 1) - 1) > 1e-3)) {
15478
- const liveOrigW = obj.__asLiveOrigW;
15479
- const liveOrigH = obj.__asLiveOrigH;
15480
- const decSx = Math.abs(decomposed.scaleX || 1);
15481
- const decSy = Math.abs(decomposed.scaleY || 1);
15482
- const sx = Math.abs(decSx - 1) < 1e-3 && liveOrigW && liveOrigW > 0 ? Math.max(1e-3, (obj.width ?? liveOrigW) / liveOrigW) : decSx;
15483
- const baseHForRecover = Number(
15484
- obj.minBoxHeight ?? obj.height ?? liveOrigH ?? 1
15485
- );
15486
- const sy = Math.abs(decSy - 1) < 1e-3 && liveOrigH && liveOrigH > 0 ? Math.max(1e-3, baseHForRecover / liveOrigH) : decSy;
15049
+ } else if (obj instanceof fabric__namespace.Textbox && isActiveSelection && (Math.abs((decomposed.scaleX ?? 1) - 1) > 1e-3 || Math.abs((decomposed.scaleY ?? 1) - 1) > 1e-3)) {
15050
+ const sx = Math.abs(decomposed.scaleX || 1);
15051
+ const sy = Math.abs(decomposed.scaleY || 1);
15487
15052
  const isLikelyUniformCorner = !activeSelectionResizeHandle && Math.abs(sx - sy) < 0.01 && Math.abs(sx - 1) > 1e-3;
15488
15053
  const isCornerHandle = activeSelectionResizeHandle === "tl" || activeSelectionResizeHandle === "tr" || activeSelectionResizeHandle === "bl" || activeSelectionResizeHandle === "br" || isLikelyUniformCorner;
15489
15054
  const isHeightSideHandle = activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb";
15490
15055
  const fontScale = isCornerHandle ? Math.max(1e-3, Math.sqrt(sx * sy)) : 1;
15491
- const widthBase = liveOrigW && liveOrigW > 0 ? liveOrigW : intrinsicWidth;
15492
- const heightBase = liveOrigH && liveOrigH > 0 ? liveOrigH : intrinsicHeight;
15493
- const bakedWidth = Math.max(20, widthBase * sx);
15494
- const liveMinHOrig = obj.__asLiveOrigMinH;
15495
- const currentMinH = Number(obj.minBoxHeight ?? (sourceElement == null ? void 0 : sourceElement.minBoxHeight));
15496
- const minHBase = Number.isFinite(liveMinHOrig) && liveMinHOrig > 0 ? liveMinHOrig : liveOrigH && liveOrigH > 0 ? currentMinH / sy : currentMinH;
15497
- const nextMinH = Number.isFinite(minHBase) && minHBase > 0 ? minHBase * sy : isHeightSideHandle ? Math.max(1, heightBase * sy) : void 0;
15056
+ const bakedWidth = Math.max(20, intrinsicWidth * sx);
15057
+ const baseMinH = Number(obj.minBoxHeight ?? (sourceElement == null ? void 0 : sourceElement.minBoxHeight));
15058
+ const nextMinH = Number.isFinite(baseMinH) && baseMinH > 0 ? baseMinH * sy : isHeightSideHandle ? Math.max(1, intrinsicHeight * sy) : void 0;
15498
15059
  const bakedTextScaleUpdates = { width: bakedWidth };
15499
15060
  const debugTextBeforeBake = debugGroupTextCornerResize ? summarizeFabricObjectForResizeDebug(obj) : null;
15500
15061
  finalScaleX = 1;
@@ -15553,9 +15114,14 @@ const PageCanvas = react.forwardRef(
15553
15114
  const localScaleX = 1 / sx;
15554
15115
  const localScaleY = 1 / sy;
15555
15116
  obj.set({ scaleX: localScaleX, scaleY: localScaleY });
15556
- const selectionMatrix = (_i = activeObj == null ? void 0 : activeObj.calcTransformMatrix) == null ? void 0 : _i.call(activeObj);
15117
+ const selectionMatrix = (_h = activeObj == null ? void 0 : activeObj.calcTransformMatrix) == null ? void 0 : _h.call(activeObj);
15557
15118
  const localCenter = selectionMatrix ? fabric__namespace.util.transformPoint(preBakeCenter, fabric__namespace.util.invertTransform(selectionMatrix)) : preBakeCenter;
15558
- obj.setPositionByOrigin(localCenter, "center", "center");
15119
+ const localWidth = bakedWidth * localScaleX;
15120
+ const localHeight = (obj.height ?? intrinsicHeight) * localScaleY;
15121
+ obj.set({
15122
+ left: localCenter.x - localWidth / 2,
15123
+ top: localCenter.y - localHeight / 2
15124
+ });
15559
15125
  } else {
15560
15126
  obj.setPositionByOrigin(preBakeCenter, "center", "center");
15561
15127
  }
@@ -15568,23 +15134,32 @@ const PageCanvas = react.forwardRef(
15568
15134
  } catch {
15569
15135
  }
15570
15136
  try {
15571
- const angleRad = (finalAngle ?? 0) * Math.PI / 180;
15137
+ const angleRad = (decomposed.angle ?? 0) * Math.PI / 180;
15572
15138
  const cos = Math.cos(angleRad);
15573
15139
  const sin = Math.sin(angleRad);
15574
15140
  const hw = finalWidth / 2;
15575
15141
  const hh = finalHeight / 2;
15576
- absoluteLeft = decomposed.translateX - hw * cos + hh * sin;
15577
- absoluteTop = decomposed.translateY - hw * sin - hh * cos;
15142
+ const corners = [
15143
+ { x: -hw, y: -hh },
15144
+ { x: hw, y: -hh },
15145
+ { x: hw, y: hh },
15146
+ { x: -hw, y: hh }
15147
+ ].map((p) => ({
15148
+ x: decomposed.translateX + p.x * cos - p.y * sin,
15149
+ y: decomposed.translateY + p.x * sin + p.y * cos
15150
+ }));
15151
+ absoluteLeft = Math.min(...corners.map((p) => p.x));
15152
+ absoluteTop = Math.min(...corners.map((p) => p.y));
15578
15153
  } catch {
15579
15154
  }
15580
15155
  finalAbsoluteMatrix = fabric__namespace.util.composeMatrix({
15581
15156
  translateX: decomposed.translateX,
15582
15157
  translateY: decomposed.translateY,
15583
- angle: finalAngle ?? 0,
15158
+ angle: decomposed.angle ?? 0,
15584
15159
  scaleX: 1,
15585
15160
  scaleY: 1,
15586
- skewX: finalSkewX ?? 0,
15587
- skewY: finalSkewY ?? 0
15161
+ skewX: 0,
15162
+ skewY: 0
15588
15163
  });
15589
15164
  if (debugGroupTextCornerResize) {
15590
15165
  logGroupTextResizeDebug("text-bake", {
@@ -15639,21 +15214,7 @@ const PageCanvas = react.forwardRef(
15639
15214
  const state = useEditorStore.getState();
15640
15215
  const page = state.canvas.pages.find((p) => p.id === pageId);
15641
15216
  const pageChildrenForSave = (page == null ? void 0 : page.children) ?? [];
15642
- const storePos = (logicalGroupFinalFrame == null ? void 0 : logicalGroupFinalFrame.groupId) === logicalGroupSelectionId ? (() => {
15643
- const localCenter = fabric__namespace.util.transformPoint(
15644
- new fabric__namespace.Point(decomposed.translateX ?? 0, decomposed.translateY ?? 0),
15645
- fabric__namespace.util.invertTransform(logicalGroupFinalFrame.matrix)
15646
- );
15647
- const localAngle = finalAngleFromDecomposed ? ((Number(finalAngle ?? 0) - asAngleForBake) % 360 + 540) % 360 - 180 : Number(finalAngle ?? 0);
15648
- const localAngleRad = localAngle * Math.PI / 180;
15649
- return {
15650
- left: localCenter.x - finalWidth / 2 * Math.cos(localAngleRad) + finalHeight / 2 * Math.sin(localAngleRad) + logicalGroupFinalFrame.width / 2,
15651
- top: localCenter.y - finalWidth / 2 * Math.sin(localAngleRad) - finalHeight / 2 * Math.cos(localAngleRad) + logicalGroupFinalFrame.height / 2
15652
- };
15653
- })() : absoluteToStorePosition(absoluteLeft, absoluteTop, objId, pageChildrenForSave);
15654
- if (isLogicalGroupAS && finalAngleFromDecomposed && typeof finalAngle === "number") {
15655
- finalAngle = ((finalAngle - asAngleForBake) % 360 + 540) % 360 - 180;
15656
- }
15217
+ const storePos = absoluteToStorePosition(absoluteLeft, absoluteTop, objId, pageChildrenForSave);
15657
15218
  const isLineObj = obj instanceof fabric__namespace.Line;
15658
15219
  const isAutoShrinkText = (sourceElement == null ? void 0 : sourceElement.type) === "text" && sourceElement.overflowPolicy === "auto-shrink";
15659
15220
  const autoShrinkStoredHeight = isAutoShrinkText ? sourceElement.height : void 0;
@@ -15665,17 +15226,13 @@ const PageCanvas = react.forwardRef(
15665
15226
  // so finalWidth already reflects the new width chosen by the user.
15666
15227
  width: finalWidth,
15667
15228
  height: isLineObj ? 0 : isAutoShrinkText ? typeof autoShrinkStoredHeight === "number" ? autoShrinkStoredHeight : finalHeight : finalHeight,
15668
- angle: finalAngle,
15669
- skewX: isLineObj ? 0 : finalSkewX,
15670
- skewY: isLineObj ? 0 : finalSkewY,
15229
+ angle: decomposed.angle,
15230
+ skewX: isLineObj ? 0 : decomposed.skewX,
15231
+ skewY: isLineObj ? 0 : decomposed.skewY,
15671
15232
  scaleX: finalScaleX,
15672
- scaleY: finalScaleY
15233
+ scaleY: finalScaleY,
15234
+ transformMatrix: finalAbsoluteMatrix
15673
15235
  };
15674
- if (!isLogicalGroupAS) {
15675
- elementUpdate.transformMatrix = finalAbsoluteMatrix;
15676
- } else {
15677
- elementUpdate.transformMatrix = void 0;
15678
- }
15679
15236
  if (obj instanceof fabric__namespace.Textbox) {
15680
15237
  const bakedTextScaleUpdates = obj.__pixldocsBakedTextScaleUpdates;
15681
15238
  if (bakedTextScaleUpdates && typeof bakedTextScaleUpdates === "object") {
@@ -15706,41 +15263,10 @@ const PageCanvas = react.forwardRef(
15706
15263
  objectBeforeStoreWrite: summarizeFabricObjectForResizeDebug(obj)
15707
15264
  });
15708
15265
  }
15709
- if (debugGroupImageSideResize && isGroupResizeImageLikeObject(obj)) {
15710
- logGroupImageResizeDebug("store-update-image", {
15711
- time: Math.round(performance.now()),
15712
- handle: activeSelectionResizeHandle,
15713
- imageId: objId,
15714
- storePos,
15715
- elementUpdate,
15716
- objectBeforeStoreWrite: summarizeFabricObjectForResizeDebug(obj)
15717
- });
15718
- }
15719
15266
  updateElement(objId, elementUpdate, { recordHistory: false, skipLayoutRecalc: true });
15720
15267
  obj.setCoords();
15721
- delete obj.__asLiveOrigW;
15722
- delete obj.__asLiveOrigH;
15723
- delete obj.__asLiveOrigMinH;
15724
15268
  }
15725
- if (isLogicalGroupAS && logicalGroupSelectionId && activeObj instanceof fabric__namespace.ActiveSelection) {
15726
- try {
15727
- const pageChildrenForGroup = ((_j = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _j.children) ?? [];
15728
- const groupNode = findNodeById(pageChildrenForGroup, logicalGroupSelectionId);
15729
- if (groupNode && logicalGroupFinalFrame) {
15730
- const storePosGroup = absoluteToStorePosition(logicalGroupFinalFrame.left, logicalGroupFinalFrame.top, logicalGroupSelectionId, pageChildrenForGroup);
15731
- useEditorStore.getState().updateNode(logicalGroupSelectionId, {
15732
- left: storePosGroup.left,
15733
- top: storePosGroup.top,
15734
- width: logicalGroupFinalFrame.width,
15735
- height: logicalGroupFinalFrame.height,
15736
- angle: logicalGroupFinalFrame.angle
15737
- }, { recordHistory: false, skipLayoutRecalc: true });
15738
- }
15739
- } catch (err) {
15740
- console.warn("[Pixldocs] logical-group envelope persist failed", err);
15741
- }
15742
- }
15743
- const pageChildrenForReflow = ((_k = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _k.children) ?? [];
15269
+ const pageChildrenForReflow = ((_i = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _i.children) ?? [];
15744
15270
  const stackGroupsToReflow = /* @__PURE__ */ new Set();
15745
15271
  for (const id of modifiedIdsThisRound) {
15746
15272
  const parent = findParentGroup(pageChildrenForReflow, id);
@@ -15767,16 +15293,6 @@ const PageCanvas = react.forwardRef(
15767
15293
  renderOnAddRemove: fabricCanvas.renderOnAddRemove
15768
15294
  });
15769
15295
  }
15770
- if (debugGroupImageSideResize) {
15771
- logGroupImageResizeDebug("before-reselect", {
15772
- time: Math.round(performance.now()),
15773
- handle: activeSelectionResizeHandle,
15774
- wasGroupSel,
15775
- selection: summarizeFabricObjectForResizeDebug(activeObj),
15776
- members: membersToReselect.map((member) => summarizeFabricObjectForResizeDebug(member)),
15777
- renderOnAddRemove: fabricCanvas.renderOnAddRemove
15778
- });
15779
- }
15780
15296
  const prevRenderOnAddRemove = fabricCanvas.renderOnAddRemove;
15781
15297
  fabricCanvas.renderOnAddRemove = false;
15782
15298
  skipSelectionClearOnDiscardRef.current = true;
@@ -15791,10 +15307,9 @@ const PageCanvas = react.forwardRef(
15791
15307
  if (!ct) continue;
15792
15308
  ct.frameW = bake.width;
15793
15309
  ct.frameH = bake.height;
15794
- const bakeCenter = rotatedTopLeftToCenter(bake.left, bake.top, bake.width, bake.height, bake.angle);
15795
15310
  bake.obj.set({
15796
- left: bakeCenter.x,
15797
- top: bakeCenter.y,
15311
+ left: bake.left + bake.width / 2,
15312
+ top: bake.top + bake.height / 2,
15798
15313
  width: bake.width,
15799
15314
  height: bake.height,
15800
15315
  scaleX: 1,
@@ -15821,16 +15336,6 @@ const PageCanvas = react.forwardRef(
15821
15336
  renderOnAddRemove: fabricCanvas.renderOnAddRemove
15822
15337
  });
15823
15338
  }
15824
- if (debugGroupImageSideResize) {
15825
- logGroupImageResizeDebug("after-reselect", {
15826
- time: Math.round(performance.now()),
15827
- handle: activeSelectionResizeHandle,
15828
- wasGroupSel,
15829
- selection: summarizeFabricObjectForResizeDebug(newSel),
15830
- members: membersToReselect.map((member) => summarizeFabricObjectForResizeDebug(member)),
15831
- renderOnAddRemove: fabricCanvas.renderOnAddRemove
15832
- });
15833
- }
15834
15339
  } else if (membersToReselect.length === 1) {
15835
15340
  fabricCanvas.setActiveObject(membersToReselect[0]);
15836
15341
  }
@@ -15867,7 +15372,6 @@ const PageCanvas = react.forwardRef(
15867
15372
  const activeObj = fabricCanvas.getActiveObject();
15868
15373
  if (!(activeObj instanceof fabric__namespace.ActiveSelection)) return;
15869
15374
  if (skipActiveSelectionBakeOnClearRef.current) return;
15870
- if (activeObj.__pixldocsGroupSelection) return;
15871
15375
  const selectionMatrix = activeObj.calcTransformMatrix();
15872
15376
  for (const obj of deselected) {
15873
15377
  const objId = getObjectId(obj);
@@ -16337,7 +15841,7 @@ const PageCanvas = react.forwardRef(
16337
15841
  const nextHeight = Math.max(minVisiblePlaceholder, Number(resolvedSizeImg.height) || 50);
16338
15842
  const storePosImg = pageChildren ? (() => {
16339
15843
  const node = findNodeById(pageChildren, element.id);
16340
- return node && isElement(node) ? getElementFabricPlacement(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
15844
+ return node ? getAbsoluteBounds(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
16341
15845
  })() : { left: element.left ?? 0, top: element.top ?? 0 };
16342
15846
  const elementForPlaceholder = { ...element, width: nextWidth, height: nextHeight };
16343
15847
  const placeholder = isCropGroup2 ? createImagePlaceholderForGroup(elementForPlaceholder) : createImagePlaceholder(elementForPlaceholder);
@@ -16400,14 +15904,13 @@ const PageCanvas = react.forwardRef(
16400
15904
  }
16401
15905
  const cropPos = pageChildren ? (() => {
16402
15906
  const node = findNodeById(pageChildren, element.id);
16403
- return node && isElement(node) ? getElementFabricPlacement(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16404
- })() : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16405
- const cropCenter = rotatedTopLeftToCenter(cropPos.left, cropPos.top, ct.frameW ?? 0, ct.frameH ?? 0, cropPos.angle ?? element.angle ?? 0);
16406
- const cropCenterX = cropCenter.x;
16407
- const cropCenterY = cropCenter.y;
15907
+ return node ? getAbsoluteBounds(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
15908
+ })() : { left: element.left ?? 0, top: element.top ?? 0 };
15909
+ const cropCenterX = cropPos.left + (ct.frameW ?? 0) / 2;
15910
+ const cropCenterY = cropPos.top + (ct.frameH ?? 0) / 2;
16408
15911
  if (element.left !== void 0) existingObj.set({ left: cropCenterX });
16409
15912
  if (element.top !== void 0) existingObj.set({ top: cropCenterY });
16410
- existingObj.set({ angle: cropPos.angle ?? element.angle ?? 0 });
15913
+ if (element.angle !== void 0) existingObj.set({ angle: element.angle });
16411
15914
  existingObj.set({
16412
15915
  flipX: element.flipX ?? false,
16413
15916
  flipY: element.flipY ?? false
@@ -16530,8 +16033,8 @@ const PageCanvas = react.forwardRef(
16530
16033
  if (isPlaceholderGroup) {
16531
16034
  const storePosImg = pageChildren ? (() => {
16532
16035
  const node = findNodeById(pageChildren, element.id);
16533
- return node && isElement(node) ? getElementFabricPlacement(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16534
- })() : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16036
+ return node ? getAbsoluteBounds(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
16037
+ })() : { left: element.left ?? 0, top: element.top ?? 0 };
16535
16038
  const resolvedSizeImg = (pageChildren == null ? void 0 : pageChildren.length) ? getNodeBounds(element, pageChildren) : { width: typeof element.width === "number" ? element.width : 200, height: typeof element.height === "number" ? element.height : 50 };
16536
16039
  const hasExplicitSize = typeof element.width === "number" && Number.isFinite(element.width) && element.width > 0 && typeof element.height === "number" && Number.isFinite(element.height) && element.height > 0;
16537
16040
  const minVisiblePlaceholder = hasExplicitSize ? 1 : 20;
@@ -16545,7 +16048,7 @@ const PageCanvas = react.forwardRef(
16545
16048
  top: storePosImg.top + nextHeight / 2,
16546
16049
  originX: "center",
16547
16050
  originY: "center",
16548
- angle: storePosImg.angle ?? element.angle ?? 0,
16051
+ angle: element.angle ?? 0,
16549
16052
  opacity: isHidden ? 0 : element.opacity ?? 1,
16550
16053
  flipX: element.flipX ?? false,
16551
16054
  flipY: element.flipY ?? false,
@@ -16594,8 +16097,8 @@ const PageCanvas = react.forwardRef(
16594
16097
  const visibilityChanged = previousVisible !== currentVisible;
16595
16098
  const storePosForImg = pageChildren ? (() => {
16596
16099
  const node = findNodeById(pageChildren, element.id);
16597
- return node && isElement(node) ? getElementFabricPlacement(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16598
- })() : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16100
+ return node ? getAbsoluteBounds(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
16101
+ })() : { left: element.left ?? 0, top: element.top ?? 0 };
16599
16102
  const positionChanged = Math.abs((existingObj.left ?? 0) - storePosForImg.left) > 0.1 || Math.abs((existingObj.top ?? 0) - storePosForImg.top) > 0.1;
16600
16103
  if (visibilityChanged && !positionChanged || visibilityUpdateInProgressRef.current) {
16601
16104
  const isDynamicField = dynamicFieldIds.includes(element.id);
@@ -16637,7 +16140,7 @@ const PageCanvas = react.forwardRef(
16637
16140
  const fabricTop = existingObj.top ?? 0;
16638
16141
  const storePos = pageChildren ? (() => {
16639
16142
  const node = findNodeById(pageChildren, element.id);
16640
- return node && isElement(node) ? getElementFabricPlacement(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
16143
+ return node ? getAbsoluteBounds(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
16641
16144
  })() : { left: element.left ?? 0, top: element.top ?? 0 };
16642
16145
  const storeLeft = storePos.left;
16643
16146
  const storeTop = storePos.top;
@@ -16764,7 +16267,7 @@ const PageCanvas = react.forwardRef(
16764
16267
  setObjectData(placeholder, element.id);
16765
16268
  const absPosImg = pageTree.length > 0 ? (() => {
16766
16269
  const node = findNodeById(pageTree, element.id);
16767
- return node && isElement(node) ? getElementFabricPlacement(node, pageTree) : { left: element.left ?? 0, top: element.top ?? 0 };
16270
+ return node ? getAbsoluteBounds(node, pageTree) : { left: element.left ?? 0, top: element.top ?? 0 };
16768
16271
  })() : { left: element.left ?? 0, top: element.top ?? 0 };
16769
16272
  const placeholderWidth = Number((placeholder.width ?? 0) * (placeholder.scaleX ?? 1));
16770
16273
  const placeholderHeight = Number((placeholder.height ?? 0) * (placeholder.scaleY ?? 1));
@@ -16813,7 +16316,7 @@ const PageCanvas = react.forwardRef(
16813
16316
  if (obj) {
16814
16317
  const absPos = pageTree.length > 0 ? (() => {
16815
16318
  const node = findNodeById(pageTree, element.id);
16816
- return node && isElement(node) ? getElementFabricPlacement(node, pageTree) : { left: element.left ?? 0, top: element.top ?? 0 };
16319
+ return node ? getAbsoluteBounds(node, pageTree) : { left: element.left ?? 0, top: element.top ?? 0 };
16817
16320
  })() : { left: element.left ?? 0, top: element.top ?? 0 };
16818
16321
  obj.set({ left: absPos.left, top: absPos.top });
16819
16322
  obj.setCoords();
@@ -17203,7 +16706,9 @@ const PageCanvas = react.forwardRef(
17203
16706
  if (sameSelection && isFlatGroupSelection) {
17204
16707
  if (selectedGroupSelectionId && active instanceof fabric__namespace.ActiveSelection) {
17205
16708
  if (isPureSingleGroupSelection) {
17206
- applyLogicalGroupSelectionVisualState(active, selectedGroupSelectionId);
16709
+ active.__pixldocsGroupSelection = selectedGroupSelectionId;
16710
+ delete active.__pixldocsLogicalGroupIds;
16711
+ suppressGroupMemberBordersRef.current = active.getObjects();
17207
16712
  } else {
17208
16713
  delete active.__pixldocsGroupSelection;
17209
16714
  active.__pixldocsLogicalGroupIds = selectedGroupIds;
@@ -17243,7 +16748,8 @@ const PageCanvas = react.forwardRef(
17243
16748
  const selection = new fabric__namespace.ActiveSelection(toSelect, { canvas: fc });
17244
16749
  if (selectedGroupSelectionId) {
17245
16750
  if (isPureSingleGroupSelection) {
17246
- applyLogicalGroupSelectionVisualState(selection, selectedGroupSelectionId);
16751
+ selection.__pixldocsGroupSelection = selectedGroupSelectionId;
16752
+ suppressGroupMemberBordersRef.current = toSelect;
17247
16753
  } else {
17248
16754
  selection.__pixldocsLogicalGroupIds = selectedGroupIds;
17249
16755
  selection.hasBorders = true;
@@ -17301,8 +16807,8 @@ const PageCanvas = react.forwardRef(
17301
16807
  const currentPageTree = ((pageChildren == null ? void 0 : pageChildren.length) ? pageChildren : (_a2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
17302
16808
  const fabricPos = currentPageTree.length > 0 ? (() => {
17303
16809
  const node = findNodeById(currentPageTree, element.id);
17304
- return node && isElement(node) ? getElementFabricPlacement(node, currentPageTree) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
17305
- })() : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16810
+ return node ? getAbsoluteBounds(node, currentPageTree) : { left: element.left ?? 0, top: element.top ?? 0 };
16811
+ })() : { left: element.left ?? 0, top: element.top ?? 0 };
17306
16812
  const resolvedSize = currentPageTree.length > 0 ? getNodeBounds(element, currentPageTree) : { width: typeof element.width === "number" ? element.width : 200, height: typeof element.height === "number" ? element.height : 50 };
17307
16813
  const shouldPreserveSmallSize = typeof element.width === "number" && Number.isFinite(element.width) && element.width > 0 && typeof element.height === "number" && Number.isFinite(element.height) && element.height > 0;
17308
16814
  const minVisible = shouldPreserveSmallSize ? 1 : 20;
@@ -17337,9 +16843,8 @@ const PageCanvas = react.forwardRef(
17337
16843
  ct.shape = clipShape === "circle" ? "circle" : clipShape === "rounded" ? "roundRect" : "rect";
17338
16844
  ct.rx = rxRatio;
17339
16845
  obj.__maintainResolution = element.maintainResolution !== false;
17340
- const center = rotatedTopLeftToCenter(fabricPos.left, fabricPos.top, elementWidth, elementHeight, element.angle ?? 0);
17341
- const centerX = center.x;
17342
- const centerY = center.y;
16846
+ const centerX = fabricPos.left + elementWidth / 2;
16847
+ const centerY = fabricPos.top + elementHeight / 2;
17343
16848
  const cropSetProps = {
17344
16849
  width: elementWidth,
17345
16850
  height: elementHeight,
@@ -17579,8 +17084,7 @@ const PageCanvas = react.forwardRef(
17579
17084
  if (!skipPositionUpdate && (obj instanceof fabric__namespace.FabricImage && obj.originX === "center" || obj instanceof fabric__namespace.Group && obj.__cropGroup)) {
17580
17085
  const vW = rW * effectiveScaleX;
17581
17086
  const vH = rH * effectiveScaleY;
17582
- const center = rotatedTopLeftToCenter(fabricPos.left, fabricPos.top, vW, vH, element.angle ?? 0);
17583
- posIfNotSkipped = { left: center.x, top: center.y };
17087
+ posIfNotSkipped = { left: fabricPos.left + vW / 2, top: fabricPos.top + vH / 2 };
17584
17088
  }
17585
17089
  if (element.transformMatrix && element.transformMatrix.length === 6) {
17586
17090
  if (isTextbox) {
@@ -18371,14 +17875,14 @@ const PageCanvas = react.forwardRef(
18371
17875
  const pageTreeForCreate = ((pageChildren == null ? void 0 : pageChildren.length) ? pageChildren : (_f = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _f.children) ?? [];
18372
17876
  const createPos = pageTreeForCreate.length > 0 ? (() => {
18373
17877
  const node = findNodeById(pageTreeForCreate, element.id);
18374
- return node && isElement(node) ? getElementFabricPlacement(node, pageTreeForCreate, pageBoundsOptions) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
18375
- })() : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
17878
+ return node ? getAbsoluteBounds(node, pageTreeForCreate) : { left: element.left ?? 0, top: element.top ?? 0 };
17879
+ })() : { left: element.left ?? 0, top: element.top ?? 0 };
18376
17880
  img.set({
18377
17881
  left: createPos.left,
18378
17882
  top: createPos.top,
18379
17883
  scaleX: finalScaleX,
18380
17884
  scaleY: finalScaleY,
18381
- angle: createPos.angle ?? element.angle ?? 0,
17885
+ angle: element.angle ?? 0,
18382
17886
  skewX: element.skewX ?? 0,
18383
17887
  skewY: element.skewY ?? 0,
18384
17888
  flipX: element.flipX ?? false,
@@ -18465,8 +17969,8 @@ const PageCanvas = react.forwardRef(
18465
17969
  const pageTreeForCrop = ((pageChildren == null ? void 0 : pageChildren.length) ? pageChildren : (_n = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _n.children) ?? [];
18466
17970
  const createPosForCrop = pageTreeForCrop.length > 0 ? (() => {
18467
17971
  const node = findNodeById(pageTreeForCrop, element.id);
18468
- return node && isElement(node) ? getElementFabricPlacement(node, pageTreeForCrop, pageBoundsOptions) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
18469
- })() : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
17972
+ return node ? getAbsoluteBounds(node, pageTreeForCrop) : { left: element.left ?? 0, top: element.top ?? 0 };
17973
+ })() : { left: element.left ?? 0, top: element.top ?? 0 };
18470
17974
  const nodeForCreate = pageTreeForCrop.length ? findNodeById(pageTreeForCrop, element.id) : null;
18471
17975
  const createW = nodeForCreate && isElement(nodeForCreate) ? nodeForCreate.width : elementWidth;
18472
17976
  const createH = nodeForCreate && isElement(nodeForCreate) ? nodeForCreate.height : elementHeight;
@@ -18474,9 +17978,8 @@ const PageCanvas = react.forwardRef(
18474
17978
  const createSy = nodeForCreate && isElement(nodeForCreate) ? nodeForCreate.scaleY ?? 1 : element.scaleY ?? 1;
18475
17979
  const frameW = Math.max(1, Number(createW) || 200) * createSx;
18476
17980
  const frameH = Math.max(1, Number(createH) || 50) * createSy;
18477
- const createCenter = rotatedTopLeftToCenter(createPosForCrop.left, createPosForCrop.top, frameW, frameH, createPosForCrop.angle ?? element.angle ?? 0);
18478
- const createCenterX = createCenter.x;
18479
- const createCenterY = createCenter.y;
17981
+ const createCenterX = createPosForCrop.left + frameW / 2;
17982
+ const createCenterY = createPosForCrop.top + frameH / 2;
18480
17983
  const cropGroup = await createMaskedImageElement({
18481
17984
  image: img,
18482
17985
  frameW,
@@ -18489,7 +17992,7 @@ const PageCanvas = react.forwardRef(
18489
17992
  strokeWidth: 0,
18490
17993
  left: createCenterX,
18491
17994
  top: createCenterY,
18492
- angle: createPosForCrop.angle ?? element.angle ?? 0,
17995
+ angle: element.angle ?? 0,
18493
17996
  opacity: isHidden ? 0 : element.opacity ?? 1,
18494
17997
  selectable: allowSelection && !isHidden,
18495
17998
  evented: canBeEvented && !isHidden,
@@ -24879,9 +24382,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
24879
24382
  }
24880
24383
  return svgString;
24881
24384
  }
24882
- const resolvedPackageVersion = "0.5.353";
24385
+ const resolvedPackageVersion = "0.5.355";
24883
24386
  const PACKAGE_VERSION = resolvedPackageVersion;
24884
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.353";
24387
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.355";
24885
24388
  const roundParityValue = (value) => {
24886
24389
  if (typeof value !== "number") return value;
24887
24390
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -25695,7 +25198,7 @@ class PixldocsRenderer {
25695
25198
  await this.waitForCanvasScene(container, cloned, i);
25696
25199
  }
25697
25200
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
25698
- const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-DihZwtD7.cjs"));
25201
+ const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-BtRK4LgQ.cjs"));
25699
25202
  const prepared = preparePagesForExport(
25700
25203
  cloned.pages,
25701
25204
  canvasWidth,
@@ -28015,7 +27518,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
28015
27518
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
28016
27519
  sanitizeSvgTreeForPdf(svgToDraw);
28017
27520
  try {
28018
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-DihZwtD7.cjs"));
27521
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-BtRK4LgQ.cjs"));
28019
27522
  try {
28020
27523
  await logTextMeasurementDiagnostic(svgToDraw);
28021
27524
  } catch {
@@ -28412,4 +27915,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
28412
27915
  exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
28413
27916
  exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
28414
27917
  exports.warmTemplateFromForm = warmTemplateFromForm;
28415
- //# sourceMappingURL=index-UiuMKvLc.cjs.map
27918
+ //# sourceMappingURL=index-DWxht-v_.cjs.map