@pixldocs/canvas-renderer 0.5.354 → 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) => {
@@ -13312,36 +13224,9 @@ const PageCanvas = react.forwardRef(
13312
13224
  });
13313
13225
  };
13314
13226
  fabricCanvas.__updateDrilledGroupOutline = updateDrilledGroupOutline;
13315
- const isPointerOnSelectionControl = (selection, event) => {
13316
- var _a2;
13317
- try {
13318
- selection.setCoords();
13319
- const controls = selection.oCoords ?? ((_a2 = selection.calcOCoords) == null ? void 0 : _a2.call(selection));
13320
- const el = fabricCanvas.upperCanvasEl ?? fabricCanvas.lowerCanvasEl;
13321
- const rect = el == null ? void 0 : el.getBoundingClientRect();
13322
- if (!controls || !rect || !event) return false;
13323
- const x = Number(event.clientX) - rect.left;
13324
- const y = Number(event.clientY) - rect.top;
13325
- return Object.values(controls).some((control) => {
13326
- const pts = (control == null ? void 0 : control.touchCorner) ?? (control == null ? void 0 : control.corner);
13327
- const corners = pts ? Object.values(pts) : [];
13328
- if (!corners.length) return false;
13329
- const minX = Math.min(...corners.map((p) => p.x)) - 2;
13330
- const maxX = Math.max(...corners.map((p) => p.x)) + 2;
13331
- const minY = Math.min(...corners.map((p) => p.y)) - 2;
13332
- const maxY = Math.max(...corners.map((p) => p.y)) + 2;
13333
- return x >= minX && x <= maxX && y >= minY && y <= maxY;
13334
- });
13335
- } catch {
13336
- return false;
13337
- }
13338
- };
13339
13227
  fabricCanvas.on("mouse:down:before", (opt) => {
13340
13228
  var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
13341
13229
  const activeBeforeMouseDown = fabricCanvas.getActiveObject();
13342
- if (activeBeforeMouseDown instanceof fabric__namespace.ActiveSelection && activeBeforeMouseDown.__pixldocsGroupSelection) {
13343
- prepareGroupSelectionTransformStart(activeBeforeMouseDown);
13344
- }
13345
13230
  if (editLockRef.current) {
13346
13231
  const active = fabricCanvas.getActiveObject();
13347
13232
  if (active && (((_a2 = active._ct) == null ? void 0 : _a2.isCropGroup) || active.__cropGroup)) {
@@ -13359,8 +13244,7 @@ const PageCanvas = react.forwardRef(
13359
13244
  }
13360
13245
  let target = opt.target;
13361
13246
  let targetId = target ? getObjectId(target) : null;
13362
- const pointerOnActiveSelectionControl = activeBeforeMouseDown instanceof fabric__namespace.ActiveSelection ? isPointerOnSelectionControl(activeBeforeMouseDown, opt.e) : false;
13363
- if (target instanceof fabric__namespace.ActiveSelection && target.__pixldocsGroupSelection && target === fabricCanvas.getActiveObject() && !target.__corner && !pointerOnActiveSelectionControl) {
13247
+ if (target instanceof fabric__namespace.ActiveSelection && target.__pixldocsGroupSelection && target === fabricCanvas.getActiveObject()) {
13364
13248
  const child = pickChildInActiveSelectionAtPointer(target, opt.e);
13365
13249
  const childId = child ? getObjectId(child) : null;
13366
13250
  if (child && childId) {
@@ -13409,7 +13293,7 @@ const PageCanvas = react.forwardRef(
13409
13293
  let effectiveTargetId = targetId;
13410
13294
  const activeNowEarly = fabricCanvas.getActiveObject();
13411
13295
  const asGroupId = target instanceof fabric__namespace.ActiveSelection ? target.__pixldocsGroupSelection : void 0;
13412
- if (target instanceof fabric__namespace.ActiveSelection && asGroupId && target === activeNowEarly && !target.__corner && !pointerOnActiveSelectionControl) {
13296
+ if (target instanceof fabric__namespace.ActiveSelection && asGroupId && target === activeNowEarly) {
13413
13297
  const child = pickChildInActiveSelectionAtPointer(target, opt.e);
13414
13298
  const childId = child ? getObjectId(child) : null;
13415
13299
  if (child && childId) {
@@ -13442,7 +13326,6 @@ const PageCanvas = react.forwardRef(
13442
13326
  restoreGroupSelectionVisualState(selection, parent.id);
13443
13327
  fabricCanvas.setActiveObject(selection);
13444
13328
  selection.setCoords();
13445
- prepareGroupSelectionTransformStart(selection);
13446
13329
  fabricCanvas._target = selection;
13447
13330
  opt.target = selection;
13448
13331
  pendingGroupPromotionRef.current = { groupId: parent.id, selection };
@@ -13485,7 +13368,6 @@ const PageCanvas = react.forwardRef(
13485
13368
  restoreGroupSelectionVisualState(selection, parent.id);
13486
13369
  fabricCanvas.setActiveObject(selection);
13487
13370
  selection.setCoords();
13488
- prepareGroupSelectionTransformStart(selection);
13489
13371
  fabricCanvas._target = selection;
13490
13372
  opt.target = selection;
13491
13373
  pendingGroupPromotionRef.current = { groupId: parent.id, selection };
@@ -13754,29 +13636,34 @@ const PageCanvas = react.forwardRef(
13754
13636
  });
13755
13637
  const markSimpleTransform = (e) => {
13756
13638
  if (!isActiveRef.current) return;
13757
- prepareGroupSelectionTransformStart(e.target);
13758
13639
  markTransforming(e.target);
13759
13640
  };
13760
13641
  const getObjectFrameBoundsInSelection = (selection, obj, frameWidth, frameHeight) => {
13761
13642
  const w = Math.max(1, frameWidth ?? obj.width ?? 1);
13762
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;
13763
13648
  const matrix = fabric__namespace.util.multiplyTransformMatrices(
13764
13649
  selection.calcTransformMatrix(),
13765
13650
  obj.calcOwnMatrix()
13766
13651
  );
13767
- const decomposed = fabric__namespace.util.qrDecompose(matrix);
13768
- const scaledW = Math.max(1, w * Math.abs(decomposed.scaleX || 1));
13769
- const scaledH = Math.max(1, h * Math.abs(decomposed.scaleY || 1));
13770
- const angleRad = (decomposed.angle ?? 0) * Math.PI / 180;
13771
- const cos = Math.cos(angleRad);
13772
- const sin = Math.sin(angleRad);
13773
- const left = decomposed.translateX - scaledW / 2 * cos + scaledH / 2 * sin;
13774
- 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);
13775
13662
  return {
13776
13663
  left,
13777
13664
  top,
13778
- width: scaledW,
13779
- height: scaledH
13665
+ width: Math.max(1, Math.max(...xs) - left),
13666
+ height: Math.max(1, Math.max(...ys) - top)
13780
13667
  };
13781
13668
  };
13782
13669
  fabricCanvas.on("object:added", (e) => {
@@ -13791,30 +13678,10 @@ const PageCanvas = react.forwardRef(
13791
13678
  fabricCanvas.on("selection:cleared", () => {
13792
13679
  });
13793
13680
  fabricCanvas.on("object:scaling", (e) => {
13794
- var _a2, _b2, _c, _d, _e, _f, _g, _h;
13681
+ var _a2, _b2, _c, _d, _e, _f;
13795
13682
  if (!isActiveRef.current) return;
13796
13683
  const t = e.target;
13797
13684
  if (t) lastResizeScaleTargetRef.current = t;
13798
- try {
13799
- const transformDbg = e.transform;
13800
- const cornerDbg = (transformDbg == null ? void 0 : transformDbg.corner) || "";
13801
- const children = t instanceof fabric__namespace.Group || t instanceof fabric__namespace.ActiveSelection ? t.getObjects() : [];
13802
- logGroupImageResizeDebug("scaling-entry", {
13803
- time: Math.round(performance.now()),
13804
- corner: cornerDbg,
13805
- targetType: t == null ? void 0 : t.type,
13806
- targetCtor: (_a2 = t == null ? void 0 : t.constructor) == null ? void 0 : _a2.name,
13807
- isActiveSelection: t instanceof fabric__namespace.ActiveSelection,
13808
- isGroup: t instanceof fabric__namespace.Group,
13809
- isCropGroup: !!(t && (t.__cropGroup || ((_b2 = t._ct) == null ? void 0 : _b2.isCropGroup))),
13810
- childCount: children.length,
13811
- childTypes: children.map((c) => c == null ? void 0 : c.type),
13812
- hasImageChild: children.some((c) => isGroupResizeImageLikeObject(c)),
13813
- target: t ? summarizeFabricObjectForResizeDebug(t) : null
13814
- });
13815
- } catch (err) {
13816
- console.warn("[Pixldocs][group-image-side-resize] scaling-entry log failed", err);
13817
- }
13818
13685
  prepareGroupSelectionTransformStart(t);
13819
13686
  markTransforming(t);
13820
13687
  didTransformRef.current = true;
@@ -13978,7 +13845,7 @@ const PageCanvas = react.forwardRef(
13978
13845
  time: Math.round(performance.now()),
13979
13846
  corner,
13980
13847
  groupSelectionId: obj.__pixldocsGroupSelection,
13981
- currentTransformAction: (_c = fabricCanvas._currentTransform) == null ? void 0 : _c.action,
13848
+ currentTransformAction: (_a2 = fabricCanvas._currentTransform) == null ? void 0 : _a2.action,
13982
13849
  selection: summarizeFabricObjectForResizeDebug(obj),
13983
13850
  textChildren: obj.getObjects().filter((child) => child instanceof fabric__namespace.Textbox).map((child) => summarizeFabricObjectForResizeDebug(child))
13984
13851
  };
@@ -13988,43 +13855,19 @@ const PageCanvas = react.forwardRef(
13988
13855
  const isXSide = corner === "ml" || corner === "mr";
13989
13856
  const sAxis = isXSide ? Math.abs(obj.scaleX ?? 1) : Math.abs(obj.scaleY ?? 1);
13990
13857
  if (sAxis > 1e-3) {
13991
- const hasRotatedChild = obj.getObjects().some((c) => {
13992
- const a = ((c.angle ?? 0) % 180 + 180) % 180;
13993
- return !(a < 0.5 || a > 179.5);
13994
- });
13995
- const selectionAngle = ((obj.angle ?? 0) % 180 + 180) % 180;
13996
- const isSelectionRotated = !(selectionAngle < 0.5 || selectionAngle > 179.5);
13997
- const shouldPinNonTextChildren = hasRotatedChild || isSelectionRotated;
13998
- const shouldDebugGroupImageResize = obj.getObjects().some((child) => isGroupResizeImageLikeObject(child));
13999
- if (shouldDebugGroupImageResize) {
14000
- logGroupImageResizeDebug("live-start", {
14001
- time: Math.round(performance.now()),
14002
- corner,
14003
- isXSide,
14004
- sAxis,
14005
- hasRotatedChild,
14006
- isSelectionRotated,
14007
- shouldPinNonTextChildren,
14008
- groupSelectionId: obj.__pixldocsGroupSelection,
14009
- selection: summarizeFabricObjectForResizeDebug(obj),
14010
- children: obj.getObjects().map((child) => summarizeFabricObjectForResizeDebug(child))
14011
- });
14012
- }
14013
- if ((isXSide || shouldPinNonTextChildren) && ((_d = groupShiftReflowSnapshotRef.current) == null ? void 0 : _d.selection) !== obj) {
13858
+ if (isXSide && ((_b2 = groupShiftReflowSnapshotRef.current) == null ? void 0 : _b2.selection) !== obj) {
14014
13859
  groupShiftReflowSnapshotRef.current = null;
14015
13860
  const logicalGroupId = obj.__pixldocsGroupSelection;
14016
13861
  if (logicalGroupId) {
14017
13862
  try {
14018
13863
  const state = useEditorStore.getState();
14019
- 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) ?? [];
14020
13865
  const groupNode = findNodeById(pageChildren2, logicalGroupId);
14021
13866
  if (groupNode && isGroup(groupNode) && !isStackLayoutMode(groupNode.layoutMode)) {
14022
13867
  const entries = obj.getObjects().map((c) => ({
14023
13868
  obj: c,
14024
13869
  id: getObjectId(c) ?? "",
14025
- left0: c.left ?? 0,
14026
13870
  top0: c.top ?? 0,
14027
- width0: (c.width ?? 0) * Math.abs(c.scaleX ?? 1),
14028
13871
  height0: (c.height ?? 0) * Math.abs(c.scaleY ?? 1)
14029
13872
  })).filter((e2) => e2.id).sort((a, b) => a.top0 - b.top0);
14030
13873
  if (entries.length > 1) {
@@ -14047,150 +13890,78 @@ const PageCanvas = react.forwardRef(
14047
13890
  const asTop0 = obj.top ?? 0;
14048
13891
  const asRect0 = obj.getBoundingRect();
14049
13892
  let didReflowTextChild = false;
14050
- if (hasRotatedChild) {
14051
- if (isXSide) {
14052
- obj._set("width", asW0 * sAxis);
14053
- obj._set("scaleX", 1);
14054
- } else {
14055
- obj._set("height", asH0 * sAxis);
14056
- obj._set("scaleY", 1);
14057
- }
14058
- }
14059
- const childCounterScale = hasRotatedChild ? 1 : 1 / sAxis;
14060
- let restoredNonTextAfterLayout = false;
14061
- const restoreNonTextChildren = (pins) => {
14062
- var _a3, _b3;
14063
- if (!shouldPinNonTextChildren || ((_a3 = groupShiftReflowSnapshotRef.current) == null ? void 0 : _a3.selection) !== obj) return;
14064
- for (const entry of groupShiftReflowSnapshotRef.current.children) {
14065
- const child = entry.obj;
14066
- if (child instanceof fabric__namespace.Textbox) continue;
14067
- if (child instanceof fabric__namespace.FabricImage || child instanceof fabric__namespace.Group && (child.__cropGroup || ((_b3 = child._ct) == null ? void 0 : _b3.isCropGroup))) {
14068
- const pin = pins == null ? void 0 : pins.get(child);
14069
- let targetLeft = hasRotatedChild && isXSide ? entry.left0 * sAxis : entry.left0;
14070
- let targetTop = hasRotatedChild && !isXSide ? entry.top0 * sAxis : entry.top0;
14071
- if (pin == null ? void 0 : pin.worldCenter) {
14072
- try {
14073
- const invSelectionMatrix = fabric__namespace.util.invertTransform(obj.calcTransformMatrix());
14074
- const localCenter = fabric__namespace.util.transformPoint(pin.worldCenter, invSelectionMatrix);
14075
- targetLeft = localCenter.x;
14076
- targetTop = localCenter.y;
14077
- } catch {
14078
- targetLeft = pin.left ?? targetLeft;
14079
- targetTop = pin.top ?? targetTop;
14080
- }
14081
- } else {
14082
- targetLeft = (pin == null ? void 0 : pin.left) ?? targetLeft;
14083
- targetTop = (pin == null ? void 0 : pin.top) ?? targetTop;
14084
- }
14085
- const beforeRestore = shouldDebugGroupImageResize ? summarizeFabricObjectForResizeDebug(child) : null;
14086
- if (Math.abs((child.left ?? 0) - targetLeft) > 0.01) child._set("left", targetLeft);
14087
- if (Math.abs((child.top ?? 0) - targetTop) > 0.01) child._set("top", targetTop);
14088
- if (isXSide) child._set("scaleX", childCounterScale);
14089
- else child._set("scaleY", childCounterScale);
14090
- child.setCoords();
14091
- child.dirty = true;
14092
- if (shouldDebugGroupImageResize) {
14093
- logGroupImageResizeDebug("restore-non-text", {
14094
- time: Math.round(performance.now()),
14095
- corner,
14096
- childId: getObjectId(child),
14097
- targetLeft,
14098
- targetTop,
14099
- pin,
14100
- before: beforeRestore,
14101
- after: summarizeFabricObjectForResizeDebug(child)
14102
- });
14103
- }
14104
- }
14105
- }
14106
- };
14107
- const projectRotatedTextPosition = (child) => {
14108
- var _a3;
14109
- if (!hasRotatedChild || ((_a3 = groupShiftReflowSnapshotRef.current) == null ? void 0 : _a3.selection) !== obj) return;
14110
- const entry = groupShiftReflowSnapshotRef.current.children.find((candidate) => candidate.obj === child);
14111
- if (!entry) return;
14112
- if (isXSide) child._set("left", entry.left0 * sAxis);
14113
- else child._set("top", entry.top0 * sAxis);
14114
- };
14115
13893
  for (const child of obj.getObjects()) {
14116
- if (child instanceof fabric__namespace.Group && (child.__cropGroup || ((_f = child._ct) == null ? void 0 : _f.isCropGroup))) {
14117
- const beforeImageChildResize = shouldDebugGroupImageResize ? summarizeFabricObjectForResizeDebug(child) : null;
13894
+ if (child instanceof fabric__namespace.Group && (child.__cropGroup || ((_d = child._ct) == null ? void 0 : _d.isCropGroup))) {
14118
13895
  const ct = child.__cropData;
14119
- if (ct) {
13896
+ if (!ct) continue;
13897
+ if (isXSide) {
14120
13898
  if (child.__asLiveOrigW == null) {
14121
- child.__asLiveOrigW = ct.frameW ?? child.width ?? 1;
13899
+ const baseW = child.width ?? ct.frameW ?? 0;
13900
+ child.__asLiveOrigW = baseW * (child.scaleX ?? 1);
14122
13901
  }
14123
- if (child.__asLiveOrigH == null) {
14124
- child.__asLiveOrigH = ct.frameH ?? child.height ?? 1;
14125
- }
14126
- if (isXSide) {
14127
- 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) {
14128
13905
  ct.frameW = newW;
14129
13906
  child._set("width", newW);
14130
- } else {
14131
- 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) {
14132
13923
  ct.frameH = newH;
14133
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;
14134
13932
  }
14135
- try {
14136
- updateCoverLayout(child);
14137
- } catch {
14138
- }
14139
- }
14140
- if (isXSide) child._set("scaleX", childCounterScale);
14141
- else child._set("scaleY", childCounterScale);
14142
- child.setCoords();
14143
- child.dirty = true;
14144
- if (shouldDebugGroupImageResize) {
14145
- logGroupImageResizeDebug("live-crop-child-resized", {
14146
- time: Math.round(performance.now()),
14147
- corner,
14148
- sAxis,
14149
- childCounterScale,
14150
- before: beforeImageChildResize,
14151
- after: summarizeFabricObjectForResizeDebug(child),
14152
- cropData: ct ? { frameW: ct.frameW, frameH: ct.frameH } : null
14153
- });
14154
13933
  }
14155
- didReflowTextChild = true;
14156
13934
  continue;
14157
13935
  }
14158
13936
  if (child instanceof fabric__namespace.FabricImage && !child.__cropGroup && !child.smartElementType) {
14159
- const beforeImageChildResize = shouldDebugGroupImageResize ? summarizeFabricObjectForResizeDebug(child) : null;
14160
13937
  if (isXSide) {
14161
13938
  if (child.__asLiveOrigW == null) {
14162
- 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;
14163
13948
  }
14164
- const newW = Math.max(1, Number(child.__asLiveOrigW) * sAxis);
14165
- child._set("width", newW);
14166
13949
  } else {
14167
13950
  if (child.__asLiveOrigH == null) {
14168
- 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;
14169
13960
  }
14170
- const newH = Math.max(1, Number(child.__asLiveOrigH) * sAxis);
14171
- child._set("height", newH);
14172
- }
14173
- if (isXSide) child._set("scaleX", childCounterScale);
14174
- else child._set("scaleY", childCounterScale);
14175
- child.setCoords();
14176
- child.dirty = true;
14177
- if (shouldDebugGroupImageResize) {
14178
- logGroupImageResizeDebug("live-image-child-resized", {
14179
- time: Math.round(performance.now()),
14180
- corner,
14181
- sAxis,
14182
- childCounterScale,
14183
- liveOrigW: child.__asLiveOrigW,
14184
- liveOrigH: child.__asLiveOrigH,
14185
- before: beforeImageChildResize,
14186
- after: summarizeFabricObjectForResizeDebug(child)
14187
- });
14188
13961
  }
14189
- didReflowTextChild = true;
14190
13962
  continue;
14191
13963
  }
14192
13964
  if (!(child instanceof fabric__namespace.Textbox)) continue;
14193
- projectRotatedTextPosition(child);
14194
13965
  if (isXSide) {
14195
13966
  if (child.__asLiveOrigW == null) {
14196
13967
  child.__asLiveOrigW = (child.width ?? 0) * (child.scaleX ?? 1);
@@ -14199,7 +13970,7 @@ const PageCanvas = react.forwardRef(
14199
13970
  const newW = Math.max(20, origW * sAxis);
14200
13971
  if (Math.abs((child.width ?? 0) - newW) > 0.5) {
14201
13972
  child._set("width", newW);
14202
- child._set("scaleX", childCounterScale);
13973
+ child._set("scaleX", 1 / sAxis);
14203
13974
  try {
14204
13975
  child.initDimensions();
14205
13976
  } catch {
@@ -14212,14 +13983,10 @@ const PageCanvas = react.forwardRef(
14212
13983
  if (child.__asLiveOrigH == null) {
14213
13984
  child.__asLiveOrigH = (child.height ?? 0) * (child.scaleY ?? 1);
14214
13985
  }
14215
- if (child.__asLiveOrigMinH == null) {
14216
- const m = Number(child.minBoxHeight);
14217
- if (Number.isFinite(m) && m > 0) child.__asLiveOrigMinH = m;
14218
- }
14219
13986
  const origH = child.__asLiveOrigH;
14220
13987
  const newH = Math.max(20, origH * sAxis);
14221
13988
  child.minBoxHeight = newH;
14222
- child._set("scaleY", childCounterScale);
13989
+ child._set("scaleY", 1 / sAxis);
14223
13990
  try {
14224
13991
  child.initDimensions();
14225
13992
  } catch {
@@ -14229,7 +13996,7 @@ const PageCanvas = react.forwardRef(
14229
13996
  didReflowTextChild = true;
14230
13997
  }
14231
13998
  }
14232
- if (isXSide && !shouldPinNonTextChildren && ((_g = groupShiftReflowSnapshotRef.current) == null ? void 0 : _g.selection) === obj) {
13999
+ if (isXSide && ((_e = groupShiftReflowSnapshotRef.current) == null ? void 0 : _e.selection) === obj) {
14233
14000
  const snap = groupShiftReflowSnapshotRef.current;
14234
14001
  const anchorEntry = snap.children[0];
14235
14002
  const anchorTopLive = anchorEntry.obj.top ?? 0;
@@ -14262,26 +14029,10 @@ const PageCanvas = react.forwardRef(
14262
14029
  if (cornersBefore) {
14263
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 };
14264
14031
  }
14265
- const nonTextPinsBeforeLayout = shouldPinNonTextChildren ? new Map(obj.getObjects().map((child) => [child, {
14266
- left: child.left ?? 0,
14267
- top: child.top ?? 0,
14268
- worldCenter: child instanceof fabric__namespace.Textbox ? void 0 : child.getCenterPoint()
14269
- }])) : void 0;
14270
14032
  try {
14271
14033
  obj.triggerLayout();
14272
14034
  } catch {
14273
14035
  }
14274
- restoreNonTextChildren(nonTextPinsBeforeLayout);
14275
- restoredNonTextAfterLayout = !!nonTextPinsBeforeLayout;
14276
- if (shouldDebugGroupImageResize) {
14277
- logGroupImageResizeDebug("after-trigger-layout", {
14278
- time: Math.round(performance.now()),
14279
- corner,
14280
- selection: summarizeFabricObjectForResizeDebug(obj),
14281
- nonTextPinsBeforeLayout,
14282
- children: obj.getObjects().map((child) => summarizeFabricObjectForResizeDebug(child))
14283
- });
14284
- }
14285
14036
  obj._set("width", asW0);
14286
14037
  obj._set("scaleX", asSx0);
14287
14038
  obj._set("scaleY", asSy0);
@@ -14307,19 +14058,9 @@ const PageCanvas = react.forwardRef(
14307
14058
  obj._set("left", asLeft0);
14308
14059
  obj._set("top", asTop0);
14309
14060
  }
14310
- if (!restoredNonTextAfterLayout) restoreNonTextChildren();
14311
14061
  obj._set("width", asW0);
14312
14062
  obj._set("scaleX", asSx0);
14313
14063
  obj._set("scaleY", asSy0);
14314
- if (hasRotatedChild) {
14315
- if (isXSide) {
14316
- obj._set("width", asW0 * sAxis);
14317
- obj._set("scaleX", 1);
14318
- } else {
14319
- obj._set("height", asH0 * sAxis);
14320
- obj._set("scaleY", 1);
14321
- }
14322
- }
14323
14064
  obj.setCoords();
14324
14065
  obj.dirty = true;
14325
14066
  }
@@ -14411,7 +14152,7 @@ const PageCanvas = react.forwardRef(
14411
14152
  setGuides(gridGuidesForScale.length ? [...scaleGuides, ...gridGuidesForScale] : scaleGuides);
14412
14153
  if (drilledGroupIdRef.current) {
14413
14154
  try {
14414
- (_h = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _h.call(fabricCanvas);
14155
+ (_f = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _f.call(fabricCanvas);
14415
14156
  } catch {
14416
14157
  }
14417
14158
  }
@@ -14502,37 +14243,9 @@ const PageCanvas = react.forwardRef(
14502
14243
  }
14503
14244
  });
14504
14245
  fabricCanvas.on("object:rotating", (e) => {
14505
- var _a2, _b2;
14506
- prepareGroupSelectionTransformStart(e.target);
14507
14246
  markSimpleTransform(e);
14508
14247
  didTransformRef.current = true;
14509
14248
  const tr = e.target;
14510
- try {
14511
- const children = tr instanceof fabric__namespace.Group || tr instanceof fabric__namespace.ActiveSelection ? tr.getObjects() : [];
14512
- logGroupImageResizeDebug("rotating-entry", {
14513
- time: Math.round(performance.now()),
14514
- angle: tr == null ? void 0 : tr.angle,
14515
- targetType: tr == null ? void 0 : tr.type,
14516
- targetCtor: (_a2 = tr == null ? void 0 : tr.constructor) == null ? void 0 : _a2.name,
14517
- isActiveSelection: tr instanceof fabric__namespace.ActiveSelection,
14518
- isGroup: tr instanceof fabric__namespace.Group,
14519
- isCropGroup: !!(tr && (tr.__cropGroup || ((_b2 = tr._ct) == null ? void 0 : _b2.isCropGroup))),
14520
- childCount: children.length,
14521
- childTypes: children.map((c) => c == null ? void 0 : c.type),
14522
- hasImageChild: children.some((c) => isGroupResizeImageLikeObject(c)),
14523
- target: tr ? summarizeFabricObjectForResizeDebug(tr) : null,
14524
- children: children.map((c) => {
14525
- var _a3;
14526
- return {
14527
- type: c == null ? void 0 : c.type,
14528
- ctor: (_a3 = c == null ? void 0 : c.constructor) == null ? void 0 : _a3.name,
14529
- summary: summarizeFabricObjectForResizeDebug(c)
14530
- };
14531
- })
14532
- });
14533
- } catch (err) {
14534
- console.warn("[Pixldocs][group-image-side-resize] rotating-entry log failed", err);
14535
- }
14536
14249
  try {
14537
14250
  const getCursor = fabricCanvas.__pixldocsGetRotateCursor;
14538
14251
  const upper = fabricCanvas.upperCanvasEl;
@@ -14575,7 +14288,7 @@ const PageCanvas = react.forwardRef(
14575
14288
  setDrilledGroupBounds(null);
14576
14289
  drilledGroupIdRef.current = null;
14577
14290
  if (activeDuringMove instanceof fabric__namespace.ActiveSelection && groupIdToKeep) {
14578
- preserveLogicalGroupTagDuringMove(activeDuringMove, groupIdToKeep);
14291
+ restoreGroupSelectionVisualState(activeDuringMove, groupIdToKeep);
14579
14292
  }
14580
14293
  }
14581
14294
  if (e.target) e.target.__pixldocsDragMoved = true;
@@ -14628,7 +14341,7 @@ const PageCanvas = react.forwardRef(
14628
14341
  });
14629
14342
  let cropGroupSaveTimer = null;
14630
14343
  fabricCanvas.on("object:modified", (e) => {
14631
- var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k;
14344
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i;
14632
14345
  try {
14633
14346
  dragStarted = false;
14634
14347
  setGuides([]);
@@ -14637,43 +14350,18 @@ const PageCanvas = react.forwardRef(
14637
14350
  groupResizeActiveSnapRef.current = null;
14638
14351
  onDragEnd == null ? void 0 : onDragEnd();
14639
14352
  try {
14640
- const mt = e.target;
14641
- const children = mt instanceof fabric__namespace.Group || mt instanceof fabric__namespace.ActiveSelection ? mt.getObjects() : [];
14642
- logGroupImageResizeDebug("modified-entry", {
14643
- time: Math.round(performance.now()),
14644
- didTransform: didTransformRef.current,
14645
- targetType: mt == null ? void 0 : mt.type,
14646
- targetCtor: (_a2 = mt == null ? void 0 : mt.constructor) == null ? void 0 : _a2.name,
14647
- isActiveSelection: mt instanceof fabric__namespace.ActiveSelection,
14648
- isGroup: mt instanceof fabric__namespace.Group,
14649
- angle: mt == null ? void 0 : mt.angle,
14650
- childCount: children.length,
14651
- childTypes: children.map((c) => c == null ? void 0 : c.type),
14652
- hasImageChild: children.some((c) => isGroupResizeImageLikeObject(c)),
14653
- target: mt ? summarizeFabricObjectForResizeDebug(mt) : null,
14654
- children: children.map((c) => {
14655
- var _a3;
14656
- return {
14657
- type: c == null ? void 0 : c.type,
14658
- ctor: (_a3 = c == null ? void 0 : c.constructor) == null ? void 0 : _a3.name,
14659
- summary: summarizeFabricObjectForResizeDebug(c)
14660
- };
14661
- })
14662
- });
14663
- } catch (err) {
14664
- console.warn("[Pixldocs][group-image-side-resize] modified-entry log failed", err);
14665
- }
14666
- const modifiedTarget = e.target;
14667
- if (modifiedTarget instanceof fabric__namespace.ActiveSelection && modifiedTarget.getObjects().length === 0) {
14668
- didTransformRef.current = false;
14669
- groupSelectionTransformStartRef.current = null;
14670
- activeSelectionMoveStartRef.current = null;
14671
- activeSelectionResizeHandleRef.current = null;
14672
- unlockEditsSoon();
14673
- 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 {
14674
14361
  }
14675
14362
  groupShiftReflowSnapshotRef.current = null;
14676
14363
  lockEdits();
14364
+ const modifiedTarget = e.target;
14677
14365
  const modifiedTargetId = modifiedTarget ? getObjectId(modifiedTarget) : null;
14678
14366
  const modifiedTargetElement = modifiedTargetId ? elementsRef.current.find((el) => el.id === modifiedTargetId) : null;
14679
14367
  if (modifiedTarget && (modifiedTargetElement == null ? void 0 : modifiedTargetElement.type) === "shape") {
@@ -14698,7 +14386,7 @@ const PageCanvas = react.forwardRef(
14698
14386
  const active = fabricCanvas.getActiveObject();
14699
14387
  const activeId = active ? getObjectId(active) : null;
14700
14388
  if (active && activeId && activeId !== "__background__" && !(active instanceof fabric__namespace.Group)) {
14701
- 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) ?? [];
14702
14390
  const parentGroup = findParentGroup(pageChildrenForParent, activeId);
14703
14391
  if (parentGroup && isGroup(parentGroup) && parentGroup.backgroundColor) {
14704
14392
  let fabricSectionGroup = active.group && active.group instanceof fabric__namespace.Group ? active.group : null;
@@ -14780,7 +14468,7 @@ const PageCanvas = react.forwardRef(
14780
14468
  useEditorStore.getState().reflowStackGroupInPage(pageId, groupId);
14781
14469
  }
14782
14470
  const stateAfter = useEditorStore.getState();
14783
- 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) ?? [];
14784
14472
  const groupNodeAfter = findNodeById(pageAfter, groupId);
14785
14473
  if (groupNodeAfter) {
14786
14474
  const abs = getAbsoluteBounds(groupNodeAfter, pageAfter);
@@ -14816,9 +14504,8 @@ const PageCanvas = react.forwardRef(
14816
14504
  const stateCrop = useEditorStore.getState();
14817
14505
  const pageCrop = stateCrop.canvas.pages.find((p) => p.id === pageId);
14818
14506
  const pageChildrenCrop = (pageCrop == null ? void 0 : pageCrop.children) ?? [];
14819
- const angleRad = (active.angle ?? 0) * Math.PI / 180;
14820
- const absLeft = (active.left ?? 0) - ct.frameW / 2 * Math.cos(angleRad) + ct.frameH / 2 * Math.sin(angleRad);
14821
- 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;
14822
14509
  const storePosCrop = absoluteToStorePosition(absLeft, absTop, objId, pageChildrenCrop);
14823
14510
  updateElement2(objId, {
14824
14511
  width: ct.frameW,
@@ -14843,7 +14530,7 @@ const PageCanvas = react.forwardRef(
14843
14530
  }
14844
14531
  if (active && active instanceof fabric__namespace.Group && active.__docuforgeSectionGroup && getObjectId(active)) {
14845
14532
  const groupId = getObjectId(active);
14846
- 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) ?? [];
14847
14534
  const modifiedTarget2 = e == null ? void 0 : e.target;
14848
14535
  const resizeScaleTarget = lastResizeScaleTargetRef.current;
14849
14536
  lastResizeScaleTargetRef.current = null;
@@ -14874,7 +14561,7 @@ const PageCanvas = react.forwardRef(
14874
14561
  const node = findNodeById(pageChildrenSec, groupId);
14875
14562
  if (isChildModified && node && !groupMoved) {
14876
14563
  const stateAfter = useEditorStore.getState();
14877
- 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) ?? [];
14878
14565
  const groupNodeAfter = findNodeById(pageAfter, groupId);
14879
14566
  if (groupNodeAfter) {
14880
14567
  const abs = getAbsoluteBounds(groupNodeAfter, pageAfter);
@@ -14890,7 +14577,7 @@ const PageCanvas = react.forwardRef(
14890
14577
  }
14891
14578
  if (active && active instanceof fabric__namespace.Group && !(active instanceof fabric__namespace.ActiveSelection) && getObjectId(active)) {
14892
14579
  const groupId = getObjectId(active);
14893
- 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) ?? [];
14894
14581
  const w = (active.width ?? 0) * (active.scaleX ?? 1);
14895
14582
  const h = (active.height ?? 0) * (active.scaleY ?? 1);
14896
14583
  const centerX = active.left ?? 0;
@@ -14912,7 +14599,7 @@ const PageCanvas = react.forwardRef(
14912
14599
  }
14913
14600
  const activeObj = fabricCanvas.getActiveObject();
14914
14601
  let activeObjects = fabricCanvas.getActiveObjects();
14915
- 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;
14916
14603
  const activeSelectionDelta = activeObj instanceof fabric__namespace.ActiveSelection && activeSelectionMoveStart ? (() => {
14917
14604
  const rect = activeObj.getBoundingRect();
14918
14605
  return {
@@ -14929,18 +14616,6 @@ const PageCanvas = react.forwardRef(
14929
14616
  const isActiveSelection = activeObj instanceof fabric__namespace.ActiveSelection || activeObjects.length > 1;
14930
14617
  const activeSelectionResizeHandle = isActiveSelection ? activeSelectionResizeHandleRef.current : null;
14931
14618
  const debugGroupTextCornerResize = activeObj instanceof fabric__namespace.ActiveSelection && isCornerResizeHandle(activeSelectionResizeHandle) && activeObjects.some((candidate) => candidate instanceof fabric__namespace.Textbox);
14932
- const debugGroupImageSideResize = activeObj instanceof fabric__namespace.ActiveSelection && (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb") && activeObjects.some((candidate) => isGroupResizeImageLikeObject(candidate));
14933
- if (debugGroupImageSideResize) {
14934
- logGroupImageResizeDebug("modified-start", {
14935
- time: Math.round(performance.now()),
14936
- handle: activeSelectionResizeHandle,
14937
- target: summarizeFabricObjectForResizeDebug(modifiedTarget),
14938
- selection: summarizeFabricObjectForResizeDebug(activeObj),
14939
- activeObjectIds: activeObjects.map((candidate) => getObjectId(candidate)),
14940
- selectedStoreIds: useEditorStore.getState().canvas.selectedIds,
14941
- members: activeObjects.map((candidate) => summarizeFabricObjectForResizeDebug(candidate))
14942
- });
14943
- }
14944
14619
  if (debugGroupTextCornerResize) {
14945
14620
  logGroupTextResizeDebug("modified-start", {
14946
14621
  time: Math.round(performance.now()),
@@ -14973,14 +14648,7 @@ const PageCanvas = react.forwardRef(
14973
14648
  const node = findNodeById(pageChildren2, id);
14974
14649
  return !!(node && isGroup(node));
14975
14650
  });
14976
- const activeSelectionHadTransform = activeObj instanceof fabric__namespace.ActiveSelection && (Math.abs((activeObj.scaleX ?? 1) - 1) > 0.01 || Math.abs((activeObj.scaleY ?? 1) - 1) > 0.01 || (() => {
14977
- var _a3;
14978
- const normAngle = (angle) => (angle % 360 + 360) % 360;
14979
- const startAngle = ((_a3 = groupSelectionTransformStartRef.current) == null ? void 0 : _a3.selection) === activeObj ? groupSelectionTransformStartRef.current.selectionAngle : 0;
14980
- const currentAngle = normAngle(activeObj.angle ?? 0);
14981
- const diff = Math.abs(currentAngle - normAngle(startAngle));
14982
- return Math.min(diff, 360 - diff) > 1;
14983
- })());
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);
14984
14652
  if (!anyCropGroup && activeSelectionDelta && !activeSelectionHadTransform && selectedLogicalGroupIds.length > 0) {
14985
14653
  const selectedStoreIds = useEditorStore.getState().canvas.selectedIds ?? [];
14986
14654
  const groupMemberIds = /* @__PURE__ */ new Set();
@@ -15021,13 +14689,7 @@ const PageCanvas = react.forwardRef(
15021
14689
  return;
15022
14690
  }
15023
14691
  }
15024
- const isActiveSelectionSideResize = isActiveSelection && (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb");
15025
- const normalizeAngle = (angle) => (angle % 360 + 360) % 360;
15026
- const shortestAngleDelta = (a, b) => {
15027
- const diff = Math.abs(normalizeAngle(a) - normalizeAngle(b));
15028
- return Math.min(diff, 360 - diff);
15029
- };
15030
- if (selectedElementIds.length > 0) {
14692
+ if (selectedElementIds.length > 0 && !anyCropGroup) {
15031
14693
  const firstObj = activeObjects[0];
15032
14694
  const firstId = getObjectId(firstObj);
15033
14695
  const parentGroups = selectedElementIds.map((id) => findParentGroup(pageChildren2, id)).filter((g) => g !== null);
@@ -15050,9 +14712,9 @@ const PageCanvas = react.forwardRef(
15050
14712
  let movedGroupLeft = groupAbs.left;
15051
14713
  let movedGroupTop = groupAbs.top;
15052
14714
  if (activeObj instanceof fabric__namespace.ActiveSelection && (transformStart == null ? void 0 : transformStart.groupId) === groupToMove.id) {
15053
- const selectionCenter = activeObj.getCenterPoint();
15054
- movedGroupLeft = transformStart.groupLeft + (selectionCenter.x - transformStart.selectionCenterX);
15055
- 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);
15056
14718
  } else if (activeObj instanceof fabric__namespace.ActiveSelection && firstId && firstObj) {
15057
14719
  const firstNode = findNodeById(pageChildren2, firstId);
15058
14720
  if (firstNode) {
@@ -15088,58 +14750,19 @@ const PageCanvas = react.forwardRef(
15088
14750
  }
15089
14751
  const deltaX = movedGroupLeft - groupAbs.left;
15090
14752
  const deltaY = movedGroupTop - groupAbs.top;
15091
- const hadResizeHandle = isActiveSelection && !!activeSelectionResizeHandle;
15092
- const hadScale = isActiveSelection && activeObj && (hadResizeHandle || Math.abs((activeObj.scaleX ?? 1) - 1) > 0.01 || Math.abs((activeObj.scaleY ?? 1) - 1) > 0.01);
15093
- const startSelAngle = normalizeAngle((transformStart == null ? void 0 : transformStart.selectionAngle) ?? 0);
15094
- const currentSelAngle = isActiveSelection && activeObj ? normalizeAngle(activeObj.angle ?? 0) : 0;
15095
- const storedGroupAngle = normalizeAngle(Number(groupToMove.angle ?? 0));
15096
- const effectiveStartAngle = transformStart ? startSelAngle : storedGroupAngle;
15097
- const angleDelta = shortestAngleDelta(currentSelAngle, effectiveStartAngle);
15098
- const hadRotation = isActiveSelection && activeObj && angleDelta > 1;
15099
- if (activeGroupSelectionId === groupToMove.id && hadRotation && !hadScale && !activeSelectionResizeHandle && activeObj instanceof fabric__namespace.ActiveSelection) {
15100
- const { updateNode: updateNodeStore, commitHistory: commitHistoryStore, getCurrentElements } = useEditorStore.getState();
15101
- const center = activeObj.getCenterPoint();
15102
- const baseCenterX = (transformStart == null ? void 0 : transformStart.selectionCenterX) ?? groupAbs.left + groupAbs.width / 2;
15103
- const baseCenterY = (transformStart == null ? void 0 : transformStart.selectionCenterY) ?? groupAbs.top + groupAbs.height / 2;
15104
- const nextAbsLeft = groupAbs.left + (center.x - baseCenterX);
15105
- const nextAbsTop = groupAbs.top + (center.y - baseCenterY);
15106
- const storePos = absoluteToStorePosition(nextAbsLeft, nextAbsTop, groupToMove.id, pageChildren2);
15107
- updateNodeStore(groupToMove.id, {
15108
- left: storePos.left,
15109
- top: storePos.top,
15110
- angle: currentSelAngle
15111
- }, { recordHistory: false, skipLayoutRecalc: true });
15112
- commitHistoryStore();
15113
- restoreGroupSelectionVisualState(activeObj, groupToMove.id);
15114
- fabricCanvas.setActiveObject(activeObj);
15115
- activeObj.setCoords();
15116
- selectElements([groupToMove.id], false, false);
15117
- fabricCanvas.requestRenderAll();
15118
- elementsRef.current = getCurrentElements();
15119
- const restoreSnapshot = {
15120
- memberIds: activeObj.getObjects().map((obj) => getObjectId(obj)).filter((id) => !!id && id !== "__background__"),
15121
- groupSelectionId: groupToMove.id,
15122
- expiresAt: Date.now() + 1200
15123
- };
15124
- recentGroupSelectionRestoreRef.current = restoreSnapshot;
15125
- activeObj.getObjects().forEach((obj) => {
15126
- const objId = getObjectId(obj);
15127
- if (objId && objId !== "__background__") {
15128
- justModifiedIdsRef.current.add(objId);
15129
- modifiedIdsThisRound.add(objId);
15130
- }
15131
- });
15132
- setTimeout(() => modifiedIdsThisRound.forEach((id) => justModifiedIdsRef.current.delete(id)), 150);
15133
- groupSelectionTransformStartRef.current = null;
15134
- activeSelectionMoveStartRef.current = null;
15135
- activeSelectionResizeHandleRef.current = null;
15136
- unlockEditsSoon();
15137
- return;
15138
- }
15139
- 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)) {
15140
14762
  const { updateNode: updateNodeStore, commitHistory: commitHistoryStore, getCurrentElements } = useEditorStore.getState();
15141
- const storePos = absoluteToStorePosition(movedGroupLeft, movedGroupTop, groupToMove.id, pageChildren2);
15142
- 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 });
15143
14766
  commitHistoryStore();
15144
14767
  pendingGroupDrillInRef.current = null;
15145
14768
  fabricCanvas.__activeEditingGroupId = null;
@@ -15164,8 +14787,6 @@ const PageCanvas = react.forwardRef(
15164
14787
  }
15165
14788
  setTimeout(() => modifiedIdsThisRound.forEach((id) => justModifiedIdsRef.current.delete(id)), 150);
15166
14789
  groupSelectionTransformStartRef.current = null;
15167
- activeSelectionMoveStartRef.current = null;
15168
- activeSelectionResizeHandleRef.current = null;
15169
14790
  const restoreSnapshot = {
15170
14791
  memberIds: targetObjects.map((obj) => getObjectId(obj)).filter((id) => !!id && id !== "__background__"),
15171
14792
  groupSelectionId,
@@ -15179,38 +14800,6 @@ const PageCanvas = react.forwardRef(
15179
14800
  }
15180
14801
  }
15181
14802
  const pendingCropGroupFrameBakes = [];
15182
- const logicalGroupSelectionId = activeObj instanceof fabric__namespace.ActiveSelection ? activeObj.__pixldocsGroupSelection : void 0;
15183
- const isLogicalGroupAS = !!logicalGroupSelectionId && !(activeObj == null ? void 0 : activeObj.__cropGroup) && !(activeObj == null ? void 0 : activeObj.__docuforgeSectionGroup);
15184
- const logicalGroupNodeForBake = logicalGroupSelectionId ? findNodeById(pageChildren2, logicalGroupSelectionId) : null;
15185
- const asAngleForBake = isLogicalGroupAS && activeObj ? normalizeAngle(Number(activeObj.angle ?? 0)) : 0;
15186
- const logicalGroupFinalFrame = (() => {
15187
- var _a3;
15188
- if (!isLogicalGroupAS || !logicalGroupSelectionId || !(activeObj instanceof fabric__namespace.ActiveSelection)) return null;
15189
- const baseline = ((_a3 = groupSelectionTransformStartRef.current) == null ? void 0 : _a3.groupId) === logicalGroupSelectionId ? groupSelectionTransformStartRef.current : null;
15190
- const localWidth = Math.max(1, (activeObj.width ?? (baseline == null ? void 0 : baseline.groupWidth) ?? 1) * Math.abs(activeObj.scaleX ?? 1));
15191
- const localHeight = Math.max(1, (activeObj.height ?? (baseline == null ? void 0 : baseline.groupHeight) ?? 1) * Math.abs(activeObj.scaleY ?? 1));
15192
- const center = activeObj.getCenterPoint();
15193
- const topLeft = centerToRotatedTopLeft(center.x, center.y, localWidth, localHeight, asAngleForBake);
15194
- return {
15195
- groupId: logicalGroupSelectionId,
15196
- left: topLeft.left,
15197
- top: topLeft.top,
15198
- width: localWidth,
15199
- height: localHeight,
15200
- centerX: center.x,
15201
- centerY: center.y,
15202
- angle: asAngleForBake,
15203
- matrix: fabric__namespace.util.composeMatrix({
15204
- translateX: center.x,
15205
- translateY: center.y,
15206
- angle: asAngleForBake,
15207
- scaleX: 1,
15208
- scaleY: 1,
15209
- skewX: 0,
15210
- skewY: 0
15211
- })
15212
- };
15213
- })();
15214
14803
  for (const obj of activeObjects) {
15215
14804
  const objId = getObjectId(obj);
15216
14805
  if (!objId || objId === "__background__") continue;
@@ -15256,15 +14845,16 @@ const PageCanvas = react.forwardRef(
15256
14845
  modifiedIdsThisRound.add(objId);
15257
14846
  let absoluteLeft;
15258
14847
  let absoluteTop;
15259
- const initialTopLeft = centerToRotatedTopLeft(
15260
- decomposed.translateX ?? (obj.left ?? 0),
15261
- decomposed.translateY ?? (obj.top ?? 0),
15262
- intrinsicWidth * Math.abs(decomposed.scaleX || 1),
15263
- intrinsicHeight * Math.abs(decomposed.scaleY || 1),
15264
- decomposed.angle ?? 0
15265
- );
15266
- absoluteLeft = initialTopLeft.left;
15267
- 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
+ }
15268
14858
  if (obj instanceof fabric__namespace.Group && obj.__cropGroup) {
15269
14859
  const ct = obj.__cropData;
15270
14860
  if (isActiveSelection && activeObj instanceof fabric__namespace.ActiveSelection) {
@@ -15274,22 +14864,14 @@ const PageCanvas = react.forwardRef(
15274
14864
  } else {
15275
14865
  const w = ((ct == null ? void 0 : ct.frameW) ?? obj.width ?? 0) * Math.abs(obj.scaleX ?? 1);
15276
14866
  const h = ((ct == null ? void 0 : ct.frameH) ?? obj.height ?? 0) * Math.abs(obj.scaleY ?? 1);
15277
- const angleRad = (decomposed.angle ?? obj.angle ?? 0) * Math.PI / 180;
15278
- absoluteLeft = (decomposed.translateX ?? absoluteLeft ?? 0) - w / 2 * Math.cos(angleRad) + h / 2 * Math.sin(angleRad);
15279
- 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;
15280
14869
  }
15281
14870
  } else if (obj instanceof fabric__namespace.FabricImage && (obj.originX === "center" || obj.originY === "center")) {
15282
- if (isActiveSelection && activeObj instanceof fabric__namespace.ActiveSelection) {
15283
- const frameBounds = getObjectFrameBoundsInSelection(activeObj, obj, obj.width ?? 0, obj.height ?? 0);
15284
- absoluteLeft = frameBounds.left;
15285
- absoluteTop = frameBounds.top;
15286
- } else {
15287
- const w = (obj.width ?? 0) * (obj.scaleX ?? 1);
15288
- const h = (obj.height ?? 0) * (obj.scaleY ?? 1);
15289
- const angleRad = (decomposed.angle ?? obj.angle ?? 0) * Math.PI / 180;
15290
- absoluteLeft = (decomposed.translateX ?? absoluteLeft ?? 0) - w / 2 * Math.cos(angleRad) + h / 2 * Math.sin(angleRad);
15291
- absoluteTop = (decomposed.translateY ?? absoluteTop ?? 0) - w / 2 * Math.sin(angleRad) - h / 2 * Math.cos(angleRad);
15292
- }
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;
15293
14875
  }
15294
14876
  const preserveCornerGeometry = (sourceElement == null ? void 0 : sourceElement.type) === "shape" && (sourceElement.shapeType === "circle" || sourceElement.shapeType === "rounded-rect" || sourceElement.shapeType === "triangle");
15295
14877
  let finalWidth = intrinsicWidth;
@@ -15297,10 +14879,6 @@ const PageCanvas = react.forwardRef(
15297
14879
  let finalScaleX = decomposed.scaleX;
15298
14880
  let finalScaleY = decomposed.scaleY;
15299
14881
  let finalAbsoluteMatrix = absoluteMatrix;
15300
- let finalAngle = decomposed.angle;
15301
- let finalSkewX = decomposed.skewX;
15302
- let finalSkewY = decomposed.skewY;
15303
- let finalAngleFromDecomposed = true;
15304
14882
  if (obj instanceof fabric__namespace.Group && obj.__cropGroup) {
15305
14883
  const ct = obj.__cropData;
15306
14884
  if (ct) {
@@ -15317,14 +14895,12 @@ const PageCanvas = react.forwardRef(
15317
14895
  absoluteLeft = frameBounds.left;
15318
14896
  absoluteTop = frameBounds.top;
15319
14897
  } else {
15320
- const angleRad = (decomposed.angle ?? obj.angle ?? 0) * Math.PI / 180;
15321
- absoluteLeft = (decomposed.translateX ?? absoluteLeft) - finalWidth / 2 * Math.cos(angleRad) + finalHeight / 2 * Math.sin(angleRad);
15322
- 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;
15323
14900
  }
15324
- const finalCenter = rotatedTopLeftToCenter(absoluteLeft, absoluteTop, finalWidth, finalHeight, decomposed.angle ?? (obj.angle ?? 0));
15325
14901
  finalAbsoluteMatrix = fabric__namespace.util.composeMatrix({
15326
- translateX: finalCenter.x,
15327
- translateY: finalCenter.y,
14902
+ translateX: absoluteLeft + finalWidth / 2,
14903
+ translateY: absoluteTop + finalHeight / 2,
15328
14904
  angle: decomposed.angle ?? (obj.angle ?? 0),
15329
14905
  scaleX: 1,
15330
14906
  scaleY: 1,
@@ -15359,12 +14935,6 @@ const PageCanvas = react.forwardRef(
15359
14935
  finalHeight = bakedH;
15360
14936
  finalScaleX = 1;
15361
14937
  finalScaleY = 1;
15362
- if (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb") {
15363
- finalAngle = (sourceElement == null ? void 0 : sourceElement.angle) ?? obj.angle ?? decomposed.angle;
15364
- finalSkewX = (sourceElement == null ? void 0 : sourceElement.skewX) ?? obj.skewX ?? 0;
15365
- finalSkewY = (sourceElement == null ? void 0 : sourceElement.skewY) ?? obj.skewY ?? 0;
15366
- if ((sourceElement == null ? void 0 : sourceElement.angle) !== void 0 || obj.angle !== void 0) finalAngleFromDecomposed = false;
15367
- }
15368
14938
  obj.set({ scaleX: 1, scaleY: 1 });
15369
14939
  const newSrc = renderSmartElementToDataUri(sourceElement.smartElementType, sourceElement.smartProps, bakedW, bakedH);
15370
14940
  if (newSrc) {
@@ -15380,7 +14950,6 @@ const PageCanvas = react.forwardRef(
15380
14950
  useEditorStore.getState().updateElement(objId, { src: newSrc }, { recordHistory: false, skipLayoutRecalc: true });
15381
14951
  }
15382
14952
  } else if (isActiveSelection && (Math.abs((decomposed.scaleX ?? 1) - 1) > 1e-3 || Math.abs((decomposed.scaleY ?? 1) - 1) > 1e-3)) {
15383
- const debugImageBeforeBake = debugGroupImageSideResize ? summarizeFabricObjectForResizeDebug(obj) : null;
15384
14953
  const sx = Math.abs(decomposed.scaleX || 1);
15385
14954
  const sy = Math.abs(decomposed.scaleY || 1);
15386
14955
  const handle = activeSelectionResizeHandle;
@@ -15414,9 +14983,22 @@ const PageCanvas = react.forwardRef(
15414
14983
  const localScaleX = 1 / sx;
15415
14984
  const localScaleY = 1 / sy;
15416
14985
  obj.set({ scaleX: localScaleX, scaleY: localScaleY });
15417
- 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);
15418
14987
  const localCenter = selectionMatrix ? fabric__namespace.util.transformPoint(preBakeCenter, fabric__namespace.util.invertTransform(selectionMatrix)) : preBakeCenter;
15419
- 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
+ }
15420
15002
  }
15421
15003
  obj.dirty = true;
15422
15004
  if (activeObj) activeObj.dirty = true;
@@ -15427,63 +15009,34 @@ const PageCanvas = react.forwardRef(
15427
15009
  finalHeight = bakedH;
15428
15010
  finalScaleX = 1;
15429
15011
  finalScaleY = 1;
15430
- if (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb") {
15431
- finalAngle = (sourceElement == null ? void 0 : sourceElement.angle) ?? obj.angle ?? decomposed.angle;
15432
- finalSkewX = (sourceElement == null ? void 0 : sourceElement.skewX) ?? obj.skewX ?? 0;
15433
- finalSkewY = (sourceElement == null ? void 0 : sourceElement.skewY) ?? obj.skewY ?? 0;
15434
- if ((sourceElement == null ? void 0 : sourceElement.angle) !== void 0 || obj.angle !== void 0) finalAngleFromDecomposed = false;
15435
- }
15436
15012
  try {
15437
- const angleRad = (finalAngle ?? 0) * Math.PI / 180;
15013
+ const angleRad = (decomposed.angle ?? 0) * Math.PI / 180;
15438
15014
  const cos = Math.cos(angleRad);
15439
15015
  const sin = Math.sin(angleRad);
15440
15016
  const hw = finalWidth / 2;
15441
15017
  const hh = finalHeight / 2;
15442
- absoluteLeft = decomposed.translateX - hw * cos + hh * sin;
15443
- 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));
15444
15029
  } catch {
15445
15030
  }
15446
15031
  finalAbsoluteMatrix = fabric__namespace.util.composeMatrix({
15447
15032
  translateX: decomposed.translateX,
15448
15033
  translateY: decomposed.translateY,
15449
- angle: finalAngle ?? 0,
15034
+ angle: decomposed.angle ?? 0,
15450
15035
  scaleX: 1,
15451
15036
  scaleY: 1,
15452
- skewX: finalSkewX ?? 0,
15453
- skewY: finalSkewY ?? 0
15037
+ skewX: 0,
15038
+ skewY: 0
15454
15039
  });
15455
- if (debugGroupImageSideResize) {
15456
- logGroupImageResizeDebug("image-bake", {
15457
- time: Math.round(performance.now()),
15458
- handle: activeSelectionResizeHandle,
15459
- imageId: objId,
15460
- source: sourceElement ? {
15461
- left: sourceElement.left,
15462
- top: sourceElement.top,
15463
- width: sourceElement.width,
15464
- height: sourceElement.height,
15465
- angle: sourceElement.angle,
15466
- scaleX: sourceElement.scaleX,
15467
- scaleY: sourceElement.scaleY
15468
- } : null,
15469
- factors: { sx, sy, fx, fy, isCornerHandle },
15470
- beforeBake: debugImageBeforeBake,
15471
- afterBake: summarizeFabricObjectForResizeDebug(obj),
15472
- persistedGeometry: {
15473
- absoluteLeft,
15474
- absoluteTop,
15475
- finalWidth,
15476
- finalHeight,
15477
- finalScaleX,
15478
- finalScaleY,
15479
- finalAngle,
15480
- finalSkewX,
15481
- finalSkewY,
15482
- decomposed,
15483
- finalAbsoluteMatrix
15484
- }
15485
- });
15486
- }
15487
15040
  } else {
15488
15041
  finalWidth = intrinsicWidth;
15489
15042
  finalHeight = intrinsicHeight;
@@ -15493,33 +15046,16 @@ const PageCanvas = react.forwardRef(
15493
15046
  finalHeight = 0;
15494
15047
  finalScaleX = 1;
15495
15048
  finalScaleY = 1;
15496
- if (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb") {
15497
- finalAngle = (sourceElement == null ? void 0 : sourceElement.angle) ?? obj.angle ?? decomposed.angle;
15498
- finalSkewX = (sourceElement == null ? void 0 : sourceElement.skewX) ?? obj.skewX ?? 0;
15499
- finalSkewY = (sourceElement == null ? void 0 : sourceElement.skewY) ?? obj.skewY ?? 0;
15500
- if ((sourceElement == null ? void 0 : sourceElement.angle) !== void 0 || obj.angle !== void 0) finalAngleFromDecomposed = false;
15501
- }
15502
- } 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)) {
15503
- const liveOrigW = obj.__asLiveOrigW;
15504
- const liveOrigH = obj.__asLiveOrigH;
15505
- const decSx = Math.abs(decomposed.scaleX || 1);
15506
- const decSy = Math.abs(decomposed.scaleY || 1);
15507
- const sx = Math.abs(decSx - 1) < 1e-3 && liveOrigW && liveOrigW > 0 ? Math.max(1e-3, (obj.width ?? liveOrigW) / liveOrigW) : decSx;
15508
- const baseHForRecover = Number(
15509
- obj.minBoxHeight ?? obj.height ?? liveOrigH ?? 1
15510
- );
15511
- 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);
15512
15052
  const isLikelyUniformCorner = !activeSelectionResizeHandle && Math.abs(sx - sy) < 0.01 && Math.abs(sx - 1) > 1e-3;
15513
15053
  const isCornerHandle = activeSelectionResizeHandle === "tl" || activeSelectionResizeHandle === "tr" || activeSelectionResizeHandle === "bl" || activeSelectionResizeHandle === "br" || isLikelyUniformCorner;
15514
15054
  const isHeightSideHandle = activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb";
15515
15055
  const fontScale = isCornerHandle ? Math.max(1e-3, Math.sqrt(sx * sy)) : 1;
15516
- const widthBase = liveOrigW && liveOrigW > 0 ? liveOrigW : intrinsicWidth;
15517
- const heightBase = liveOrigH && liveOrigH > 0 ? liveOrigH : intrinsicHeight;
15518
- const bakedWidth = Math.max(20, widthBase * sx);
15519
- const liveMinHOrig = obj.__asLiveOrigMinH;
15520
- const currentMinH = Number(obj.minBoxHeight ?? (sourceElement == null ? void 0 : sourceElement.minBoxHeight));
15521
- const minHBase = Number.isFinite(liveMinHOrig) && liveMinHOrig > 0 ? liveMinHOrig : liveOrigH && liveOrigH > 0 ? currentMinH / sy : currentMinH;
15522
- 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;
15523
15059
  const bakedTextScaleUpdates = { width: bakedWidth };
15524
15060
  const debugTextBeforeBake = debugGroupTextCornerResize ? summarizeFabricObjectForResizeDebug(obj) : null;
15525
15061
  finalScaleX = 1;
@@ -15578,9 +15114,14 @@ const PageCanvas = react.forwardRef(
15578
15114
  const localScaleX = 1 / sx;
15579
15115
  const localScaleY = 1 / sy;
15580
15116
  obj.set({ scaleX: localScaleX, scaleY: localScaleY });
15581
- 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);
15582
15118
  const localCenter = selectionMatrix ? fabric__namespace.util.transformPoint(preBakeCenter, fabric__namespace.util.invertTransform(selectionMatrix)) : preBakeCenter;
15583
- 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
+ });
15584
15125
  } else {
15585
15126
  obj.setPositionByOrigin(preBakeCenter, "center", "center");
15586
15127
  }
@@ -15593,23 +15134,32 @@ const PageCanvas = react.forwardRef(
15593
15134
  } catch {
15594
15135
  }
15595
15136
  try {
15596
- const angleRad = (finalAngle ?? 0) * Math.PI / 180;
15137
+ const angleRad = (decomposed.angle ?? 0) * Math.PI / 180;
15597
15138
  const cos = Math.cos(angleRad);
15598
15139
  const sin = Math.sin(angleRad);
15599
15140
  const hw = finalWidth / 2;
15600
15141
  const hh = finalHeight / 2;
15601
- absoluteLeft = decomposed.translateX - hw * cos + hh * sin;
15602
- 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));
15603
15153
  } catch {
15604
15154
  }
15605
15155
  finalAbsoluteMatrix = fabric__namespace.util.composeMatrix({
15606
15156
  translateX: decomposed.translateX,
15607
15157
  translateY: decomposed.translateY,
15608
- angle: finalAngle ?? 0,
15158
+ angle: decomposed.angle ?? 0,
15609
15159
  scaleX: 1,
15610
15160
  scaleY: 1,
15611
- skewX: finalSkewX ?? 0,
15612
- skewY: finalSkewY ?? 0
15161
+ skewX: 0,
15162
+ skewY: 0
15613
15163
  });
15614
15164
  if (debugGroupTextCornerResize) {
15615
15165
  logGroupTextResizeDebug("text-bake", {
@@ -15664,21 +15214,7 @@ const PageCanvas = react.forwardRef(
15664
15214
  const state = useEditorStore.getState();
15665
15215
  const page = state.canvas.pages.find((p) => p.id === pageId);
15666
15216
  const pageChildrenForSave = (page == null ? void 0 : page.children) ?? [];
15667
- const storePos = (logicalGroupFinalFrame == null ? void 0 : logicalGroupFinalFrame.groupId) === logicalGroupSelectionId ? (() => {
15668
- const localCenter = fabric__namespace.util.transformPoint(
15669
- new fabric__namespace.Point(decomposed.translateX ?? 0, decomposed.translateY ?? 0),
15670
- fabric__namespace.util.invertTransform(logicalGroupFinalFrame.matrix)
15671
- );
15672
- const localAngle = finalAngleFromDecomposed ? ((Number(finalAngle ?? 0) - asAngleForBake) % 360 + 540) % 360 - 180 : Number(finalAngle ?? 0);
15673
- const localAngleRad = localAngle * Math.PI / 180;
15674
- return {
15675
- left: localCenter.x - finalWidth / 2 * Math.cos(localAngleRad) + finalHeight / 2 * Math.sin(localAngleRad) + logicalGroupFinalFrame.width / 2,
15676
- top: localCenter.y - finalWidth / 2 * Math.sin(localAngleRad) - finalHeight / 2 * Math.cos(localAngleRad) + logicalGroupFinalFrame.height / 2
15677
- };
15678
- })() : absoluteToStorePosition(absoluteLeft, absoluteTop, objId, pageChildrenForSave);
15679
- if (isLogicalGroupAS && finalAngleFromDecomposed && typeof finalAngle === "number") {
15680
- finalAngle = ((finalAngle - asAngleForBake) % 360 + 540) % 360 - 180;
15681
- }
15217
+ const storePos = absoluteToStorePosition(absoluteLeft, absoluteTop, objId, pageChildrenForSave);
15682
15218
  const isLineObj = obj instanceof fabric__namespace.Line;
15683
15219
  const isAutoShrinkText = (sourceElement == null ? void 0 : sourceElement.type) === "text" && sourceElement.overflowPolicy === "auto-shrink";
15684
15220
  const autoShrinkStoredHeight = isAutoShrinkText ? sourceElement.height : void 0;
@@ -15690,17 +15226,13 @@ const PageCanvas = react.forwardRef(
15690
15226
  // so finalWidth already reflects the new width chosen by the user.
15691
15227
  width: finalWidth,
15692
15228
  height: isLineObj ? 0 : isAutoShrinkText ? typeof autoShrinkStoredHeight === "number" ? autoShrinkStoredHeight : finalHeight : finalHeight,
15693
- angle: finalAngle,
15694
- skewX: isLineObj ? 0 : finalSkewX,
15695
- skewY: isLineObj ? 0 : finalSkewY,
15229
+ angle: decomposed.angle,
15230
+ skewX: isLineObj ? 0 : decomposed.skewX,
15231
+ skewY: isLineObj ? 0 : decomposed.skewY,
15696
15232
  scaleX: finalScaleX,
15697
- scaleY: finalScaleY
15233
+ scaleY: finalScaleY,
15234
+ transformMatrix: finalAbsoluteMatrix
15698
15235
  };
15699
- if (!isLogicalGroupAS) {
15700
- elementUpdate.transformMatrix = finalAbsoluteMatrix;
15701
- } else {
15702
- elementUpdate.transformMatrix = void 0;
15703
- }
15704
15236
  if (obj instanceof fabric__namespace.Textbox) {
15705
15237
  const bakedTextScaleUpdates = obj.__pixldocsBakedTextScaleUpdates;
15706
15238
  if (bakedTextScaleUpdates && typeof bakedTextScaleUpdates === "object") {
@@ -15731,41 +15263,10 @@ const PageCanvas = react.forwardRef(
15731
15263
  objectBeforeStoreWrite: summarizeFabricObjectForResizeDebug(obj)
15732
15264
  });
15733
15265
  }
15734
- if (debugGroupImageSideResize && isGroupResizeImageLikeObject(obj)) {
15735
- logGroupImageResizeDebug("store-update-image", {
15736
- time: Math.round(performance.now()),
15737
- handle: activeSelectionResizeHandle,
15738
- imageId: objId,
15739
- storePos,
15740
- elementUpdate,
15741
- objectBeforeStoreWrite: summarizeFabricObjectForResizeDebug(obj)
15742
- });
15743
- }
15744
15266
  updateElement(objId, elementUpdate, { recordHistory: false, skipLayoutRecalc: true });
15745
15267
  obj.setCoords();
15746
- delete obj.__asLiveOrigW;
15747
- delete obj.__asLiveOrigH;
15748
- delete obj.__asLiveOrigMinH;
15749
15268
  }
15750
- if (isLogicalGroupAS && logicalGroupSelectionId && activeObj instanceof fabric__namespace.ActiveSelection) {
15751
- try {
15752
- const pageChildrenForGroup = ((_j = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _j.children) ?? [];
15753
- const groupNode = findNodeById(pageChildrenForGroup, logicalGroupSelectionId);
15754
- if (groupNode && logicalGroupFinalFrame) {
15755
- const storePosGroup = absoluteToStorePosition(logicalGroupFinalFrame.left, logicalGroupFinalFrame.top, logicalGroupSelectionId, pageChildrenForGroup);
15756
- useEditorStore.getState().updateNode(logicalGroupSelectionId, {
15757
- left: storePosGroup.left,
15758
- top: storePosGroup.top,
15759
- width: logicalGroupFinalFrame.width,
15760
- height: logicalGroupFinalFrame.height,
15761
- angle: logicalGroupFinalFrame.angle
15762
- }, { recordHistory: false, skipLayoutRecalc: true });
15763
- }
15764
- } catch (err) {
15765
- console.warn("[Pixldocs] logical-group envelope persist failed", err);
15766
- }
15767
- }
15768
- 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) ?? [];
15769
15270
  const stackGroupsToReflow = /* @__PURE__ */ new Set();
15770
15271
  for (const id of modifiedIdsThisRound) {
15771
15272
  const parent = findParentGroup(pageChildrenForReflow, id);
@@ -15792,16 +15293,6 @@ const PageCanvas = react.forwardRef(
15792
15293
  renderOnAddRemove: fabricCanvas.renderOnAddRemove
15793
15294
  });
15794
15295
  }
15795
- if (debugGroupImageSideResize) {
15796
- logGroupImageResizeDebug("before-reselect", {
15797
- time: Math.round(performance.now()),
15798
- handle: activeSelectionResizeHandle,
15799
- wasGroupSel,
15800
- selection: summarizeFabricObjectForResizeDebug(activeObj),
15801
- members: membersToReselect.map((member) => summarizeFabricObjectForResizeDebug(member)),
15802
- renderOnAddRemove: fabricCanvas.renderOnAddRemove
15803
- });
15804
- }
15805
15296
  const prevRenderOnAddRemove = fabricCanvas.renderOnAddRemove;
15806
15297
  fabricCanvas.renderOnAddRemove = false;
15807
15298
  skipSelectionClearOnDiscardRef.current = true;
@@ -15816,10 +15307,9 @@ const PageCanvas = react.forwardRef(
15816
15307
  if (!ct) continue;
15817
15308
  ct.frameW = bake.width;
15818
15309
  ct.frameH = bake.height;
15819
- const bakeCenter = rotatedTopLeftToCenter(bake.left, bake.top, bake.width, bake.height, bake.angle);
15820
15310
  bake.obj.set({
15821
- left: bakeCenter.x,
15822
- top: bakeCenter.y,
15311
+ left: bake.left + bake.width / 2,
15312
+ top: bake.top + bake.height / 2,
15823
15313
  width: bake.width,
15824
15314
  height: bake.height,
15825
15315
  scaleX: 1,
@@ -15846,16 +15336,6 @@ const PageCanvas = react.forwardRef(
15846
15336
  renderOnAddRemove: fabricCanvas.renderOnAddRemove
15847
15337
  });
15848
15338
  }
15849
- if (debugGroupImageSideResize) {
15850
- logGroupImageResizeDebug("after-reselect", {
15851
- time: Math.round(performance.now()),
15852
- handle: activeSelectionResizeHandle,
15853
- wasGroupSel,
15854
- selection: summarizeFabricObjectForResizeDebug(newSel),
15855
- members: membersToReselect.map((member) => summarizeFabricObjectForResizeDebug(member)),
15856
- renderOnAddRemove: fabricCanvas.renderOnAddRemove
15857
- });
15858
- }
15859
15339
  } else if (membersToReselect.length === 1) {
15860
15340
  fabricCanvas.setActiveObject(membersToReselect[0]);
15861
15341
  }
@@ -15892,7 +15372,6 @@ const PageCanvas = react.forwardRef(
15892
15372
  const activeObj = fabricCanvas.getActiveObject();
15893
15373
  if (!(activeObj instanceof fabric__namespace.ActiveSelection)) return;
15894
15374
  if (skipActiveSelectionBakeOnClearRef.current) return;
15895
- if (activeObj.__pixldocsGroupSelection) return;
15896
15375
  const selectionMatrix = activeObj.calcTransformMatrix();
15897
15376
  for (const obj of deselected) {
15898
15377
  const objId = getObjectId(obj);
@@ -16362,7 +15841,7 @@ const PageCanvas = react.forwardRef(
16362
15841
  const nextHeight = Math.max(minVisiblePlaceholder, Number(resolvedSizeImg.height) || 50);
16363
15842
  const storePosImg = pageChildren ? (() => {
16364
15843
  const node = findNodeById(pageChildren, element.id);
16365
- 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 };
16366
15845
  })() : { left: element.left ?? 0, top: element.top ?? 0 };
16367
15846
  const elementForPlaceholder = { ...element, width: nextWidth, height: nextHeight };
16368
15847
  const placeholder = isCropGroup2 ? createImagePlaceholderForGroup(elementForPlaceholder) : createImagePlaceholder(elementForPlaceholder);
@@ -16425,14 +15904,13 @@ const PageCanvas = react.forwardRef(
16425
15904
  }
16426
15905
  const cropPos = pageChildren ? (() => {
16427
15906
  const node = findNodeById(pageChildren, element.id);
16428
- return node && isElement(node) ? getElementFabricPlacement(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16429
- })() : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16430
- const cropCenter = rotatedTopLeftToCenter(cropPos.left, cropPos.top, ct.frameW ?? 0, ct.frameH ?? 0, cropPos.angle ?? element.angle ?? 0);
16431
- const cropCenterX = cropCenter.x;
16432
- 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;
16433
15911
  if (element.left !== void 0) existingObj.set({ left: cropCenterX });
16434
15912
  if (element.top !== void 0) existingObj.set({ top: cropCenterY });
16435
- existingObj.set({ angle: cropPos.angle ?? element.angle ?? 0 });
15913
+ if (element.angle !== void 0) existingObj.set({ angle: element.angle });
16436
15914
  existingObj.set({
16437
15915
  flipX: element.flipX ?? false,
16438
15916
  flipY: element.flipY ?? false
@@ -16555,8 +16033,8 @@ const PageCanvas = react.forwardRef(
16555
16033
  if (isPlaceholderGroup) {
16556
16034
  const storePosImg = pageChildren ? (() => {
16557
16035
  const node = findNodeById(pageChildren, element.id);
16558
- return node && isElement(node) ? getElementFabricPlacement(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16559
- })() : { 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 };
16560
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 };
16561
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;
16562
16040
  const minVisiblePlaceholder = hasExplicitSize ? 1 : 20;
@@ -16570,7 +16048,7 @@ const PageCanvas = react.forwardRef(
16570
16048
  top: storePosImg.top + nextHeight / 2,
16571
16049
  originX: "center",
16572
16050
  originY: "center",
16573
- angle: storePosImg.angle ?? element.angle ?? 0,
16051
+ angle: element.angle ?? 0,
16574
16052
  opacity: isHidden ? 0 : element.opacity ?? 1,
16575
16053
  flipX: element.flipX ?? false,
16576
16054
  flipY: element.flipY ?? false,
@@ -16619,8 +16097,8 @@ const PageCanvas = react.forwardRef(
16619
16097
  const visibilityChanged = previousVisible !== currentVisible;
16620
16098
  const storePosForImg = pageChildren ? (() => {
16621
16099
  const node = findNodeById(pageChildren, element.id);
16622
- return node && isElement(node) ? getElementFabricPlacement(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16623
- })() : { 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 };
16624
16102
  const positionChanged = Math.abs((existingObj.left ?? 0) - storePosForImg.left) > 0.1 || Math.abs((existingObj.top ?? 0) - storePosForImg.top) > 0.1;
16625
16103
  if (visibilityChanged && !positionChanged || visibilityUpdateInProgressRef.current) {
16626
16104
  const isDynamicField = dynamicFieldIds.includes(element.id);
@@ -16662,7 +16140,7 @@ const PageCanvas = react.forwardRef(
16662
16140
  const fabricTop = existingObj.top ?? 0;
16663
16141
  const storePos = pageChildren ? (() => {
16664
16142
  const node = findNodeById(pageChildren, element.id);
16665
- 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 };
16666
16144
  })() : { left: element.left ?? 0, top: element.top ?? 0 };
16667
16145
  const storeLeft = storePos.left;
16668
16146
  const storeTop = storePos.top;
@@ -16789,7 +16267,7 @@ const PageCanvas = react.forwardRef(
16789
16267
  setObjectData(placeholder, element.id);
16790
16268
  const absPosImg = pageTree.length > 0 ? (() => {
16791
16269
  const node = findNodeById(pageTree, element.id);
16792
- 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 };
16793
16271
  })() : { left: element.left ?? 0, top: element.top ?? 0 };
16794
16272
  const placeholderWidth = Number((placeholder.width ?? 0) * (placeholder.scaleX ?? 1));
16795
16273
  const placeholderHeight = Number((placeholder.height ?? 0) * (placeholder.scaleY ?? 1));
@@ -16838,7 +16316,7 @@ const PageCanvas = react.forwardRef(
16838
16316
  if (obj) {
16839
16317
  const absPos = pageTree.length > 0 ? (() => {
16840
16318
  const node = findNodeById(pageTree, element.id);
16841
- 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 };
16842
16320
  })() : { left: element.left ?? 0, top: element.top ?? 0 };
16843
16321
  obj.set({ left: absPos.left, top: absPos.top });
16844
16322
  obj.setCoords();
@@ -17228,7 +16706,9 @@ const PageCanvas = react.forwardRef(
17228
16706
  if (sameSelection && isFlatGroupSelection) {
17229
16707
  if (selectedGroupSelectionId && active instanceof fabric__namespace.ActiveSelection) {
17230
16708
  if (isPureSingleGroupSelection) {
17231
- applyLogicalGroupSelectionVisualState(active, selectedGroupSelectionId);
16709
+ active.__pixldocsGroupSelection = selectedGroupSelectionId;
16710
+ delete active.__pixldocsLogicalGroupIds;
16711
+ suppressGroupMemberBordersRef.current = active.getObjects();
17232
16712
  } else {
17233
16713
  delete active.__pixldocsGroupSelection;
17234
16714
  active.__pixldocsLogicalGroupIds = selectedGroupIds;
@@ -17268,7 +16748,8 @@ const PageCanvas = react.forwardRef(
17268
16748
  const selection = new fabric__namespace.ActiveSelection(toSelect, { canvas: fc });
17269
16749
  if (selectedGroupSelectionId) {
17270
16750
  if (isPureSingleGroupSelection) {
17271
- applyLogicalGroupSelectionVisualState(selection, selectedGroupSelectionId);
16751
+ selection.__pixldocsGroupSelection = selectedGroupSelectionId;
16752
+ suppressGroupMemberBordersRef.current = toSelect;
17272
16753
  } else {
17273
16754
  selection.__pixldocsLogicalGroupIds = selectedGroupIds;
17274
16755
  selection.hasBorders = true;
@@ -17326,9 +16807,8 @@ const PageCanvas = react.forwardRef(
17326
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) ?? [];
17327
16808
  const fabricPos = currentPageTree.length > 0 ? (() => {
17328
16809
  const node = findNodeById(currentPageTree, element.id);
17329
- return node && isElement(node) ? getElementFabricPlacement(node, currentPageTree) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
17330
- })() : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
17331
- const fabricAngle = fabricPos.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 };
17332
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 };
17333
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;
17334
16814
  const minVisible = shouldPreserveSmallSize ? 1 : 20;
@@ -17363,9 +16843,8 @@ const PageCanvas = react.forwardRef(
17363
16843
  ct.shape = clipShape === "circle" ? "circle" : clipShape === "rounded" ? "roundRect" : "rect";
17364
16844
  ct.rx = rxRatio;
17365
16845
  obj.__maintainResolution = element.maintainResolution !== false;
17366
- const center = rotatedTopLeftToCenter(fabricPos.left, fabricPos.top, elementWidth, elementHeight, element.angle ?? 0);
17367
- const centerX = center.x;
17368
- const centerY = center.y;
16846
+ const centerX = fabricPos.left + elementWidth / 2;
16847
+ const centerY = fabricPos.top + elementHeight / 2;
17369
16848
  const cropSetProps = {
17370
16849
  width: elementWidth,
17371
16850
  height: elementHeight,
@@ -17585,7 +17064,7 @@ const PageCanvas = react.forwardRef(
17585
17064
  y1: 0,
17586
17065
  x2: lineLen,
17587
17066
  y2: 0,
17588
- angle: fabricAngle,
17067
+ angle: element.angle ?? 0,
17589
17068
  scaleX: 1,
17590
17069
  scaleY: 1,
17591
17070
  skewX: 0,
@@ -17605,8 +17084,7 @@ const PageCanvas = react.forwardRef(
17605
17084
  if (!skipPositionUpdate && (obj instanceof fabric__namespace.FabricImage && obj.originX === "center" || obj instanceof fabric__namespace.Group && obj.__cropGroup)) {
17606
17085
  const vW = rW * effectiveScaleX;
17607
17086
  const vH = rH * effectiveScaleY;
17608
- const center = rotatedTopLeftToCenter(fabricPos.left, fabricPos.top, vW, vH, element.angle ?? 0);
17609
- posIfNotSkipped = { left: center.x, top: center.y };
17087
+ posIfNotSkipped = { left: fabricPos.left + vW / 2, top: fabricPos.top + vH / 2 };
17610
17088
  }
17611
17089
  if (element.transformMatrix && element.transformMatrix.length === 6) {
17612
17090
  if (isTextbox) {
@@ -17615,7 +17093,7 @@ const PageCanvas = react.forwardRef(
17615
17093
  width: rW,
17616
17094
  scaleX: effectiveScaleX,
17617
17095
  scaleY: effectiveScaleY,
17618
- angle: fabricAngle,
17096
+ angle: element.angle ?? 0,
17619
17097
  skewX: element.skewX ?? 0,
17620
17098
  skewY: appliedSkewY
17621
17099
  });
@@ -17624,7 +17102,7 @@ const PageCanvas = react.forwardRef(
17624
17102
  ...posIfNotSkipped,
17625
17103
  scaleX: effectiveScaleX,
17626
17104
  scaleY: effectiveScaleY,
17627
- angle: fabricAngle,
17105
+ angle: element.angle ?? 0,
17628
17106
  skewX: element.skewX ?? 0,
17629
17107
  skewY: element.skewY ?? 0
17630
17108
  });
@@ -17635,7 +17113,7 @@ const PageCanvas = react.forwardRef(
17635
17113
  obj.set({
17636
17114
  ...posIfNotSkipped,
17637
17115
  width: rW,
17638
- angle: fabricAngle,
17116
+ angle: element.angle ?? 0,
17639
17117
  skewX: element.skewX ?? 0,
17640
17118
  skewY: appliedSkewY,
17641
17119
  scaleX: effectiveScaleX * baseScaleX,
@@ -17644,7 +17122,7 @@ const PageCanvas = react.forwardRef(
17644
17122
  } else {
17645
17123
  obj.set({
17646
17124
  ...posIfNotSkipped,
17647
- angle: fabricAngle,
17125
+ angle: element.angle ?? 0,
17648
17126
  skewX: element.skewX ?? 0,
17649
17127
  skewY: element.skewY ?? 0,
17650
17128
  scaleX: effectiveScaleX * baseScaleX,
@@ -18397,14 +17875,14 @@ const PageCanvas = react.forwardRef(
18397
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) ?? [];
18398
17876
  const createPos = pageTreeForCreate.length > 0 ? (() => {
18399
17877
  const node = findNodeById(pageTreeForCreate, element.id);
18400
- return node && isElement(node) ? getElementFabricPlacement(node, pageTreeForCreate, pageBoundsOptions) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
18401
- })() : { 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 };
18402
17880
  img.set({
18403
17881
  left: createPos.left,
18404
17882
  top: createPos.top,
18405
17883
  scaleX: finalScaleX,
18406
17884
  scaleY: finalScaleY,
18407
- angle: createPos.angle ?? element.angle ?? 0,
17885
+ angle: element.angle ?? 0,
18408
17886
  skewX: element.skewX ?? 0,
18409
17887
  skewY: element.skewY ?? 0,
18410
17888
  flipX: element.flipX ?? false,
@@ -18491,8 +17969,8 @@ const PageCanvas = react.forwardRef(
18491
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) ?? [];
18492
17970
  const createPosForCrop = pageTreeForCrop.length > 0 ? (() => {
18493
17971
  const node = findNodeById(pageTreeForCrop, element.id);
18494
- return node && isElement(node) ? getElementFabricPlacement(node, pageTreeForCrop, pageBoundsOptions) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
18495
- })() : { 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 };
18496
17974
  const nodeForCreate = pageTreeForCrop.length ? findNodeById(pageTreeForCrop, element.id) : null;
18497
17975
  const createW = nodeForCreate && isElement(nodeForCreate) ? nodeForCreate.width : elementWidth;
18498
17976
  const createH = nodeForCreate && isElement(nodeForCreate) ? nodeForCreate.height : elementHeight;
@@ -18500,9 +17978,8 @@ const PageCanvas = react.forwardRef(
18500
17978
  const createSy = nodeForCreate && isElement(nodeForCreate) ? nodeForCreate.scaleY ?? 1 : element.scaleY ?? 1;
18501
17979
  const frameW = Math.max(1, Number(createW) || 200) * createSx;
18502
17980
  const frameH = Math.max(1, Number(createH) || 50) * createSy;
18503
- const createCenter = rotatedTopLeftToCenter(createPosForCrop.left, createPosForCrop.top, frameW, frameH, createPosForCrop.angle ?? element.angle ?? 0);
18504
- const createCenterX = createCenter.x;
18505
- const createCenterY = createCenter.y;
17981
+ const createCenterX = createPosForCrop.left + frameW / 2;
17982
+ const createCenterY = createPosForCrop.top + frameH / 2;
18506
17983
  const cropGroup = await createMaskedImageElement({
18507
17984
  image: img,
18508
17985
  frameW,
@@ -18515,7 +17992,7 @@ const PageCanvas = react.forwardRef(
18515
17992
  strokeWidth: 0,
18516
17993
  left: createCenterX,
18517
17994
  top: createCenterY,
18518
- angle: createPosForCrop.angle ?? element.angle ?? 0,
17995
+ angle: element.angle ?? 0,
18519
17996
  opacity: isHidden ? 0 : element.opacity ?? 1,
18520
17997
  selectable: allowSelection && !isHidden,
18521
17998
  evented: canBeEvented && !isHidden,
@@ -24905,9 +24382,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
24905
24382
  }
24906
24383
  return svgString;
24907
24384
  }
24908
- const resolvedPackageVersion = "0.5.354";
24385
+ const resolvedPackageVersion = "0.5.355";
24909
24386
  const PACKAGE_VERSION = resolvedPackageVersion;
24910
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.354";
24387
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.355";
24911
24388
  const roundParityValue = (value) => {
24912
24389
  if (typeof value !== "number") return value;
24913
24390
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -25721,7 +25198,7 @@ class PixldocsRenderer {
25721
25198
  await this.waitForCanvasScene(container, cloned, i);
25722
25199
  }
25723
25200
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
25724
- const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-DnoKFr-R.cjs"));
25201
+ const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-BtRK4LgQ.cjs"));
25725
25202
  const prepared = preparePagesForExport(
25726
25203
  cloned.pages,
25727
25204
  canvasWidth,
@@ -28041,7 +27518,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
28041
27518
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
28042
27519
  sanitizeSvgTreeForPdf(svgToDraw);
28043
27520
  try {
28044
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-DnoKFr-R.cjs"));
27521
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-BtRK4LgQ.cjs"));
28045
27522
  try {
28046
27523
  await logTextMeasurementDiagnostic(svgToDraw);
28047
27524
  } catch {
@@ -28438,4 +27915,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
28438
27915
  exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
28439
27916
  exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
28440
27917
  exports.warmTemplateFromForm = warmTemplateFromForm;
28441
- //# sourceMappingURL=index-BUYWcO1C.cjs.map
27918
+ //# sourceMappingURL=index-DWxht-v_.cjs.map