@pixldocs/canvas-renderer 0.5.353 → 0.5.355

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10500,105 +10500,6 @@ function bakeEdgeFade(source, fade) {
10500
10500
  }
10501
10501
  return canvas;
10502
10502
  }
10503
- const normalizeSignedAngle = (angle) => (angle % 360 + 540) % 360 - 180;
10504
- const rotatedTopLeftToCenter = (left, top, width, height, angleDeg = 0) => {
10505
- const angle = angleDeg * Math.PI / 180;
10506
- const cos = Math.cos(angle);
10507
- const sin = Math.sin(angle);
10508
- return {
10509
- x: left + width / 2 * cos - height / 2 * sin,
10510
- y: top + width / 2 * sin + height / 2 * cos
10511
- };
10512
- };
10513
- const centerToRotatedTopLeft = (centerX, centerY, width, height, angleDeg = 0) => {
10514
- const angle = angleDeg * Math.PI / 180;
10515
- const cos = Math.cos(angle);
10516
- const sin = Math.sin(angle);
10517
- return {
10518
- left: centerX - width / 2 * cos + height / 2 * sin,
10519
- top: centerY - width / 2 * sin - height / 2 * cos
10520
- };
10521
- };
10522
- const getGroupTransformFrame = (group, pageChildren, options) => {
10523
- const bounds = getNodeBounds(group, pageChildren);
10524
- const width = Math.max(1, Number(group.width ?? bounds.width) || bounds.width || 1);
10525
- const height = Math.max(1, Number(group.height ?? bounds.height) || bounds.height || 1);
10526
- return {
10527
- left: Number(group.left ?? bounds.left ?? 0) || 0,
10528
- top: Number(group.top ?? bounds.top ?? 0) || 0,
10529
- width,
10530
- height,
10531
- angle: Number(group.angle ?? 0) || 0
10532
- };
10533
- };
10534
- const getGroupLocalToParentMatrix = (group, pageChildren, options) => {
10535
- const frame = getGroupTransformFrame(group, pageChildren);
10536
- const rad = frame.angle * Math.PI / 180;
10537
- const cos = Math.cos(rad);
10538
- const sin = Math.sin(rad);
10539
- return [
10540
- cos,
10541
- sin,
10542
- -sin,
10543
- cos,
10544
- frame.left,
10545
- frame.top
10546
- ];
10547
- };
10548
- const getAncestorGroupTransform = (nodeId, pageChildren, fabric2, options) => {
10549
- let matrix = [1, 0, 0, 1, 0, 0];
10550
- let angle = 0;
10551
- const chain = [];
10552
- let currentId = nodeId;
10553
- for (let guard = 0; guard < 32; guard++) {
10554
- const parent = findParentGroup(pageChildren, currentId);
10555
- if (!parent) break;
10556
- chain.unshift(parent);
10557
- currentId = parent.id;
10558
- }
10559
- for (const group of chain) {
10560
- matrix = fabric2.util.multiplyTransformMatrices(
10561
- matrix,
10562
- getGroupLocalToParentMatrix(group, pageChildren)
10563
- );
10564
- angle += Number(group.angle ?? 0) || 0;
10565
- }
10566
- return { matrix, angle: normalizeSignedAngle(angle) };
10567
- };
10568
- const getElementFabricPlacement$1 = (element, pageChildren, fabric2, options) => {
10569
- if (!pageChildren.length) {
10570
- return { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
10571
- }
10572
- const ancestor = getAncestorGroupTransform(element.id, pageChildren, fabric2);
10573
- const point = fabric2.util.transformPoint(
10574
- new fabric2.Point(element.left ?? 0, element.top ?? 0),
10575
- ancestor.matrix
10576
- );
10577
- return {
10578
- left: point.x,
10579
- top: point.y,
10580
- angle: normalizeSignedAngle(ancestor.angle + Number(element.angle ?? 0))
10581
- };
10582
- };
10583
- const getGroupAbsoluteTransformFrame$1 = (group, pageChildren, fabric2, options) => {
10584
- const frame = getGroupTransformFrame(group, pageChildren);
10585
- const ancestor = getAncestorGroupTransform(group.id, pageChildren, fabric2);
10586
- const centerLocal = rotatedTopLeftToCenter(frame.left, frame.top, frame.width, frame.height, frame.angle);
10587
- const center = fabric2.util.transformPoint(new fabric2.Point(centerLocal.x, centerLocal.y), ancestor.matrix);
10588
- const topLeft = fabric2.util.transformPoint(new fabric2.Point(frame.left, frame.top), ancestor.matrix);
10589
- return {
10590
- left: topLeft.x,
10591
- top: topLeft.y,
10592
- width: frame.width,
10593
- height: frame.height,
10594
- centerX: center.x,
10595
- centerY: center.y,
10596
- angle: normalizeSignedAngle(ancestor.angle + frame.angle)
10597
- };
10598
- };
10599
- function preserveLogicalGroupTagDuringMove(selection, groupId) {
10600
- selection.__pixldocsGroupSelection = groupId;
10601
- }
10602
10503
  const SELECTION_PRIMARY = "hsl(217, 91%, 60%)";
10603
10504
  const SELECTION_BORDER_SCALE = 2;
10604
10505
  let ensureCanvaControlRenders = () => {
@@ -11052,18 +10953,12 @@ try {
11052
10953
  } catch (e) {
11053
10954
  }
11054
10955
  };
11055
- const wrapControlsFactory = (key) => {
11056
- if (typeof cu[key] !== "function") return;
11057
- const descriptor = Object.getOwnPropertyDescriptor(cu, key);
11058
- if (descriptor && descriptor.writable === false && !descriptor.set) return;
11059
- const original = cu[key].bind(cu);
11060
- try {
11061
- cu[key] = () => installPillRenders(original());
11062
- } catch {
11063
- }
11064
- };
11065
- wrapControlsFactory("createObjectDefaultControls");
11066
- wrapControlsFactory("createTextboxDefaultControls");
10956
+ const origObj = cu.createObjectDefaultControls.bind(cu);
10957
+ cu.createObjectDefaultControls = () => installPillRenders(origObj());
10958
+ if (typeof cu.createTextboxDefaultControls === "function") {
10959
+ const origTb = cu.createTextboxDefaultControls.bind(cu);
10960
+ cu.createTextboxDefaultControls = () => installPillRenders(origTb());
10961
+ }
11067
10962
  const wrapClassCreateControls = (Klass) => {
11068
10963
  if (!Klass || typeof Klass.createControls !== "function") return;
11069
10964
  const orig = Klass.createControls.bind(Klass);
@@ -11130,8 +11025,6 @@ const scaleUpdateNumber = (updates, source, key, factor) => {
11130
11025
  };
11131
11026
  const GROUP_TEXT_RESIZE_DEBUG_PREFIX = "[Pixldocs][group-text-corner-resize]";
11132
11027
  const GROUP_TEXT_RESIZE_DEBUG_MAX_ENTRIES = 200;
11133
- const GROUP_IMAGE_RESIZE_DEBUG_PREFIX = "[Pixldocs][group-image-side-resize]";
11134
- const GROUP_IMAGE_RESIZE_DEBUG_MAX_ENTRIES = 300;
11135
11028
  const isCornerResizeHandle = (handle) => handle === "tl" || handle === "tr" || handle === "bl" || handle === "br";
11136
11029
  const summarizeFabricObjectForResizeDebug = (obj) => {
11137
11030
  var _a2;
@@ -11194,43 +11087,6 @@ const logGroupTextResizeDebug = (phase, payload) => {
11194
11087
  console.log(GROUP_TEXT_RESIZE_DEBUG_PREFIX, phase, payload);
11195
11088
  }
11196
11089
  };
11197
- const isGroupResizeImageLikeObject = (obj) => {
11198
- var _a2;
11199
- return !!obj && (obj instanceof fabric.FabricImage || obj instanceof fabric.Group && (obj.__cropGroup || ((_a2 = obj._ct) == null ? void 0 : _a2.isCropGroup)));
11200
- };
11201
- const logGroupImageResizeDebug = (phase, payload) => {
11202
- if (typeof console === "undefined") return;
11203
- try {
11204
- const seen = /* @__PURE__ */ new WeakSet();
11205
- const normalize = (value) => {
11206
- if (value == null) return value;
11207
- const valueType = typeof value;
11208
- if (valueType === "number") return Number.isFinite(value) ? Math.round(value * 1e3) / 1e3 : String(value);
11209
- if (valueType === "string" || valueType === "boolean") return value;
11210
- if (valueType === "function") return `[Function ${value.name || "anonymous"}]`;
11211
- if (Array.isArray(value)) return value.map((entry) => normalize(entry));
11212
- if (valueType === "object") {
11213
- if (seen.has(value)) return "[Circular]";
11214
- seen.add(value);
11215
- if (value instanceof fabric.FabricObject) return normalize(summarizeFabricObjectForResizeDebug(value));
11216
- const output = {};
11217
- Object.entries(value).forEach(([key, entry]) => {
11218
- output[key] = normalize(entry);
11219
- });
11220
- return output;
11221
- }
11222
- return String(value);
11223
- };
11224
- const normalizedPayload = normalize(payload);
11225
- const line = `${GROUP_IMAGE_RESIZE_DEBUG_PREFIX} ${phase} ${JSON.stringify(normalizedPayload)}`;
11226
- const debugWindow = window;
11227
- debugWindow.__pixldocsGroupImageResizeLogs = Array.isArray(debugWindow.__pixldocsGroupImageResizeLogs) ? debugWindow.__pixldocsGroupImageResizeLogs.slice(-GROUP_IMAGE_RESIZE_DEBUG_MAX_ENTRIES + 1) : [];
11228
- debugWindow.__pixldocsGroupImageResizeLogs.push(line);
11229
- console.log(line);
11230
- } catch {
11231
- console.log(GROUP_IMAGE_RESIZE_DEBUG_PREFIX, phase, payload);
11232
- }
11233
- };
11234
11090
  const bakeTextboxScaleIntoTypography = (obj, sourceElement) => {
11235
11091
  const sx = Math.abs(obj.scaleX ?? 1) || 1;
11236
11092
  const sy = Math.abs(obj.scaleY ?? 1) || 1;
@@ -11304,8 +11160,6 @@ const bakeTextboxScaleIntoTypography = (obj, sourceElement) => {
11304
11160
  };
11305
11161
  return updates;
11306
11162
  };
11307
- const getElementFabricPlacement = (element, pageChildren, options) => getElementFabricPlacement$1(element, pageChildren, fabric);
11308
- const getGroupAbsoluteTransformFrame = (group, pageChildren, options) => getGroupAbsoluteTransformFrame$1(group, pageChildren, fabric);
11309
11163
  function applyWarpAwareSelectionBorders(selection) {
11310
11164
  var _a2;
11311
11165
  if (selection.__pixldocsOrigASHasBorders !== void 0) {
@@ -11314,7 +11168,6 @@ function applyWarpAwareSelectionBorders(selection) {
11314
11168
  }
11315
11169
  selection.hasBorders = true;
11316
11170
  selection.hasControls = true;
11317
- if (selection.__pixldocsGroupSelection) return;
11318
11171
  try {
11319
11172
  if (selection.__pixldocsAlignedAngle == null) {
11320
11173
  const kids = selection.getObjects();
@@ -11441,46 +11294,10 @@ const PageCanvas = forwardRef(
11441
11294
  const [ready, setReady] = useState(false);
11442
11295
  const [unlockRequestId, setUnlockRequestId] = useState(0);
11443
11296
  const applyLogicalGroupSelectionVisualState = useCallback((selection, groupId) => {
11444
- var _a2, _b2;
11297
+ var _a2;
11445
11298
  selection.__pixldocsGroupSelection = groupId;
11446
11299
  delete selection.__pixldocsLogicalGroupIds;
11447
11300
  selection.hasBorders = true;
11448
- try {
11449
- const membersBeforeFrame = selection.getObjects();
11450
- const selectionMatrixBefore = selection.calcTransformMatrix();
11451
- const memberWorldMatrices = membersBeforeFrame.map((member) => fabric.util.multiplyTransformMatrices(
11452
- selectionMatrixBefore,
11453
- member.calcOwnMatrix()
11454
- ));
11455
- const pageChildren2 = ((_a2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
11456
- const groupNode = findNodeById(pageChildren2, groupId);
11457
- const groupFrame = groupNode && isGroup(groupNode) ? getGroupAbsoluteTransformFrame(groupNode, pageChildren2, pageBoundsOptions) : null;
11458
- const groupAngle = groupFrame ? groupFrame.angle : 0;
11459
- if (Number.isFinite(groupAngle)) {
11460
- selection.set({ angle: groupAngle, scaleX: 1, scaleY: 1, skewX: 0, skewY: 0 });
11461
- if (groupFrame) {
11462
- selection.setPositionByOrigin(
11463
- new fabric.Point(groupFrame.centerX, groupFrame.centerY),
11464
- "center",
11465
- "center"
11466
- );
11467
- }
11468
- const invSelectionAfter = fabric.util.invertTransform(
11469
- selection.calcTransformMatrix()
11470
- );
11471
- membersBeforeFrame.forEach((member, index) => {
11472
- const localMatrix = fabric.util.multiplyTransformMatrices(
11473
- invSelectionAfter,
11474
- memberWorldMatrices[index]
11475
- );
11476
- fabric.util.applyTransformToObject(member, localMatrix);
11477
- member.setCoords();
11478
- member.dirty = true;
11479
- });
11480
- selection.setCoords();
11481
- }
11482
- } catch {
11483
- }
11484
11301
  const members = selection.getObjects();
11485
11302
  for (const prev of suppressGroupMemberBordersRef.current) {
11486
11303
  if (members.includes(prev)) continue;
@@ -11504,7 +11321,7 @@ const PageCanvas = forwardRef(
11504
11321
  if (m.__pixldocsOrigHasControls === void 0) m.__pixldocsOrigHasControls = m.hasControls;
11505
11322
  m.hasBorders = false;
11506
11323
  m.hasControls = false;
11507
- if (m.__cropGroup || ((_b2 = m._ct) == null ? void 0 : _b2.isCropGroup)) {
11324
+ if (m.__cropGroup || ((_a2 = m._ct) == null ? void 0 : _a2.isCropGroup)) {
11508
11325
  if (m.__pixldocsOrigLockScalingX === void 0) {
11509
11326
  m.__pixldocsOrigLockScalingX = m.lockScalingX;
11510
11327
  m.__pixldocsOrigLockScalingY = m.lockScalingY;
@@ -11514,7 +11331,7 @@ const PageCanvas = forwardRef(
11514
11331
  }
11515
11332
  }
11516
11333
  applyWarpAwareSelectionBorders(selection);
11517
- }, [pageId]);
11334
+ }, []);
11518
11335
  const pageBoundsOptions = useMemo(
11519
11336
  () => ({ pageContentWidth: canvasWidth, pageContentHeight: canvasHeight }),
11520
11337
  [canvasWidth, canvasHeight]
@@ -11588,6 +11405,7 @@ const PageCanvas = forwardRef(
11588
11405
  const preserveSelectionAfterTransformIdRef = useRef(null);
11589
11406
  const groupSelectionTransformStartRef = useRef(null);
11590
11407
  const activeSelectionMoveStartRef = useRef(null);
11408
+ const sectionGroupTransientImagesRef = useRef(null);
11591
11409
  setGroupOverlayLiveBoundsRef.current = setGroupOverlayLiveBounds;
11592
11410
  const {
11593
11411
  selectElements,
@@ -12433,6 +12251,7 @@ const PageCanvas = forwardRef(
12433
12251
  fabricCanvas.__fontCleanup = fontCleanup;
12434
12252
  fabricCanvas.__isUserTransforming = false;
12435
12253
  fabricCanvas.on("mouse:down", () => {
12254
+ groupSelectionTransformStartRef.current = null;
12436
12255
  activeSelectionMoveStartRef.current = null;
12437
12256
  activeSelectionResizeHandleRef.current = null;
12438
12257
  const active = fabricCanvas.getActiveObject();
@@ -12443,7 +12262,6 @@ const PageCanvas = forwardRef(
12443
12262
  selectionLeft: rect.left,
12444
12263
  selectionTop: rect.top
12445
12264
  };
12446
- prepareGroupSelectionTransformStart(active);
12447
12265
  }
12448
12266
  if (fabricCanvas._currentTransform) {
12449
12267
  fabricCanvas.__isUserTransforming = true;
@@ -12505,8 +12323,101 @@ const PageCanvas = forwardRef(
12505
12323
  });
12506
12324
  }
12507
12325
  });
12508
- fabricCanvas.on("object:moving", () => {
12326
+ const collectSectionGroupImageDescendantObjects = (groupNode) => {
12327
+ const ids = getAllElementIds(groupNode.children ?? []);
12328
+ if (ids.length === 0) return [];
12329
+ const elementById = new Map(elementsRef.current.map((el) => [el.id, el]));
12330
+ const out = [];
12331
+ for (const id of ids) {
12332
+ const el = elementById.get(id);
12333
+ if (!el || el.type !== "image") continue;
12334
+ const obj = fabricCanvas.getObjects().find((o) => getObjectId(o) === id);
12335
+ if (obj) out.push(obj);
12336
+ }
12337
+ return out;
12338
+ };
12339
+ const ensureSectionGroupTransientSnapshot = (group) => {
12340
+ var _a2;
12341
+ if (!group || !(group instanceof fabric.Group)) return false;
12342
+ if (!group.__docuforgeSectionGroup) return false;
12343
+ const groupId = getObjectId(group);
12344
+ if (!groupId) return false;
12345
+ const existing = sectionGroupTransientImagesRef.current;
12346
+ if (existing && existing.groupId === groupId && existing.group === group) return true;
12347
+ const pageChildrenLocal = ((_a2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
12348
+ const node = findNodeById(pageChildrenLocal, groupId);
12349
+ if (!node || !isGroup(node)) return false;
12350
+ const images = collectSectionGroupImageDescendantObjects(node);
12351
+ const gcx = group.left ?? 0;
12352
+ const gcy = group.top ?? 0;
12353
+ const gangle = group.angle ?? 0;
12354
+ const gsx = group.scaleX ?? 1;
12355
+ const gsy = group.scaleY ?? 1;
12356
+ const rad = -gangle * Math.PI / 180;
12357
+ const cos0 = Math.cos(rad);
12358
+ const sin0 = Math.sin(rad);
12359
+ const snap = images.map((obj) => {
12360
+ const icx = obj.left ?? 0;
12361
+ const icy = obj.top ?? 0;
12362
+ const dx = icx - gcx;
12363
+ const dy = icy - gcy;
12364
+ const rx = dx * cos0 - dy * sin0;
12365
+ const ry = dx * sin0 + dy * cos0;
12366
+ return {
12367
+ obj,
12368
+ localX: gsx ? rx / gsx : rx,
12369
+ localY: gsy ? ry / gsy : ry,
12370
+ relAngle: (obj.angle ?? 0) - gangle,
12371
+ relSx: (obj.scaleX ?? 1) / (gsx || 1),
12372
+ relSy: (obj.scaleY ?? 1) / (gsy || 1)
12373
+ };
12374
+ });
12375
+ sectionGroupTransientImagesRef.current = {
12376
+ groupId,
12377
+ group,
12378
+ group0: { cx: gcx, cy: gcy, angle: gangle, sx: gsx, sy: gsy },
12379
+ images: snap
12380
+ };
12381
+ return true;
12382
+ };
12383
+ const applySectionGroupTransientTransform = () => {
12384
+ const snap = sectionGroupTransientImagesRef.current;
12385
+ if (!snap || snap.images.length === 0) return;
12386
+ const group = snap.group;
12387
+ const gcx = group.left ?? 0;
12388
+ const gcy = group.top ?? 0;
12389
+ const gangle = group.angle ?? 0;
12390
+ const gsx = group.scaleX ?? 1;
12391
+ const gsy = group.scaleY ?? 1;
12392
+ const rad = gangle * Math.PI / 180;
12393
+ const cos = Math.cos(rad);
12394
+ const sin = Math.sin(rad);
12395
+ for (const entry of snap.images) {
12396
+ const lx = entry.localX * gsx;
12397
+ const ly = entry.localY * gsy;
12398
+ const wx = lx * cos - ly * sin;
12399
+ const wy = lx * sin + ly * cos;
12400
+ entry.obj.set({
12401
+ left: gcx + wx,
12402
+ top: gcy + wy,
12403
+ angle: entry.relAngle + gangle,
12404
+ scaleX: entry.relSx * gsx,
12405
+ scaleY: entry.relSy * gsy
12406
+ });
12407
+ entry.obj.setCoords();
12408
+ entry.obj.dirty = true;
12409
+ }
12410
+ };
12411
+ const clearSectionGroupTransientSnapshot = () => {
12412
+ sectionGroupTransientImagesRef.current = null;
12413
+ };
12414
+ const maybeFollowSectionGroupTransient = (target) => {
12415
+ if (!ensureSectionGroupTransientSnapshot(target)) return;
12416
+ applySectionGroupTransientTransform();
12417
+ };
12418
+ fabricCanvas.on("object:moving", (e) => {
12509
12419
  var _a2, _b2;
12420
+ maybeFollowSectionGroupTransient((e == null ? void 0 : e.target) ?? null);
12510
12421
  fabricCanvas.__isUserTransforming = true;
12511
12422
  didTransformRef.current = true;
12512
12423
  if (drilledGroupIdRef.current) {
@@ -12548,8 +12459,9 @@ const PageCanvas = forwardRef(
12548
12459
  });
12549
12460
  }
12550
12461
  });
12551
- fabricCanvas.on("object:rotating", () => {
12462
+ fabricCanvas.on("object:rotating", (e) => {
12552
12463
  var _a2;
12464
+ maybeFollowSectionGroupTransient((e == null ? void 0 : e.target) ?? null);
12553
12465
  fabricCanvas.__isUserTransforming = true;
12554
12466
  didTransformRef.current = true;
12555
12467
  if (drilledGroupIdRef.current) {
@@ -12559,6 +12471,12 @@ const PageCanvas = forwardRef(
12559
12471
  }
12560
12472
  }
12561
12473
  });
12474
+ fabricCanvas.on("object:scaling", (e) => {
12475
+ maybeFollowSectionGroupTransient((e == null ? void 0 : e.target) ?? null);
12476
+ });
12477
+ fabricCanvas.on("mouse:up", () => {
12478
+ clearSectionGroupTransientSnapshot();
12479
+ });
12562
12480
  const syncSelectionToStore = () => {
12563
12481
  var _a2, _b2, _c, _d;
12564
12482
  if (!isActiveRef.current || isRebuildingRef.current || isSyncingSelectionToFabricRef.current || !allowSelection) return;
@@ -12945,22 +12863,16 @@ const PageCanvas = forwardRef(
12945
12863
  const pageChildren2 = ((_b2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
12946
12864
  const groupNode = findNodeById(pageChildren2, groupId);
12947
12865
  if (!groupNode) return;
12948
- const groupFrame = isGroup(groupNode) ? getGroupAbsoluteTransformFrame(groupNode, pageChildren2) : null;
12949
- const groupAbs = groupFrame ?? getAbsoluteBounds(groupNode, pageChildren2);
12866
+ const groupAbs = getAbsoluteBounds(groupNode, pageChildren2);
12950
12867
  const rect = active.getBoundingRect();
12951
- const center = active.getCenterPoint();
12952
12868
  groupSelectionTransformStartRef.current = {
12953
12869
  groupId,
12954
12870
  selection: active,
12955
12871
  selectionLeft: rect.left,
12956
12872
  selectionTop: rect.top,
12957
- selectionCenterX: center.x,
12958
- selectionCenterY: center.y,
12959
12873
  groupLeft: groupAbs.left,
12960
12874
  groupTop: groupAbs.top,
12961
- groupWidth: groupAbs.width,
12962
- groupHeight: groupAbs.height,
12963
- selectionAngle: (((groupFrame == null ? void 0 : groupFrame.angle) ?? active.angle ?? 0) % 360 + 360) % 360
12875
+ selectionAngle: ((active.angle ?? 0) % 360 + 360) % 360
12964
12876
  };
12965
12877
  };
12966
12878
  const restoreGroupSelectionVisualState = (selection, groupId) => {
@@ -13297,9 +13209,6 @@ const PageCanvas = forwardRef(
13297
13209
  fabricCanvas.on("mouse:down:before", (opt) => {
13298
13210
  var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
13299
13211
  const activeBeforeMouseDown = fabricCanvas.getActiveObject();
13300
- if (activeBeforeMouseDown instanceof fabric.ActiveSelection && activeBeforeMouseDown.__pixldocsGroupSelection) {
13301
- prepareGroupSelectionTransformStart(activeBeforeMouseDown);
13302
- }
13303
13212
  if (editLockRef.current) {
13304
13213
  const active = fabricCanvas.getActiveObject();
13305
13214
  if (active && (((_a2 = active._ct) == null ? void 0 : _a2.isCropGroup) || active.__cropGroup)) {
@@ -13399,7 +13308,6 @@ const PageCanvas = forwardRef(
13399
13308
  restoreGroupSelectionVisualState(selection, parent.id);
13400
13309
  fabricCanvas.setActiveObject(selection);
13401
13310
  selection.setCoords();
13402
- prepareGroupSelectionTransformStart(selection);
13403
13311
  fabricCanvas._target = selection;
13404
13312
  opt.target = selection;
13405
13313
  pendingGroupPromotionRef.current = { groupId: parent.id, selection };
@@ -13442,7 +13350,6 @@ const PageCanvas = forwardRef(
13442
13350
  restoreGroupSelectionVisualState(selection, parent.id);
13443
13351
  fabricCanvas.setActiveObject(selection);
13444
13352
  selection.setCoords();
13445
- prepareGroupSelectionTransformStart(selection);
13446
13353
  fabricCanvas._target = selection;
13447
13354
  opt.target = selection;
13448
13355
  pendingGroupPromotionRef.current = { groupId: parent.id, selection };
@@ -13711,29 +13618,34 @@ const PageCanvas = forwardRef(
13711
13618
  });
13712
13619
  const markSimpleTransform = (e) => {
13713
13620
  if (!isActiveRef.current) return;
13714
- prepareGroupSelectionTransformStart(e.target);
13715
13621
  markTransforming(e.target);
13716
13622
  };
13717
13623
  const getObjectFrameBoundsInSelection = (selection, obj, frameWidth, frameHeight) => {
13718
13624
  const w = Math.max(1, frameWidth ?? obj.width ?? 1);
13719
13625
  const h = Math.max(1, frameHeight ?? obj.height ?? 1);
13626
+ const originX = obj.originX ?? "left";
13627
+ const originY = obj.originY ?? "top";
13628
+ const localLeft = originX === "center" ? -w / 2 : originX === "right" ? -w : 0;
13629
+ const localTop = originY === "center" ? -h / 2 : originY === "bottom" ? -h : 0;
13720
13630
  const matrix = fabric.util.multiplyTransformMatrices(
13721
13631
  selection.calcTransformMatrix(),
13722
13632
  obj.calcOwnMatrix()
13723
13633
  );
13724
- const decomposed = fabric.util.qrDecompose(matrix);
13725
- const scaledW = Math.max(1, w * Math.abs(decomposed.scaleX || 1));
13726
- const scaledH = Math.max(1, h * Math.abs(decomposed.scaleY || 1));
13727
- const angleRad = (decomposed.angle ?? 0) * Math.PI / 180;
13728
- const cos = Math.cos(angleRad);
13729
- const sin = Math.sin(angleRad);
13730
- const left = decomposed.translateX - scaledW / 2 * cos + scaledH / 2 * sin;
13731
- const top = decomposed.translateY - scaledW / 2 * sin - scaledH / 2 * cos;
13634
+ const points = [
13635
+ new fabric.Point(localLeft, localTop),
13636
+ new fabric.Point(localLeft + w, localTop),
13637
+ new fabric.Point(localLeft + w, localTop + h),
13638
+ new fabric.Point(localLeft, localTop + h)
13639
+ ].map((point) => fabric.util.transformPoint(point, matrix));
13640
+ const xs = points.map((p) => p.x);
13641
+ const ys = points.map((p) => p.y);
13642
+ const left = Math.min(...xs);
13643
+ const top = Math.min(...ys);
13732
13644
  return {
13733
13645
  left,
13734
13646
  top,
13735
- width: scaledW,
13736
- height: scaledH
13647
+ width: Math.max(1, Math.max(...xs) - left),
13648
+ height: Math.max(1, Math.max(...ys) - top)
13737
13649
  };
13738
13650
  };
13739
13651
  fabricCanvas.on("object:added", (e) => {
@@ -13748,30 +13660,10 @@ const PageCanvas = forwardRef(
13748
13660
  fabricCanvas.on("selection:cleared", () => {
13749
13661
  });
13750
13662
  fabricCanvas.on("object:scaling", (e) => {
13751
- var _a2, _b2, _c, _d, _e, _f, _g, _h;
13663
+ var _a2, _b2, _c, _d, _e, _f;
13752
13664
  if (!isActiveRef.current) return;
13753
13665
  const t = e.target;
13754
13666
  if (t) lastResizeScaleTargetRef.current = t;
13755
- try {
13756
- const transformDbg = e.transform;
13757
- const cornerDbg = (transformDbg == null ? void 0 : transformDbg.corner) || "";
13758
- const children = t instanceof fabric.Group || t instanceof fabric.ActiveSelection ? t.getObjects() : [];
13759
- logGroupImageResizeDebug("scaling-entry", {
13760
- time: Math.round(performance.now()),
13761
- corner: cornerDbg,
13762
- targetType: t == null ? void 0 : t.type,
13763
- targetCtor: (_a2 = t == null ? void 0 : t.constructor) == null ? void 0 : _a2.name,
13764
- isActiveSelection: t instanceof fabric.ActiveSelection,
13765
- isGroup: t instanceof fabric.Group,
13766
- isCropGroup: !!(t && (t.__cropGroup || ((_b2 = t._ct) == null ? void 0 : _b2.isCropGroup))),
13767
- childCount: children.length,
13768
- childTypes: children.map((c) => c == null ? void 0 : c.type),
13769
- hasImageChild: children.some((c) => isGroupResizeImageLikeObject(c)),
13770
- target: t ? summarizeFabricObjectForResizeDebug(t) : null
13771
- });
13772
- } catch (err) {
13773
- console.warn("[Pixldocs][group-image-side-resize] scaling-entry log failed", err);
13774
- }
13775
13667
  prepareGroupSelectionTransformStart(t);
13776
13668
  markTransforming(t);
13777
13669
  didTransformRef.current = true;
@@ -13935,7 +13827,7 @@ const PageCanvas = forwardRef(
13935
13827
  time: Math.round(performance.now()),
13936
13828
  corner,
13937
13829
  groupSelectionId: obj.__pixldocsGroupSelection,
13938
- currentTransformAction: (_c = fabricCanvas._currentTransform) == null ? void 0 : _c.action,
13830
+ currentTransformAction: (_a2 = fabricCanvas._currentTransform) == null ? void 0 : _a2.action,
13939
13831
  selection: summarizeFabricObjectForResizeDebug(obj),
13940
13832
  textChildren: obj.getObjects().filter((child) => child instanceof fabric.Textbox).map((child) => summarizeFabricObjectForResizeDebug(child))
13941
13833
  };
@@ -13945,43 +13837,19 @@ const PageCanvas = forwardRef(
13945
13837
  const isXSide = corner === "ml" || corner === "mr";
13946
13838
  const sAxis = isXSide ? Math.abs(obj.scaleX ?? 1) : Math.abs(obj.scaleY ?? 1);
13947
13839
  if (sAxis > 1e-3) {
13948
- const hasRotatedChild = obj.getObjects().some((c) => {
13949
- const a = ((c.angle ?? 0) % 180 + 180) % 180;
13950
- return !(a < 0.5 || a > 179.5);
13951
- });
13952
- const selectionAngle = ((obj.angle ?? 0) % 180 + 180) % 180;
13953
- const isSelectionRotated = !(selectionAngle < 0.5 || selectionAngle > 179.5);
13954
- const shouldPinNonTextChildren = hasRotatedChild || isSelectionRotated;
13955
- const shouldDebugGroupImageResize = obj.getObjects().some((child) => isGroupResizeImageLikeObject(child));
13956
- if (shouldDebugGroupImageResize) {
13957
- logGroupImageResizeDebug("live-start", {
13958
- time: Math.round(performance.now()),
13959
- corner,
13960
- isXSide,
13961
- sAxis,
13962
- hasRotatedChild,
13963
- isSelectionRotated,
13964
- shouldPinNonTextChildren,
13965
- groupSelectionId: obj.__pixldocsGroupSelection,
13966
- selection: summarizeFabricObjectForResizeDebug(obj),
13967
- children: obj.getObjects().map((child) => summarizeFabricObjectForResizeDebug(child))
13968
- });
13969
- }
13970
- if ((isXSide || shouldPinNonTextChildren) && ((_d = groupShiftReflowSnapshotRef.current) == null ? void 0 : _d.selection) !== obj) {
13840
+ if (isXSide && ((_b2 = groupShiftReflowSnapshotRef.current) == null ? void 0 : _b2.selection) !== obj) {
13971
13841
  groupShiftReflowSnapshotRef.current = null;
13972
13842
  const logicalGroupId = obj.__pixldocsGroupSelection;
13973
13843
  if (logicalGroupId) {
13974
13844
  try {
13975
13845
  const state = useEditorStore.getState();
13976
- const pageChildren2 = ((_e = state.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _e.children) ?? [];
13846
+ const pageChildren2 = ((_c = state.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _c.children) ?? [];
13977
13847
  const groupNode = findNodeById(pageChildren2, logicalGroupId);
13978
13848
  if (groupNode && isGroup(groupNode) && !isStackLayoutMode(groupNode.layoutMode)) {
13979
13849
  const entries = obj.getObjects().map((c) => ({
13980
13850
  obj: c,
13981
13851
  id: getObjectId(c) ?? "",
13982
- left0: c.left ?? 0,
13983
13852
  top0: c.top ?? 0,
13984
- width0: (c.width ?? 0) * Math.abs(c.scaleX ?? 1),
13985
13853
  height0: (c.height ?? 0) * Math.abs(c.scaleY ?? 1)
13986
13854
  })).filter((e2) => e2.id).sort((a, b) => a.top0 - b.top0);
13987
13855
  if (entries.length > 1) {
@@ -14004,150 +13872,78 @@ const PageCanvas = forwardRef(
14004
13872
  const asTop0 = obj.top ?? 0;
14005
13873
  const asRect0 = obj.getBoundingRect();
14006
13874
  let didReflowTextChild = false;
14007
- if (hasRotatedChild) {
14008
- if (isXSide) {
14009
- obj._set("width", asW0 * sAxis);
14010
- obj._set("scaleX", 1);
14011
- } else {
14012
- obj._set("height", asH0 * sAxis);
14013
- obj._set("scaleY", 1);
14014
- }
14015
- }
14016
- const childCounterScale = hasRotatedChild ? 1 : 1 / sAxis;
14017
- let restoredNonTextAfterLayout = false;
14018
- const restoreNonTextChildren = (pins) => {
14019
- var _a3, _b3;
14020
- if (!shouldPinNonTextChildren || ((_a3 = groupShiftReflowSnapshotRef.current) == null ? void 0 : _a3.selection) !== obj) return;
14021
- for (const entry of groupShiftReflowSnapshotRef.current.children) {
14022
- const child = entry.obj;
14023
- if (child instanceof fabric.Textbox) continue;
14024
- if (child instanceof fabric.FabricImage || child instanceof fabric.Group && (child.__cropGroup || ((_b3 = child._ct) == null ? void 0 : _b3.isCropGroup))) {
14025
- const pin = pins == null ? void 0 : pins.get(child);
14026
- let targetLeft = hasRotatedChild && isXSide ? entry.left0 * sAxis : entry.left0;
14027
- let targetTop = hasRotatedChild && !isXSide ? entry.top0 * sAxis : entry.top0;
14028
- if (pin == null ? void 0 : pin.worldCenter) {
14029
- try {
14030
- const invSelectionMatrix = fabric.util.invertTransform(obj.calcTransformMatrix());
14031
- const localCenter = fabric.util.transformPoint(pin.worldCenter, invSelectionMatrix);
14032
- targetLeft = localCenter.x;
14033
- targetTop = localCenter.y;
14034
- } catch {
14035
- targetLeft = pin.left ?? targetLeft;
14036
- targetTop = pin.top ?? targetTop;
14037
- }
14038
- } else {
14039
- targetLeft = (pin == null ? void 0 : pin.left) ?? targetLeft;
14040
- targetTop = (pin == null ? void 0 : pin.top) ?? targetTop;
14041
- }
14042
- const beforeRestore = shouldDebugGroupImageResize ? summarizeFabricObjectForResizeDebug(child) : null;
14043
- if (Math.abs((child.left ?? 0) - targetLeft) > 0.01) child._set("left", targetLeft);
14044
- if (Math.abs((child.top ?? 0) - targetTop) > 0.01) child._set("top", targetTop);
14045
- if (isXSide) child._set("scaleX", childCounterScale);
14046
- else child._set("scaleY", childCounterScale);
14047
- child.setCoords();
14048
- child.dirty = true;
14049
- if (shouldDebugGroupImageResize) {
14050
- logGroupImageResizeDebug("restore-non-text", {
14051
- time: Math.round(performance.now()),
14052
- corner,
14053
- childId: getObjectId(child),
14054
- targetLeft,
14055
- targetTop,
14056
- pin,
14057
- before: beforeRestore,
14058
- after: summarizeFabricObjectForResizeDebug(child)
14059
- });
14060
- }
14061
- }
14062
- }
14063
- };
14064
- const projectRotatedTextPosition = (child) => {
14065
- var _a3;
14066
- if (!hasRotatedChild || ((_a3 = groupShiftReflowSnapshotRef.current) == null ? void 0 : _a3.selection) !== obj) return;
14067
- const entry = groupShiftReflowSnapshotRef.current.children.find((candidate) => candidate.obj === child);
14068
- if (!entry) return;
14069
- if (isXSide) child._set("left", entry.left0 * sAxis);
14070
- else child._set("top", entry.top0 * sAxis);
14071
- };
14072
13875
  for (const child of obj.getObjects()) {
14073
- if (child instanceof fabric.Group && (child.__cropGroup || ((_f = child._ct) == null ? void 0 : _f.isCropGroup))) {
14074
- const beforeImageChildResize = shouldDebugGroupImageResize ? summarizeFabricObjectForResizeDebug(child) : null;
13876
+ if (child instanceof fabric.Group && (child.__cropGroup || ((_d = child._ct) == null ? void 0 : _d.isCropGroup))) {
14075
13877
  const ct = child.__cropData;
14076
- if (ct) {
13878
+ if (!ct) continue;
13879
+ if (isXSide) {
14077
13880
  if (child.__asLiveOrigW == null) {
14078
- child.__asLiveOrigW = ct.frameW ?? child.width ?? 1;
14079
- }
14080
- if (child.__asLiveOrigH == null) {
14081
- child.__asLiveOrigH = ct.frameH ?? child.height ?? 1;
13881
+ const baseW = child.width ?? ct.frameW ?? 0;
13882
+ child.__asLiveOrigW = baseW * (child.scaleX ?? 1);
14082
13883
  }
14083
- if (isXSide) {
14084
- const newW = Math.max(1, Number(child.__asLiveOrigW) * sAxis);
13884
+ const origW = child.__asLiveOrigW;
13885
+ const newW = Math.max(20, origW * sAxis);
13886
+ if (Math.abs((child.width ?? 0) - newW) > 0.5) {
14085
13887
  ct.frameW = newW;
14086
13888
  child._set("width", newW);
14087
- } else {
14088
- const newH = Math.max(1, Number(child.__asLiveOrigH) * sAxis);
13889
+ child._set("scaleX", 1 / sAxis);
13890
+ try {
13891
+ updateCoverLayout(child);
13892
+ } catch {
13893
+ }
13894
+ child.setCoords();
13895
+ child.dirty = true;
13896
+ }
13897
+ } else {
13898
+ if (child.__asLiveOrigH == null) {
13899
+ const baseH = child.height ?? ct.frameH ?? 0;
13900
+ child.__asLiveOrigH = baseH * (child.scaleY ?? 1);
13901
+ }
13902
+ const origH = child.__asLiveOrigH;
13903
+ const newH = Math.max(20, origH * sAxis);
13904
+ if (Math.abs((child.height ?? 0) - newH) > 0.5) {
14089
13905
  ct.frameH = newH;
14090
13906
  child._set("height", newH);
13907
+ child._set("scaleY", 1 / sAxis);
13908
+ try {
13909
+ updateCoverLayout(child);
13910
+ } catch {
13911
+ }
13912
+ child.setCoords();
13913
+ child.dirty = true;
14091
13914
  }
14092
- try {
14093
- updateCoverLayout(child);
14094
- } catch {
14095
- }
14096
- }
14097
- if (isXSide) child._set("scaleX", childCounterScale);
14098
- else child._set("scaleY", childCounterScale);
14099
- child.setCoords();
14100
- child.dirty = true;
14101
- if (shouldDebugGroupImageResize) {
14102
- logGroupImageResizeDebug("live-crop-child-resized", {
14103
- time: Math.round(performance.now()),
14104
- corner,
14105
- sAxis,
14106
- childCounterScale,
14107
- before: beforeImageChildResize,
14108
- after: summarizeFabricObjectForResizeDebug(child),
14109
- cropData: ct ? { frameW: ct.frameW, frameH: ct.frameH } : null
14110
- });
14111
13915
  }
14112
- didReflowTextChild = true;
14113
13916
  continue;
14114
13917
  }
14115
13918
  if (child instanceof fabric.FabricImage && !child.__cropGroup && !child.smartElementType) {
14116
- const beforeImageChildResize = shouldDebugGroupImageResize ? summarizeFabricObjectForResizeDebug(child) : null;
14117
13919
  if (isXSide) {
14118
13920
  if (child.__asLiveOrigW == null) {
14119
- child.__asLiveOrigW = (child.width ?? 0) * Math.abs(child.scaleX ?? 1);
13921
+ child.__asLiveOrigW = (child.width ?? 0) * (child.scaleX ?? 1);
13922
+ }
13923
+ const origW = child.__asLiveOrigW;
13924
+ const newW = Math.max(1, origW * sAxis);
13925
+ if (Math.abs((child.width ?? 0) - newW) > 0.5) {
13926
+ child._set("width", newW);
13927
+ child._set("scaleX", 1 / sAxis);
13928
+ child.setCoords();
13929
+ child.dirty = true;
14120
13930
  }
14121
- const newW = Math.max(1, Number(child.__asLiveOrigW) * sAxis);
14122
- child._set("width", newW);
14123
13931
  } else {
14124
13932
  if (child.__asLiveOrigH == null) {
14125
- child.__asLiveOrigH = (child.height ?? 0) * Math.abs(child.scaleY ?? 1);
13933
+ child.__asLiveOrigH = (child.height ?? 0) * (child.scaleY ?? 1);
13934
+ }
13935
+ const origH = child.__asLiveOrigH;
13936
+ const newH = Math.max(1, origH * sAxis);
13937
+ if (Math.abs((child.height ?? 0) - newH) > 0.5) {
13938
+ child._set("height", newH);
13939
+ child._set("scaleY", 1 / sAxis);
13940
+ child.setCoords();
13941
+ child.dirty = true;
14126
13942
  }
14127
- const newH = Math.max(1, Number(child.__asLiveOrigH) * sAxis);
14128
- child._set("height", newH);
14129
- }
14130
- if (isXSide) child._set("scaleX", childCounterScale);
14131
- else child._set("scaleY", childCounterScale);
14132
- child.setCoords();
14133
- child.dirty = true;
14134
- if (shouldDebugGroupImageResize) {
14135
- logGroupImageResizeDebug("live-image-child-resized", {
14136
- time: Math.round(performance.now()),
14137
- corner,
14138
- sAxis,
14139
- childCounterScale,
14140
- liveOrigW: child.__asLiveOrigW,
14141
- liveOrigH: child.__asLiveOrigH,
14142
- before: beforeImageChildResize,
14143
- after: summarizeFabricObjectForResizeDebug(child)
14144
- });
14145
13943
  }
14146
- didReflowTextChild = true;
14147
13944
  continue;
14148
13945
  }
14149
13946
  if (!(child instanceof fabric.Textbox)) continue;
14150
- projectRotatedTextPosition(child);
14151
13947
  if (isXSide) {
14152
13948
  if (child.__asLiveOrigW == null) {
14153
13949
  child.__asLiveOrigW = (child.width ?? 0) * (child.scaleX ?? 1);
@@ -14156,7 +13952,7 @@ const PageCanvas = forwardRef(
14156
13952
  const newW = Math.max(20, origW * sAxis);
14157
13953
  if (Math.abs((child.width ?? 0) - newW) > 0.5) {
14158
13954
  child._set("width", newW);
14159
- child._set("scaleX", childCounterScale);
13955
+ child._set("scaleX", 1 / sAxis);
14160
13956
  try {
14161
13957
  child.initDimensions();
14162
13958
  } catch {
@@ -14169,14 +13965,10 @@ const PageCanvas = forwardRef(
14169
13965
  if (child.__asLiveOrigH == null) {
14170
13966
  child.__asLiveOrigH = (child.height ?? 0) * (child.scaleY ?? 1);
14171
13967
  }
14172
- if (child.__asLiveOrigMinH == null) {
14173
- const m = Number(child.minBoxHeight);
14174
- if (Number.isFinite(m) && m > 0) child.__asLiveOrigMinH = m;
14175
- }
14176
13968
  const origH = child.__asLiveOrigH;
14177
13969
  const newH = Math.max(20, origH * sAxis);
14178
13970
  child.minBoxHeight = newH;
14179
- child._set("scaleY", childCounterScale);
13971
+ child._set("scaleY", 1 / sAxis);
14180
13972
  try {
14181
13973
  child.initDimensions();
14182
13974
  } catch {
@@ -14186,7 +13978,7 @@ const PageCanvas = forwardRef(
14186
13978
  didReflowTextChild = true;
14187
13979
  }
14188
13980
  }
14189
- if (isXSide && !shouldPinNonTextChildren && ((_g = groupShiftReflowSnapshotRef.current) == null ? void 0 : _g.selection) === obj) {
13981
+ if (isXSide && ((_e = groupShiftReflowSnapshotRef.current) == null ? void 0 : _e.selection) === obj) {
14190
13982
  const snap = groupShiftReflowSnapshotRef.current;
14191
13983
  const anchorEntry = snap.children[0];
14192
13984
  const anchorTopLive = anchorEntry.obj.top ?? 0;
@@ -14219,26 +14011,10 @@ const PageCanvas = forwardRef(
14219
14011
  if (cornersBefore) {
14220
14012
  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 };
14221
14013
  }
14222
- const nonTextPinsBeforeLayout = shouldPinNonTextChildren ? new Map(obj.getObjects().map((child) => [child, {
14223
- left: child.left ?? 0,
14224
- top: child.top ?? 0,
14225
- worldCenter: child instanceof fabric.Textbox ? void 0 : child.getCenterPoint()
14226
- }])) : void 0;
14227
14014
  try {
14228
14015
  obj.triggerLayout();
14229
14016
  } catch {
14230
14017
  }
14231
- restoreNonTextChildren(nonTextPinsBeforeLayout);
14232
- restoredNonTextAfterLayout = !!nonTextPinsBeforeLayout;
14233
- if (shouldDebugGroupImageResize) {
14234
- logGroupImageResizeDebug("after-trigger-layout", {
14235
- time: Math.round(performance.now()),
14236
- corner,
14237
- selection: summarizeFabricObjectForResizeDebug(obj),
14238
- nonTextPinsBeforeLayout,
14239
- children: obj.getObjects().map((child) => summarizeFabricObjectForResizeDebug(child))
14240
- });
14241
- }
14242
14018
  obj._set("width", asW0);
14243
14019
  obj._set("scaleX", asSx0);
14244
14020
  obj._set("scaleY", asSy0);
@@ -14264,19 +14040,9 @@ const PageCanvas = forwardRef(
14264
14040
  obj._set("left", asLeft0);
14265
14041
  obj._set("top", asTop0);
14266
14042
  }
14267
- if (!restoredNonTextAfterLayout) restoreNonTextChildren();
14268
14043
  obj._set("width", asW0);
14269
14044
  obj._set("scaleX", asSx0);
14270
14045
  obj._set("scaleY", asSy0);
14271
- if (hasRotatedChild) {
14272
- if (isXSide) {
14273
- obj._set("width", asW0 * sAxis);
14274
- obj._set("scaleX", 1);
14275
- } else {
14276
- obj._set("height", asH0 * sAxis);
14277
- obj._set("scaleY", 1);
14278
- }
14279
- }
14280
14046
  obj.setCoords();
14281
14047
  obj.dirty = true;
14282
14048
  }
@@ -14368,7 +14134,7 @@ const PageCanvas = forwardRef(
14368
14134
  setGuides(gridGuidesForScale.length ? [...scaleGuides, ...gridGuidesForScale] : scaleGuides);
14369
14135
  if (drilledGroupIdRef.current) {
14370
14136
  try {
14371
- (_h = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _h.call(fabricCanvas);
14137
+ (_f = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _f.call(fabricCanvas);
14372
14138
  } catch {
14373
14139
  }
14374
14140
  }
@@ -14459,37 +14225,9 @@ const PageCanvas = forwardRef(
14459
14225
  }
14460
14226
  });
14461
14227
  fabricCanvas.on("object:rotating", (e) => {
14462
- var _a2, _b2;
14463
- prepareGroupSelectionTransformStart(e.target);
14464
14228
  markSimpleTransform(e);
14465
14229
  didTransformRef.current = true;
14466
14230
  const tr = e.target;
14467
- try {
14468
- const children = tr instanceof fabric.Group || tr instanceof fabric.ActiveSelection ? tr.getObjects() : [];
14469
- logGroupImageResizeDebug("rotating-entry", {
14470
- time: Math.round(performance.now()),
14471
- angle: tr == null ? void 0 : tr.angle,
14472
- targetType: tr == null ? void 0 : tr.type,
14473
- targetCtor: (_a2 = tr == null ? void 0 : tr.constructor) == null ? void 0 : _a2.name,
14474
- isActiveSelection: tr instanceof fabric.ActiveSelection,
14475
- isGroup: tr instanceof fabric.Group,
14476
- isCropGroup: !!(tr && (tr.__cropGroup || ((_b2 = tr._ct) == null ? void 0 : _b2.isCropGroup))),
14477
- childCount: children.length,
14478
- childTypes: children.map((c) => c == null ? void 0 : c.type),
14479
- hasImageChild: children.some((c) => isGroupResizeImageLikeObject(c)),
14480
- target: tr ? summarizeFabricObjectForResizeDebug(tr) : null,
14481
- children: children.map((c) => {
14482
- var _a3;
14483
- return {
14484
- type: c == null ? void 0 : c.type,
14485
- ctor: (_a3 = c == null ? void 0 : c.constructor) == null ? void 0 : _a3.name,
14486
- summary: summarizeFabricObjectForResizeDebug(c)
14487
- };
14488
- })
14489
- });
14490
- } catch (err) {
14491
- console.warn("[Pixldocs][group-image-side-resize] rotating-entry log failed", err);
14492
- }
14493
14231
  try {
14494
14232
  const getCursor = fabricCanvas.__pixldocsGetRotateCursor;
14495
14233
  const upper = fabricCanvas.upperCanvasEl;
@@ -14532,7 +14270,7 @@ const PageCanvas = forwardRef(
14532
14270
  setDrilledGroupBounds(null);
14533
14271
  drilledGroupIdRef.current = null;
14534
14272
  if (activeDuringMove instanceof fabric.ActiveSelection && groupIdToKeep) {
14535
- preserveLogicalGroupTagDuringMove(activeDuringMove, groupIdToKeep);
14273
+ restoreGroupSelectionVisualState(activeDuringMove, groupIdToKeep);
14536
14274
  }
14537
14275
  }
14538
14276
  if (e.target) e.target.__pixldocsDragMoved = true;
@@ -14585,7 +14323,7 @@ const PageCanvas = forwardRef(
14585
14323
  });
14586
14324
  let cropGroupSaveTimer = null;
14587
14325
  fabricCanvas.on("object:modified", (e) => {
14588
- var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k;
14326
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i;
14589
14327
  try {
14590
14328
  dragStarted = false;
14591
14329
  setGuides([]);
@@ -14594,43 +14332,18 @@ const PageCanvas = forwardRef(
14594
14332
  groupResizeActiveSnapRef.current = null;
14595
14333
  onDragEnd == null ? void 0 : onDragEnd();
14596
14334
  try {
14597
- const mt = e.target;
14598
- const children = mt instanceof fabric.Group || mt instanceof fabric.ActiveSelection ? mt.getObjects() : [];
14599
- logGroupImageResizeDebug("modified-entry", {
14600
- time: Math.round(performance.now()),
14601
- didTransform: didTransformRef.current,
14602
- targetType: mt == null ? void 0 : mt.type,
14603
- targetCtor: (_a2 = mt == null ? void 0 : mt.constructor) == null ? void 0 : _a2.name,
14604
- isActiveSelection: mt instanceof fabric.ActiveSelection,
14605
- isGroup: mt instanceof fabric.Group,
14606
- angle: mt == null ? void 0 : mt.angle,
14607
- childCount: children.length,
14608
- childTypes: children.map((c) => c == null ? void 0 : c.type),
14609
- hasImageChild: children.some((c) => isGroupResizeImageLikeObject(c)),
14610
- target: mt ? summarizeFabricObjectForResizeDebug(mt) : null,
14611
- children: children.map((c) => {
14612
- var _a3;
14613
- return {
14614
- type: c == null ? void 0 : c.type,
14615
- ctor: (_a3 = c == null ? void 0 : c.constructor) == null ? void 0 : _a3.name,
14616
- summary: summarizeFabricObjectForResizeDebug(c)
14617
- };
14618
- })
14619
- });
14620
- } catch (err) {
14621
- console.warn("[Pixldocs][group-image-side-resize] modified-entry log failed", err);
14622
- }
14623
- const modifiedTarget = e.target;
14624
- if (modifiedTarget instanceof fabric.ActiveSelection && modifiedTarget.getObjects().length === 0) {
14625
- didTransformRef.current = false;
14626
- groupSelectionTransformStartRef.current = null;
14627
- activeSelectionMoveStartRef.current = null;
14628
- activeSelectionResizeHandleRef.current = null;
14629
- unlockEditsSoon();
14630
- return;
14335
+ const t = e.target;
14336
+ if (t instanceof fabric.ActiveSelection) {
14337
+ for (const child of t.getObjects()) {
14338
+ delete child.__asLiveOrigW;
14339
+ delete child.__asLiveOrigH;
14340
+ }
14341
+ }
14342
+ } catch {
14631
14343
  }
14632
14344
  groupShiftReflowSnapshotRef.current = null;
14633
14345
  lockEdits();
14346
+ const modifiedTarget = e.target;
14634
14347
  const modifiedTargetId = modifiedTarget ? getObjectId(modifiedTarget) : null;
14635
14348
  const modifiedTargetElement = modifiedTargetId ? elementsRef.current.find((el) => el.id === modifiedTargetId) : null;
14636
14349
  if (modifiedTarget && (modifiedTargetElement == null ? void 0 : modifiedTargetElement.type) === "shape") {
@@ -14655,7 +14368,7 @@ const PageCanvas = forwardRef(
14655
14368
  const active = fabricCanvas.getActiveObject();
14656
14369
  const activeId = active ? getObjectId(active) : null;
14657
14370
  if (active && activeId && activeId !== "__background__" && !(active instanceof fabric.Group)) {
14658
- const pageChildrenForParent = ((_b2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
14371
+ const pageChildrenForParent = ((_a2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
14659
14372
  const parentGroup = findParentGroup(pageChildrenForParent, activeId);
14660
14373
  if (parentGroup && isGroup(parentGroup) && parentGroup.backgroundColor) {
14661
14374
  let fabricSectionGroup = active.group && active.group instanceof fabric.Group ? active.group : null;
@@ -14737,7 +14450,7 @@ const PageCanvas = forwardRef(
14737
14450
  useEditorStore.getState().reflowStackGroupInPage(pageId, groupId);
14738
14451
  }
14739
14452
  const stateAfter = useEditorStore.getState();
14740
- const pageAfter = ((_c = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _c.children) ?? [];
14453
+ const pageAfter = ((_b2 = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _b2.children) ?? [];
14741
14454
  const groupNodeAfter = findNodeById(pageAfter, groupId);
14742
14455
  if (groupNodeAfter) {
14743
14456
  const abs = getAbsoluteBounds(groupNodeAfter, pageAfter);
@@ -14773,9 +14486,8 @@ const PageCanvas = forwardRef(
14773
14486
  const stateCrop = useEditorStore.getState();
14774
14487
  const pageCrop = stateCrop.canvas.pages.find((p) => p.id === pageId);
14775
14488
  const pageChildrenCrop = (pageCrop == null ? void 0 : pageCrop.children) ?? [];
14776
- const angleRad = (active.angle ?? 0) * Math.PI / 180;
14777
- const absLeft = (active.left ?? 0) - ct.frameW / 2 * Math.cos(angleRad) + ct.frameH / 2 * Math.sin(angleRad);
14778
- const absTop = (active.top ?? 0) - ct.frameW / 2 * Math.sin(angleRad) - ct.frameH / 2 * Math.cos(angleRad);
14489
+ const absLeft = (active.left ?? 0) - ct.frameW / 2;
14490
+ const absTop = (active.top ?? 0) - ct.frameH / 2;
14779
14491
  const storePosCrop = absoluteToStorePosition(absLeft, absTop, objId, pageChildrenCrop);
14780
14492
  updateElement2(objId, {
14781
14493
  width: ct.frameW,
@@ -14800,7 +14512,7 @@ const PageCanvas = forwardRef(
14800
14512
  }
14801
14513
  if (active && active instanceof fabric.Group && active.__docuforgeSectionGroup && getObjectId(active)) {
14802
14514
  const groupId = getObjectId(active);
14803
- const pageChildrenSec = ((_d = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _d.children) ?? [];
14515
+ const pageChildrenSec = ((_c = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _c.children) ?? [];
14804
14516
  const modifiedTarget2 = e == null ? void 0 : e.target;
14805
14517
  const resizeScaleTarget = lastResizeScaleTargetRef.current;
14806
14518
  lastResizeScaleTargetRef.current = null;
@@ -14831,7 +14543,7 @@ const PageCanvas = forwardRef(
14831
14543
  const node = findNodeById(pageChildrenSec, groupId);
14832
14544
  if (isChildModified && node && !groupMoved) {
14833
14545
  const stateAfter = useEditorStore.getState();
14834
- const pageAfter = ((_e = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _e.children) ?? [];
14546
+ const pageAfter = ((_d = stateAfter.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _d.children) ?? [];
14835
14547
  const groupNodeAfter = findNodeById(pageAfter, groupId);
14836
14548
  if (groupNodeAfter) {
14837
14549
  const abs = getAbsoluteBounds(groupNodeAfter, pageAfter);
@@ -14847,7 +14559,7 @@ const PageCanvas = forwardRef(
14847
14559
  }
14848
14560
  if (active && active instanceof fabric.Group && !(active instanceof fabric.ActiveSelection) && getObjectId(active)) {
14849
14561
  const groupId = getObjectId(active);
14850
- const pageChildren3 = ((_f = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _f.children) ?? [];
14562
+ const pageChildren3 = ((_e = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _e.children) ?? [];
14851
14563
  const w = (active.width ?? 0) * (active.scaleX ?? 1);
14852
14564
  const h = (active.height ?? 0) * (active.scaleY ?? 1);
14853
14565
  const centerX = active.left ?? 0;
@@ -14869,7 +14581,7 @@ const PageCanvas = forwardRef(
14869
14581
  }
14870
14582
  const activeObj = fabricCanvas.getActiveObject();
14871
14583
  let activeObjects = fabricCanvas.getActiveObjects();
14872
- const activeSelectionMoveStart = activeObj instanceof fabric.ActiveSelection && ((_g = activeSelectionMoveStartRef.current) == null ? void 0 : _g.selection) === activeObj ? activeSelectionMoveStartRef.current : null;
14584
+ const activeSelectionMoveStart = activeObj instanceof fabric.ActiveSelection && ((_f = activeSelectionMoveStartRef.current) == null ? void 0 : _f.selection) === activeObj ? activeSelectionMoveStartRef.current : null;
14873
14585
  const activeSelectionDelta = activeObj instanceof fabric.ActiveSelection && activeSelectionMoveStart ? (() => {
14874
14586
  const rect = activeObj.getBoundingRect();
14875
14587
  return {
@@ -14886,18 +14598,6 @@ const PageCanvas = forwardRef(
14886
14598
  const isActiveSelection = activeObj instanceof fabric.ActiveSelection || activeObjects.length > 1;
14887
14599
  const activeSelectionResizeHandle = isActiveSelection ? activeSelectionResizeHandleRef.current : null;
14888
14600
  const debugGroupTextCornerResize = activeObj instanceof fabric.ActiveSelection && isCornerResizeHandle(activeSelectionResizeHandle) && activeObjects.some((candidate) => candidate instanceof fabric.Textbox);
14889
- const debugGroupImageSideResize = activeObj instanceof fabric.ActiveSelection && (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb") && activeObjects.some((candidate) => isGroupResizeImageLikeObject(candidate));
14890
- if (debugGroupImageSideResize) {
14891
- logGroupImageResizeDebug("modified-start", {
14892
- time: Math.round(performance.now()),
14893
- handle: activeSelectionResizeHandle,
14894
- target: summarizeFabricObjectForResizeDebug(modifiedTarget),
14895
- selection: summarizeFabricObjectForResizeDebug(activeObj),
14896
- activeObjectIds: activeObjects.map((candidate) => getObjectId(candidate)),
14897
- selectedStoreIds: useEditorStore.getState().canvas.selectedIds,
14898
- members: activeObjects.map((candidate) => summarizeFabricObjectForResizeDebug(candidate))
14899
- });
14900
- }
14901
14601
  if (debugGroupTextCornerResize) {
14902
14602
  logGroupTextResizeDebug("modified-start", {
14903
14603
  time: Math.round(performance.now()),
@@ -14930,14 +14630,7 @@ const PageCanvas = forwardRef(
14930
14630
  const node = findNodeById(pageChildren2, id);
14931
14631
  return !!(node && isGroup(node));
14932
14632
  });
14933
- const activeSelectionHadTransform = activeObj instanceof fabric.ActiveSelection && (Math.abs((activeObj.scaleX ?? 1) - 1) > 0.01 || Math.abs((activeObj.scaleY ?? 1) - 1) > 0.01 || (() => {
14934
- var _a3;
14935
- const normAngle = (angle) => (angle % 360 + 360) % 360;
14936
- const startAngle = ((_a3 = groupSelectionTransformStartRef.current) == null ? void 0 : _a3.selection) === activeObj ? groupSelectionTransformStartRef.current.selectionAngle : 0;
14937
- const currentAngle = normAngle(activeObj.angle ?? 0);
14938
- const diff = Math.abs(currentAngle - normAngle(startAngle));
14939
- return Math.min(diff, 360 - diff) > 1;
14940
- })());
14633
+ const activeSelectionHadTransform = activeObj instanceof fabric.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);
14941
14634
  if (!anyCropGroup && activeSelectionDelta && !activeSelectionHadTransform && selectedLogicalGroupIds.length > 0) {
14942
14635
  const selectedStoreIds = useEditorStore.getState().canvas.selectedIds ?? [];
14943
14636
  const groupMemberIds = /* @__PURE__ */ new Set();
@@ -14978,13 +14671,7 @@ const PageCanvas = forwardRef(
14978
14671
  return;
14979
14672
  }
14980
14673
  }
14981
- const isActiveSelectionSideResize = isActiveSelection && (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb");
14982
- const normalizeAngle = (angle) => (angle % 360 + 360) % 360;
14983
- const shortestAngleDelta = (a, b) => {
14984
- const diff = Math.abs(normalizeAngle(a) - normalizeAngle(b));
14985
- return Math.min(diff, 360 - diff);
14986
- };
14987
- if (selectedElementIds.length > 0) {
14674
+ if (selectedElementIds.length > 0 && !anyCropGroup) {
14988
14675
  const firstObj = activeObjects[0];
14989
14676
  const firstId = getObjectId(firstObj);
14990
14677
  const parentGroups = selectedElementIds.map((id) => findParentGroup(pageChildren2, id)).filter((g) => g !== null);
@@ -15007,9 +14694,9 @@ const PageCanvas = forwardRef(
15007
14694
  let movedGroupLeft = groupAbs.left;
15008
14695
  let movedGroupTop = groupAbs.top;
15009
14696
  if (activeObj instanceof fabric.ActiveSelection && (transformStart == null ? void 0 : transformStart.groupId) === groupToMove.id) {
15010
- const selectionCenter = activeObj.getCenterPoint();
15011
- movedGroupLeft = transformStart.groupLeft + (selectionCenter.x - transformStart.selectionCenterX);
15012
- movedGroupTop = transformStart.groupTop + (selectionCenter.y - transformStart.selectionCenterY);
14697
+ const selectionRect = activeObj.getBoundingRect();
14698
+ movedGroupLeft = transformStart.groupLeft + (selectionRect.left - transformStart.selectionLeft);
14699
+ movedGroupTop = transformStart.groupTop + (selectionRect.top - transformStart.selectionTop);
15013
14700
  } else if (activeObj instanceof fabric.ActiveSelection && firstId && firstObj) {
15014
14701
  const firstNode = findNodeById(pageChildren2, firstId);
15015
14702
  if (firstNode) {
@@ -15045,58 +14732,19 @@ const PageCanvas = forwardRef(
15045
14732
  }
15046
14733
  const deltaX = movedGroupLeft - groupAbs.left;
15047
14734
  const deltaY = movedGroupTop - groupAbs.top;
15048
- const hadResizeHandle = isActiveSelection && !!activeSelectionResizeHandle;
15049
- const hadScale = isActiveSelection && activeObj && (hadResizeHandle || Math.abs((activeObj.scaleX ?? 1) - 1) > 0.01 || Math.abs((activeObj.scaleY ?? 1) - 1) > 0.01);
15050
- const startSelAngle = normalizeAngle((transformStart == null ? void 0 : transformStart.selectionAngle) ?? 0);
15051
- const currentSelAngle = isActiveSelection && activeObj ? normalizeAngle(activeObj.angle ?? 0) : 0;
15052
- const storedGroupAngle = normalizeAngle(Number(groupToMove.angle ?? 0));
15053
- const effectiveStartAngle = transformStart ? startSelAngle : storedGroupAngle;
15054
- const angleDelta = shortestAngleDelta(currentSelAngle, effectiveStartAngle);
15055
- const hadRotation = isActiveSelection && activeObj && angleDelta > 1;
15056
- if (activeGroupSelectionId === groupToMove.id && hadRotation && !hadScale && !activeSelectionResizeHandle && activeObj instanceof fabric.ActiveSelection) {
15057
- const { updateNode: updateNodeStore, commitHistory: commitHistoryStore, getCurrentElements } = useEditorStore.getState();
15058
- const center = activeObj.getCenterPoint();
15059
- const baseCenterX = (transformStart == null ? void 0 : transformStart.selectionCenterX) ?? groupAbs.left + groupAbs.width / 2;
15060
- const baseCenterY = (transformStart == null ? void 0 : transformStart.selectionCenterY) ?? groupAbs.top + groupAbs.height / 2;
15061
- const nextAbsLeft = groupAbs.left + (center.x - baseCenterX);
15062
- const nextAbsTop = groupAbs.top + (center.y - baseCenterY);
15063
- const storePos = absoluteToStorePosition(nextAbsLeft, nextAbsTop, groupToMove.id, pageChildren2);
15064
- updateNodeStore(groupToMove.id, {
15065
- left: storePos.left,
15066
- top: storePos.top,
15067
- angle: currentSelAngle
15068
- }, { recordHistory: false, skipLayoutRecalc: true });
15069
- commitHistoryStore();
15070
- restoreGroupSelectionVisualState(activeObj, groupToMove.id);
15071
- fabricCanvas.setActiveObject(activeObj);
15072
- activeObj.setCoords();
15073
- selectElements([groupToMove.id], false, false);
15074
- fabricCanvas.requestRenderAll();
15075
- elementsRef.current = getCurrentElements();
15076
- const restoreSnapshot = {
15077
- memberIds: activeObj.getObjects().map((obj) => getObjectId(obj)).filter((id) => !!id && id !== "__background__"),
15078
- groupSelectionId: groupToMove.id,
15079
- expiresAt: Date.now() + 1200
15080
- };
15081
- recentGroupSelectionRestoreRef.current = restoreSnapshot;
15082
- activeObj.getObjects().forEach((obj) => {
15083
- const objId = getObjectId(obj);
15084
- if (objId && objId !== "__background__") {
15085
- justModifiedIdsRef.current.add(objId);
15086
- modifiedIdsThisRound.add(objId);
15087
- }
15088
- });
15089
- setTimeout(() => modifiedIdsThisRound.forEach((id) => justModifiedIdsRef.current.delete(id)), 150);
15090
- groupSelectionTransformStartRef.current = null;
15091
- activeSelectionMoveStartRef.current = null;
15092
- activeSelectionResizeHandleRef.current = null;
15093
- unlockEditsSoon();
15094
- return;
15095
- }
15096
- if (!isActiveSelectionSideResize && !hadScale && !hadRotation && (Math.abs(deltaX) > 0.1 || Math.abs(deltaY) > 0.1)) {
14735
+ const hadScale = isActiveSelection && activeObj && (Math.abs((activeObj.scaleX ?? 1) - 1) > 0.01 || Math.abs((activeObj.scaleY ?? 1) - 1) > 0.01);
14736
+ const startSelAngle = (((transformStart == null ? void 0 : transformStart.selectionAngle) ?? 0) % 360 + 360) % 360;
14737
+ const currentSelAngle = isActiveSelection && activeObj ? ((activeObj.angle ?? 0) % 360 + 360) % 360 : 0;
14738
+ const angleDelta = Math.min(
14739
+ Math.abs(currentSelAngle - startSelAngle),
14740
+ 360 - Math.abs(currentSelAngle - startSelAngle)
14741
+ );
14742
+ const hadRotation = isActiveSelection && activeObj && angleDelta > 0.01;
14743
+ if (!hadScale && !hadRotation && (Math.abs(deltaX) > 0.1 || Math.abs(deltaY) > 0.1)) {
15097
14744
  const { updateNode: updateNodeStore, commitHistory: commitHistoryStore, getCurrentElements } = useEditorStore.getState();
15098
- const storePos = absoluteToStorePosition(movedGroupLeft, movedGroupTop, groupToMove.id, pageChildren2);
15099
- updateNodeStore(groupToMove.id, { left: storePos.left, top: storePos.top }, { recordHistory: false, skipLayoutRecalc: true });
14745
+ const newLeft = (groupToMove.left ?? 0) + deltaX;
14746
+ const newTop = (groupToMove.top ?? 0) + deltaY;
14747
+ updateNodeStore(groupToMove.id, { left: newLeft, top: newTop }, { recordHistory: false, skipLayoutRecalc: true });
15100
14748
  commitHistoryStore();
15101
14749
  pendingGroupDrillInRef.current = null;
15102
14750
  fabricCanvas.__activeEditingGroupId = null;
@@ -15121,8 +14769,6 @@ const PageCanvas = forwardRef(
15121
14769
  }
15122
14770
  setTimeout(() => modifiedIdsThisRound.forEach((id) => justModifiedIdsRef.current.delete(id)), 150);
15123
14771
  groupSelectionTransformStartRef.current = null;
15124
- activeSelectionMoveStartRef.current = null;
15125
- activeSelectionResizeHandleRef.current = null;
15126
14772
  const restoreSnapshot = {
15127
14773
  memberIds: targetObjects.map((obj) => getObjectId(obj)).filter((id) => !!id && id !== "__background__"),
15128
14774
  groupSelectionId,
@@ -15136,38 +14782,6 @@ const PageCanvas = forwardRef(
15136
14782
  }
15137
14783
  }
15138
14784
  const pendingCropGroupFrameBakes = [];
15139
- const logicalGroupSelectionId = activeObj instanceof fabric.ActiveSelection ? activeObj.__pixldocsGroupSelection : void 0;
15140
- const isLogicalGroupAS = !!logicalGroupSelectionId && !(activeObj == null ? void 0 : activeObj.__cropGroup) && !(activeObj == null ? void 0 : activeObj.__docuforgeSectionGroup);
15141
- const logicalGroupNodeForBake = logicalGroupSelectionId ? findNodeById(pageChildren2, logicalGroupSelectionId) : null;
15142
- const asAngleForBake = isLogicalGroupAS && activeObj ? normalizeAngle(Number(activeObj.angle ?? 0)) : 0;
15143
- const logicalGroupFinalFrame = (() => {
15144
- var _a3;
15145
- if (!isLogicalGroupAS || !logicalGroupSelectionId || !(activeObj instanceof fabric.ActiveSelection)) return null;
15146
- const baseline = ((_a3 = groupSelectionTransformStartRef.current) == null ? void 0 : _a3.groupId) === logicalGroupSelectionId ? groupSelectionTransformStartRef.current : null;
15147
- const localWidth = Math.max(1, (activeObj.width ?? (baseline == null ? void 0 : baseline.groupWidth) ?? 1) * Math.abs(activeObj.scaleX ?? 1));
15148
- const localHeight = Math.max(1, (activeObj.height ?? (baseline == null ? void 0 : baseline.groupHeight) ?? 1) * Math.abs(activeObj.scaleY ?? 1));
15149
- const center = activeObj.getCenterPoint();
15150
- const topLeft = centerToRotatedTopLeft(center.x, center.y, localWidth, localHeight, asAngleForBake);
15151
- return {
15152
- groupId: logicalGroupSelectionId,
15153
- left: topLeft.left,
15154
- top: topLeft.top,
15155
- width: localWidth,
15156
- height: localHeight,
15157
- centerX: center.x,
15158
- centerY: center.y,
15159
- angle: asAngleForBake,
15160
- matrix: fabric.util.composeMatrix({
15161
- translateX: center.x,
15162
- translateY: center.y,
15163
- angle: asAngleForBake,
15164
- scaleX: 1,
15165
- scaleY: 1,
15166
- skewX: 0,
15167
- skewY: 0
15168
- })
15169
- };
15170
- })();
15171
14785
  for (const obj of activeObjects) {
15172
14786
  const objId = getObjectId(obj);
15173
14787
  if (!objId || objId === "__background__") continue;
@@ -15213,15 +14827,16 @@ const PageCanvas = forwardRef(
15213
14827
  modifiedIdsThisRound.add(objId);
15214
14828
  let absoluteLeft;
15215
14829
  let absoluteTop;
15216
- const initialTopLeft = centerToRotatedTopLeft(
15217
- decomposed.translateX ?? (obj.left ?? 0),
15218
- decomposed.translateY ?? (obj.top ?? 0),
15219
- intrinsicWidth * Math.abs(decomposed.scaleX || 1),
15220
- intrinsicHeight * Math.abs(decomposed.scaleY || 1),
15221
- decomposed.angle ?? 0
15222
- );
15223
- absoluteLeft = initialTopLeft.left;
15224
- absoluteTop = initialTopLeft.top;
14830
+ if (isActiveSelection && activeObj) {
14831
+ const selectionMatrix = activeObj.calcTransformMatrix();
14832
+ const relativePoint = { x: obj.left ?? 0, y: obj.top ?? 0 };
14833
+ const absolutePoint = fabric.util.transformPoint(relativePoint, selectionMatrix);
14834
+ absoluteLeft = absolutePoint.x;
14835
+ absoluteTop = absolutePoint.y;
14836
+ } else {
14837
+ absoluteLeft = obj.left ?? 0;
14838
+ absoluteTop = obj.top ?? 0;
14839
+ }
15225
14840
  if (obj instanceof fabric.Group && obj.__cropGroup) {
15226
14841
  const ct = obj.__cropData;
15227
14842
  if (isActiveSelection && activeObj instanceof fabric.ActiveSelection) {
@@ -15231,22 +14846,14 @@ const PageCanvas = forwardRef(
15231
14846
  } else {
15232
14847
  const w = ((ct == null ? void 0 : ct.frameW) ?? obj.width ?? 0) * Math.abs(obj.scaleX ?? 1);
15233
14848
  const h = ((ct == null ? void 0 : ct.frameH) ?? obj.height ?? 0) * Math.abs(obj.scaleY ?? 1);
15234
- const angleRad = (decomposed.angle ?? obj.angle ?? 0) * Math.PI / 180;
15235
- absoluteLeft = (decomposed.translateX ?? absoluteLeft ?? 0) - w / 2 * Math.cos(angleRad) + h / 2 * Math.sin(angleRad);
15236
- absoluteTop = (decomposed.translateY ?? absoluteTop ?? 0) - w / 2 * Math.sin(angleRad) - h / 2 * Math.cos(angleRad);
14849
+ absoluteLeft = (absoluteLeft ?? 0) - w / 2;
14850
+ absoluteTop = (absoluteTop ?? 0) - h / 2;
15237
14851
  }
15238
14852
  } else if (obj instanceof fabric.FabricImage && (obj.originX === "center" || obj.originY === "center")) {
15239
- if (isActiveSelection && activeObj instanceof fabric.ActiveSelection) {
15240
- const frameBounds = getObjectFrameBoundsInSelection(activeObj, obj, obj.width ?? 0, obj.height ?? 0);
15241
- absoluteLeft = frameBounds.left;
15242
- absoluteTop = frameBounds.top;
15243
- } else {
15244
- const w = (obj.width ?? 0) * (obj.scaleX ?? 1);
15245
- const h = (obj.height ?? 0) * (obj.scaleY ?? 1);
15246
- const angleRad = (decomposed.angle ?? obj.angle ?? 0) * Math.PI / 180;
15247
- absoluteLeft = (decomposed.translateX ?? absoluteLeft ?? 0) - w / 2 * Math.cos(angleRad) + h / 2 * Math.sin(angleRad);
15248
- absoluteTop = (decomposed.translateY ?? absoluteTop ?? 0) - w / 2 * Math.sin(angleRad) - h / 2 * Math.cos(angleRad);
15249
- }
14853
+ const w = (obj.width ?? 0) * (obj.scaleX ?? 1);
14854
+ const h = (obj.height ?? 0) * (obj.scaleY ?? 1);
14855
+ absoluteLeft = (absoluteLeft ?? 0) - w / 2;
14856
+ absoluteTop = (absoluteTop ?? 0) - h / 2;
15250
14857
  }
15251
14858
  const preserveCornerGeometry = (sourceElement == null ? void 0 : sourceElement.type) === "shape" && (sourceElement.shapeType === "circle" || sourceElement.shapeType === "rounded-rect" || sourceElement.shapeType === "triangle");
15252
14859
  let finalWidth = intrinsicWidth;
@@ -15254,10 +14861,6 @@ const PageCanvas = forwardRef(
15254
14861
  let finalScaleX = decomposed.scaleX;
15255
14862
  let finalScaleY = decomposed.scaleY;
15256
14863
  let finalAbsoluteMatrix = absoluteMatrix;
15257
- let finalAngle = decomposed.angle;
15258
- let finalSkewX = decomposed.skewX;
15259
- let finalSkewY = decomposed.skewY;
15260
- let finalAngleFromDecomposed = true;
15261
14864
  if (obj instanceof fabric.Group && obj.__cropGroup) {
15262
14865
  const ct = obj.__cropData;
15263
14866
  if (ct) {
@@ -15274,14 +14877,12 @@ const PageCanvas = forwardRef(
15274
14877
  absoluteLeft = frameBounds.left;
15275
14878
  absoluteTop = frameBounds.top;
15276
14879
  } else {
15277
- const angleRad = (decomposed.angle ?? obj.angle ?? 0) * Math.PI / 180;
15278
- absoluteLeft = (decomposed.translateX ?? absoluteLeft) - finalWidth / 2 * Math.cos(angleRad) + finalHeight / 2 * Math.sin(angleRad);
15279
- absoluteTop = (decomposed.translateY ?? absoluteTop) - finalWidth / 2 * Math.sin(angleRad) - finalHeight / 2 * Math.cos(angleRad);
14880
+ absoluteLeft = (decomposed.translateX ?? absoluteLeft) - finalWidth / 2;
14881
+ absoluteTop = (decomposed.translateY ?? absoluteTop) - finalHeight / 2;
15280
14882
  }
15281
- const finalCenter = rotatedTopLeftToCenter(absoluteLeft, absoluteTop, finalWidth, finalHeight, decomposed.angle ?? (obj.angle ?? 0));
15282
14883
  finalAbsoluteMatrix = fabric.util.composeMatrix({
15283
- translateX: finalCenter.x,
15284
- translateY: finalCenter.y,
14884
+ translateX: absoluteLeft + finalWidth / 2,
14885
+ translateY: absoluteTop + finalHeight / 2,
15285
14886
  angle: decomposed.angle ?? (obj.angle ?? 0),
15286
14887
  scaleX: 1,
15287
14888
  scaleY: 1,
@@ -15316,12 +14917,6 @@ const PageCanvas = forwardRef(
15316
14917
  finalHeight = bakedH;
15317
14918
  finalScaleX = 1;
15318
14919
  finalScaleY = 1;
15319
- if (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb") {
15320
- finalAngle = (sourceElement == null ? void 0 : sourceElement.angle) ?? obj.angle ?? decomposed.angle;
15321
- finalSkewX = (sourceElement == null ? void 0 : sourceElement.skewX) ?? obj.skewX ?? 0;
15322
- finalSkewY = (sourceElement == null ? void 0 : sourceElement.skewY) ?? obj.skewY ?? 0;
15323
- if ((sourceElement == null ? void 0 : sourceElement.angle) !== void 0 || obj.angle !== void 0) finalAngleFromDecomposed = false;
15324
- }
15325
14920
  obj.set({ scaleX: 1, scaleY: 1 });
15326
14921
  const newSrc = renderSmartElementToDataUri(sourceElement.smartElementType, sourceElement.smartProps, bakedW, bakedH);
15327
14922
  if (newSrc) {
@@ -15337,7 +14932,6 @@ const PageCanvas = forwardRef(
15337
14932
  useEditorStore.getState().updateElement(objId, { src: newSrc }, { recordHistory: false, skipLayoutRecalc: true });
15338
14933
  }
15339
14934
  } else if (isActiveSelection && (Math.abs((decomposed.scaleX ?? 1) - 1) > 1e-3 || Math.abs((decomposed.scaleY ?? 1) - 1) > 1e-3)) {
15340
- const debugImageBeforeBake = debugGroupImageSideResize ? summarizeFabricObjectForResizeDebug(obj) : null;
15341
14935
  const sx = Math.abs(decomposed.scaleX || 1);
15342
14936
  const sy = Math.abs(decomposed.scaleY || 1);
15343
14937
  const handle = activeSelectionResizeHandle;
@@ -15371,9 +14965,22 @@ const PageCanvas = forwardRef(
15371
14965
  const localScaleX = 1 / sx;
15372
14966
  const localScaleY = 1 / sy;
15373
14967
  obj.set({ scaleX: localScaleX, scaleY: localScaleY });
15374
- const selectionMatrix = (_h = activeObj == null ? void 0 : activeObj.calcTransformMatrix) == null ? void 0 : _h.call(activeObj);
14968
+ const selectionMatrix = (_g = activeObj == null ? void 0 : activeObj.calcTransformMatrix) == null ? void 0 : _g.call(activeObj);
15375
14969
  const localCenter = selectionMatrix ? fabric.util.transformPoint(preBakeCenter, fabric.util.invertTransform(selectionMatrix)) : preBakeCenter;
15376
- obj.setPositionByOrigin(localCenter, "center", "center");
14970
+ const localWidth = bakedW * localScaleX;
14971
+ const localHeight = bakedH * localScaleY;
14972
+ const isCenterOrigin = obj.originX === "center" || obj.originY === "center";
14973
+ if (isCenterOrigin) {
14974
+ obj.set({
14975
+ left: localCenter.x,
14976
+ top: localCenter.y
14977
+ });
14978
+ } else {
14979
+ obj.set({
14980
+ left: localCenter.x - localWidth / 2,
14981
+ top: localCenter.y - localHeight / 2
14982
+ });
14983
+ }
15377
14984
  }
15378
14985
  obj.dirty = true;
15379
14986
  if (activeObj) activeObj.dirty = true;
@@ -15384,63 +14991,34 @@ const PageCanvas = forwardRef(
15384
14991
  finalHeight = bakedH;
15385
14992
  finalScaleX = 1;
15386
14993
  finalScaleY = 1;
15387
- if (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb") {
15388
- finalAngle = (sourceElement == null ? void 0 : sourceElement.angle) ?? obj.angle ?? decomposed.angle;
15389
- finalSkewX = (sourceElement == null ? void 0 : sourceElement.skewX) ?? obj.skewX ?? 0;
15390
- finalSkewY = (sourceElement == null ? void 0 : sourceElement.skewY) ?? obj.skewY ?? 0;
15391
- if ((sourceElement == null ? void 0 : sourceElement.angle) !== void 0 || obj.angle !== void 0) finalAngleFromDecomposed = false;
15392
- }
15393
14994
  try {
15394
- const angleRad = (finalAngle ?? 0) * Math.PI / 180;
14995
+ const angleRad = (decomposed.angle ?? 0) * Math.PI / 180;
15395
14996
  const cos = Math.cos(angleRad);
15396
14997
  const sin = Math.sin(angleRad);
15397
14998
  const hw = finalWidth / 2;
15398
14999
  const hh = finalHeight / 2;
15399
- absoluteLeft = decomposed.translateX - hw * cos + hh * sin;
15400
- absoluteTop = decomposed.translateY - hw * sin - hh * cos;
15000
+ const corners = [
15001
+ { x: -hw, y: -hh },
15002
+ { x: hw, y: -hh },
15003
+ { x: hw, y: hh },
15004
+ { x: -hw, y: hh }
15005
+ ].map((p) => ({
15006
+ x: decomposed.translateX + p.x * cos - p.y * sin,
15007
+ y: decomposed.translateY + p.x * sin + p.y * cos
15008
+ }));
15009
+ absoluteLeft = Math.min(...corners.map((p) => p.x));
15010
+ absoluteTop = Math.min(...corners.map((p) => p.y));
15401
15011
  } catch {
15402
15012
  }
15403
15013
  finalAbsoluteMatrix = fabric.util.composeMatrix({
15404
15014
  translateX: decomposed.translateX,
15405
15015
  translateY: decomposed.translateY,
15406
- angle: finalAngle ?? 0,
15016
+ angle: decomposed.angle ?? 0,
15407
15017
  scaleX: 1,
15408
15018
  scaleY: 1,
15409
- skewX: finalSkewX ?? 0,
15410
- skewY: finalSkewY ?? 0
15019
+ skewX: 0,
15020
+ skewY: 0
15411
15021
  });
15412
- if (debugGroupImageSideResize) {
15413
- logGroupImageResizeDebug("image-bake", {
15414
- time: Math.round(performance.now()),
15415
- handle: activeSelectionResizeHandle,
15416
- imageId: objId,
15417
- source: sourceElement ? {
15418
- left: sourceElement.left,
15419
- top: sourceElement.top,
15420
- width: sourceElement.width,
15421
- height: sourceElement.height,
15422
- angle: sourceElement.angle,
15423
- scaleX: sourceElement.scaleX,
15424
- scaleY: sourceElement.scaleY
15425
- } : null,
15426
- factors: { sx, sy, fx, fy, isCornerHandle },
15427
- beforeBake: debugImageBeforeBake,
15428
- afterBake: summarizeFabricObjectForResizeDebug(obj),
15429
- persistedGeometry: {
15430
- absoluteLeft,
15431
- absoluteTop,
15432
- finalWidth,
15433
- finalHeight,
15434
- finalScaleX,
15435
- finalScaleY,
15436
- finalAngle,
15437
- finalSkewX,
15438
- finalSkewY,
15439
- decomposed,
15440
- finalAbsoluteMatrix
15441
- }
15442
- });
15443
- }
15444
15022
  } else {
15445
15023
  finalWidth = intrinsicWidth;
15446
15024
  finalHeight = intrinsicHeight;
@@ -15450,33 +15028,16 @@ const PageCanvas = forwardRef(
15450
15028
  finalHeight = 0;
15451
15029
  finalScaleX = 1;
15452
15030
  finalScaleY = 1;
15453
- if (activeSelectionResizeHandle === "ml" || activeSelectionResizeHandle === "mr" || activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb") {
15454
- finalAngle = (sourceElement == null ? void 0 : sourceElement.angle) ?? obj.angle ?? decomposed.angle;
15455
- finalSkewX = (sourceElement == null ? void 0 : sourceElement.skewX) ?? obj.skewX ?? 0;
15456
- finalSkewY = (sourceElement == null ? void 0 : sourceElement.skewY) ?? obj.skewY ?? 0;
15457
- if ((sourceElement == null ? void 0 : sourceElement.angle) !== void 0 || obj.angle !== void 0) finalAngleFromDecomposed = false;
15458
- }
15459
- } else if (obj instanceof fabric.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)) {
15460
- const liveOrigW = obj.__asLiveOrigW;
15461
- const liveOrigH = obj.__asLiveOrigH;
15462
- const decSx = Math.abs(decomposed.scaleX || 1);
15463
- const decSy = Math.abs(decomposed.scaleY || 1);
15464
- const sx = Math.abs(decSx - 1) < 1e-3 && liveOrigW && liveOrigW > 0 ? Math.max(1e-3, (obj.width ?? liveOrigW) / liveOrigW) : decSx;
15465
- const baseHForRecover = Number(
15466
- obj.minBoxHeight ?? obj.height ?? liveOrigH ?? 1
15467
- );
15468
- const sy = Math.abs(decSy - 1) < 1e-3 && liveOrigH && liveOrigH > 0 ? Math.max(1e-3, baseHForRecover / liveOrigH) : decSy;
15031
+ } else if (obj instanceof fabric.Textbox && isActiveSelection && (Math.abs((decomposed.scaleX ?? 1) - 1) > 1e-3 || Math.abs((decomposed.scaleY ?? 1) - 1) > 1e-3)) {
15032
+ const sx = Math.abs(decomposed.scaleX || 1);
15033
+ const sy = Math.abs(decomposed.scaleY || 1);
15469
15034
  const isLikelyUniformCorner = !activeSelectionResizeHandle && Math.abs(sx - sy) < 0.01 && Math.abs(sx - 1) > 1e-3;
15470
15035
  const isCornerHandle = activeSelectionResizeHandle === "tl" || activeSelectionResizeHandle === "tr" || activeSelectionResizeHandle === "bl" || activeSelectionResizeHandle === "br" || isLikelyUniformCorner;
15471
15036
  const isHeightSideHandle = activeSelectionResizeHandle === "mt" || activeSelectionResizeHandle === "mb";
15472
15037
  const fontScale = isCornerHandle ? Math.max(1e-3, Math.sqrt(sx * sy)) : 1;
15473
- const widthBase = liveOrigW && liveOrigW > 0 ? liveOrigW : intrinsicWidth;
15474
- const heightBase = liveOrigH && liveOrigH > 0 ? liveOrigH : intrinsicHeight;
15475
- const bakedWidth = Math.max(20, widthBase * sx);
15476
- const liveMinHOrig = obj.__asLiveOrigMinH;
15477
- const currentMinH = Number(obj.minBoxHeight ?? (sourceElement == null ? void 0 : sourceElement.minBoxHeight));
15478
- const minHBase = Number.isFinite(liveMinHOrig) && liveMinHOrig > 0 ? liveMinHOrig : liveOrigH && liveOrigH > 0 ? currentMinH / sy : currentMinH;
15479
- const nextMinH = Number.isFinite(minHBase) && minHBase > 0 ? minHBase * sy : isHeightSideHandle ? Math.max(1, heightBase * sy) : void 0;
15038
+ const bakedWidth = Math.max(20, intrinsicWidth * sx);
15039
+ const baseMinH = Number(obj.minBoxHeight ?? (sourceElement == null ? void 0 : sourceElement.minBoxHeight));
15040
+ const nextMinH = Number.isFinite(baseMinH) && baseMinH > 0 ? baseMinH * sy : isHeightSideHandle ? Math.max(1, intrinsicHeight * sy) : void 0;
15480
15041
  const bakedTextScaleUpdates = { width: bakedWidth };
15481
15042
  const debugTextBeforeBake = debugGroupTextCornerResize ? summarizeFabricObjectForResizeDebug(obj) : null;
15482
15043
  finalScaleX = 1;
@@ -15535,9 +15096,14 @@ const PageCanvas = forwardRef(
15535
15096
  const localScaleX = 1 / sx;
15536
15097
  const localScaleY = 1 / sy;
15537
15098
  obj.set({ scaleX: localScaleX, scaleY: localScaleY });
15538
- const selectionMatrix = (_i = activeObj == null ? void 0 : activeObj.calcTransformMatrix) == null ? void 0 : _i.call(activeObj);
15099
+ const selectionMatrix = (_h = activeObj == null ? void 0 : activeObj.calcTransformMatrix) == null ? void 0 : _h.call(activeObj);
15539
15100
  const localCenter = selectionMatrix ? fabric.util.transformPoint(preBakeCenter, fabric.util.invertTransform(selectionMatrix)) : preBakeCenter;
15540
- obj.setPositionByOrigin(localCenter, "center", "center");
15101
+ const localWidth = bakedWidth * localScaleX;
15102
+ const localHeight = (obj.height ?? intrinsicHeight) * localScaleY;
15103
+ obj.set({
15104
+ left: localCenter.x - localWidth / 2,
15105
+ top: localCenter.y - localHeight / 2
15106
+ });
15541
15107
  } else {
15542
15108
  obj.setPositionByOrigin(preBakeCenter, "center", "center");
15543
15109
  }
@@ -15550,23 +15116,32 @@ const PageCanvas = forwardRef(
15550
15116
  } catch {
15551
15117
  }
15552
15118
  try {
15553
- const angleRad = (finalAngle ?? 0) * Math.PI / 180;
15119
+ const angleRad = (decomposed.angle ?? 0) * Math.PI / 180;
15554
15120
  const cos = Math.cos(angleRad);
15555
15121
  const sin = Math.sin(angleRad);
15556
15122
  const hw = finalWidth / 2;
15557
15123
  const hh = finalHeight / 2;
15558
- absoluteLeft = decomposed.translateX - hw * cos + hh * sin;
15559
- absoluteTop = decomposed.translateY - hw * sin - hh * cos;
15124
+ const corners = [
15125
+ { x: -hw, y: -hh },
15126
+ { x: hw, y: -hh },
15127
+ { x: hw, y: hh },
15128
+ { x: -hw, y: hh }
15129
+ ].map((p) => ({
15130
+ x: decomposed.translateX + p.x * cos - p.y * sin,
15131
+ y: decomposed.translateY + p.x * sin + p.y * cos
15132
+ }));
15133
+ absoluteLeft = Math.min(...corners.map((p) => p.x));
15134
+ absoluteTop = Math.min(...corners.map((p) => p.y));
15560
15135
  } catch {
15561
15136
  }
15562
15137
  finalAbsoluteMatrix = fabric.util.composeMatrix({
15563
15138
  translateX: decomposed.translateX,
15564
15139
  translateY: decomposed.translateY,
15565
- angle: finalAngle ?? 0,
15140
+ angle: decomposed.angle ?? 0,
15566
15141
  scaleX: 1,
15567
15142
  scaleY: 1,
15568
- skewX: finalSkewX ?? 0,
15569
- skewY: finalSkewY ?? 0
15143
+ skewX: 0,
15144
+ skewY: 0
15570
15145
  });
15571
15146
  if (debugGroupTextCornerResize) {
15572
15147
  logGroupTextResizeDebug("text-bake", {
@@ -15621,21 +15196,7 @@ const PageCanvas = forwardRef(
15621
15196
  const state = useEditorStore.getState();
15622
15197
  const page = state.canvas.pages.find((p) => p.id === pageId);
15623
15198
  const pageChildrenForSave = (page == null ? void 0 : page.children) ?? [];
15624
- const storePos = (logicalGroupFinalFrame == null ? void 0 : logicalGroupFinalFrame.groupId) === logicalGroupSelectionId ? (() => {
15625
- const localCenter = fabric.util.transformPoint(
15626
- new fabric.Point(decomposed.translateX ?? 0, decomposed.translateY ?? 0),
15627
- fabric.util.invertTransform(logicalGroupFinalFrame.matrix)
15628
- );
15629
- const localAngle = finalAngleFromDecomposed ? ((Number(finalAngle ?? 0) - asAngleForBake) % 360 + 540) % 360 - 180 : Number(finalAngle ?? 0);
15630
- const localAngleRad = localAngle * Math.PI / 180;
15631
- return {
15632
- left: localCenter.x - finalWidth / 2 * Math.cos(localAngleRad) + finalHeight / 2 * Math.sin(localAngleRad) + logicalGroupFinalFrame.width / 2,
15633
- top: localCenter.y - finalWidth / 2 * Math.sin(localAngleRad) - finalHeight / 2 * Math.cos(localAngleRad) + logicalGroupFinalFrame.height / 2
15634
- };
15635
- })() : absoluteToStorePosition(absoluteLeft, absoluteTop, objId, pageChildrenForSave);
15636
- if (isLogicalGroupAS && finalAngleFromDecomposed && typeof finalAngle === "number") {
15637
- finalAngle = ((finalAngle - asAngleForBake) % 360 + 540) % 360 - 180;
15638
- }
15199
+ const storePos = absoluteToStorePosition(absoluteLeft, absoluteTop, objId, pageChildrenForSave);
15639
15200
  const isLineObj = obj instanceof fabric.Line;
15640
15201
  const isAutoShrinkText = (sourceElement == null ? void 0 : sourceElement.type) === "text" && sourceElement.overflowPolicy === "auto-shrink";
15641
15202
  const autoShrinkStoredHeight = isAutoShrinkText ? sourceElement.height : void 0;
@@ -15647,17 +15208,13 @@ const PageCanvas = forwardRef(
15647
15208
  // so finalWidth already reflects the new width chosen by the user.
15648
15209
  width: finalWidth,
15649
15210
  height: isLineObj ? 0 : isAutoShrinkText ? typeof autoShrinkStoredHeight === "number" ? autoShrinkStoredHeight : finalHeight : finalHeight,
15650
- angle: finalAngle,
15651
- skewX: isLineObj ? 0 : finalSkewX,
15652
- skewY: isLineObj ? 0 : finalSkewY,
15211
+ angle: decomposed.angle,
15212
+ skewX: isLineObj ? 0 : decomposed.skewX,
15213
+ skewY: isLineObj ? 0 : decomposed.skewY,
15653
15214
  scaleX: finalScaleX,
15654
- scaleY: finalScaleY
15215
+ scaleY: finalScaleY,
15216
+ transformMatrix: finalAbsoluteMatrix
15655
15217
  };
15656
- if (!isLogicalGroupAS) {
15657
- elementUpdate.transformMatrix = finalAbsoluteMatrix;
15658
- } else {
15659
- elementUpdate.transformMatrix = void 0;
15660
- }
15661
15218
  if (obj instanceof fabric.Textbox) {
15662
15219
  const bakedTextScaleUpdates = obj.__pixldocsBakedTextScaleUpdates;
15663
15220
  if (bakedTextScaleUpdates && typeof bakedTextScaleUpdates === "object") {
@@ -15688,41 +15245,10 @@ const PageCanvas = forwardRef(
15688
15245
  objectBeforeStoreWrite: summarizeFabricObjectForResizeDebug(obj)
15689
15246
  });
15690
15247
  }
15691
- if (debugGroupImageSideResize && isGroupResizeImageLikeObject(obj)) {
15692
- logGroupImageResizeDebug("store-update-image", {
15693
- time: Math.round(performance.now()),
15694
- handle: activeSelectionResizeHandle,
15695
- imageId: objId,
15696
- storePos,
15697
- elementUpdate,
15698
- objectBeforeStoreWrite: summarizeFabricObjectForResizeDebug(obj)
15699
- });
15700
- }
15701
15248
  updateElement(objId, elementUpdate, { recordHistory: false, skipLayoutRecalc: true });
15702
15249
  obj.setCoords();
15703
- delete obj.__asLiveOrigW;
15704
- delete obj.__asLiveOrigH;
15705
- delete obj.__asLiveOrigMinH;
15706
15250
  }
15707
- if (isLogicalGroupAS && logicalGroupSelectionId && activeObj instanceof fabric.ActiveSelection) {
15708
- try {
15709
- const pageChildrenForGroup = ((_j = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _j.children) ?? [];
15710
- const groupNode = findNodeById(pageChildrenForGroup, logicalGroupSelectionId);
15711
- if (groupNode && logicalGroupFinalFrame) {
15712
- const storePosGroup = absoluteToStorePosition(logicalGroupFinalFrame.left, logicalGroupFinalFrame.top, logicalGroupSelectionId, pageChildrenForGroup);
15713
- useEditorStore.getState().updateNode(logicalGroupSelectionId, {
15714
- left: storePosGroup.left,
15715
- top: storePosGroup.top,
15716
- width: logicalGroupFinalFrame.width,
15717
- height: logicalGroupFinalFrame.height,
15718
- angle: logicalGroupFinalFrame.angle
15719
- }, { recordHistory: false, skipLayoutRecalc: true });
15720
- }
15721
- } catch (err) {
15722
- console.warn("[Pixldocs] logical-group envelope persist failed", err);
15723
- }
15724
- }
15725
- const pageChildrenForReflow = ((_k = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _k.children) ?? [];
15251
+ const pageChildrenForReflow = ((_i = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _i.children) ?? [];
15726
15252
  const stackGroupsToReflow = /* @__PURE__ */ new Set();
15727
15253
  for (const id of modifiedIdsThisRound) {
15728
15254
  const parent = findParentGroup(pageChildrenForReflow, id);
@@ -15749,16 +15275,6 @@ const PageCanvas = forwardRef(
15749
15275
  renderOnAddRemove: fabricCanvas.renderOnAddRemove
15750
15276
  });
15751
15277
  }
15752
- if (debugGroupImageSideResize) {
15753
- logGroupImageResizeDebug("before-reselect", {
15754
- time: Math.round(performance.now()),
15755
- handle: activeSelectionResizeHandle,
15756
- wasGroupSel,
15757
- selection: summarizeFabricObjectForResizeDebug(activeObj),
15758
- members: membersToReselect.map((member) => summarizeFabricObjectForResizeDebug(member)),
15759
- renderOnAddRemove: fabricCanvas.renderOnAddRemove
15760
- });
15761
- }
15762
15278
  const prevRenderOnAddRemove = fabricCanvas.renderOnAddRemove;
15763
15279
  fabricCanvas.renderOnAddRemove = false;
15764
15280
  skipSelectionClearOnDiscardRef.current = true;
@@ -15773,10 +15289,9 @@ const PageCanvas = forwardRef(
15773
15289
  if (!ct) continue;
15774
15290
  ct.frameW = bake.width;
15775
15291
  ct.frameH = bake.height;
15776
- const bakeCenter = rotatedTopLeftToCenter(bake.left, bake.top, bake.width, bake.height, bake.angle);
15777
15292
  bake.obj.set({
15778
- left: bakeCenter.x,
15779
- top: bakeCenter.y,
15293
+ left: bake.left + bake.width / 2,
15294
+ top: bake.top + bake.height / 2,
15780
15295
  width: bake.width,
15781
15296
  height: bake.height,
15782
15297
  scaleX: 1,
@@ -15803,16 +15318,6 @@ const PageCanvas = forwardRef(
15803
15318
  renderOnAddRemove: fabricCanvas.renderOnAddRemove
15804
15319
  });
15805
15320
  }
15806
- if (debugGroupImageSideResize) {
15807
- logGroupImageResizeDebug("after-reselect", {
15808
- time: Math.round(performance.now()),
15809
- handle: activeSelectionResizeHandle,
15810
- wasGroupSel,
15811
- selection: summarizeFabricObjectForResizeDebug(newSel),
15812
- members: membersToReselect.map((member) => summarizeFabricObjectForResizeDebug(member)),
15813
- renderOnAddRemove: fabricCanvas.renderOnAddRemove
15814
- });
15815
- }
15816
15321
  } else if (membersToReselect.length === 1) {
15817
15322
  fabricCanvas.setActiveObject(membersToReselect[0]);
15818
15323
  }
@@ -15849,7 +15354,6 @@ const PageCanvas = forwardRef(
15849
15354
  const activeObj = fabricCanvas.getActiveObject();
15850
15355
  if (!(activeObj instanceof fabric.ActiveSelection)) return;
15851
15356
  if (skipActiveSelectionBakeOnClearRef.current) return;
15852
- if (activeObj.__pixldocsGroupSelection) return;
15853
15357
  const selectionMatrix = activeObj.calcTransformMatrix();
15854
15358
  for (const obj of deselected) {
15855
15359
  const objId = getObjectId(obj);
@@ -16319,7 +15823,7 @@ const PageCanvas = forwardRef(
16319
15823
  const nextHeight = Math.max(minVisiblePlaceholder, Number(resolvedSizeImg.height) || 50);
16320
15824
  const storePosImg = pageChildren ? (() => {
16321
15825
  const node = findNodeById(pageChildren, element.id);
16322
- return node && isElement(node) ? getElementFabricPlacement(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
15826
+ return node ? getAbsoluteBounds(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
16323
15827
  })() : { left: element.left ?? 0, top: element.top ?? 0 };
16324
15828
  const elementForPlaceholder = { ...element, width: nextWidth, height: nextHeight };
16325
15829
  const placeholder = isCropGroup2 ? createImagePlaceholderForGroup(elementForPlaceholder) : createImagePlaceholder(elementForPlaceholder);
@@ -16382,14 +15886,13 @@ const PageCanvas = forwardRef(
16382
15886
  }
16383
15887
  const cropPos = pageChildren ? (() => {
16384
15888
  const node = findNodeById(pageChildren, element.id);
16385
- return node && isElement(node) ? getElementFabricPlacement(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16386
- })() : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16387
- const cropCenter = rotatedTopLeftToCenter(cropPos.left, cropPos.top, ct.frameW ?? 0, ct.frameH ?? 0, cropPos.angle ?? element.angle ?? 0);
16388
- const cropCenterX = cropCenter.x;
16389
- const cropCenterY = cropCenter.y;
15889
+ return node ? getAbsoluteBounds(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
15890
+ })() : { left: element.left ?? 0, top: element.top ?? 0 };
15891
+ const cropCenterX = cropPos.left + (ct.frameW ?? 0) / 2;
15892
+ const cropCenterY = cropPos.top + (ct.frameH ?? 0) / 2;
16390
15893
  if (element.left !== void 0) existingObj.set({ left: cropCenterX });
16391
15894
  if (element.top !== void 0) existingObj.set({ top: cropCenterY });
16392
- existingObj.set({ angle: cropPos.angle ?? element.angle ?? 0 });
15895
+ if (element.angle !== void 0) existingObj.set({ angle: element.angle });
16393
15896
  existingObj.set({
16394
15897
  flipX: element.flipX ?? false,
16395
15898
  flipY: element.flipY ?? false
@@ -16512,8 +16015,8 @@ const PageCanvas = forwardRef(
16512
16015
  if (isPlaceholderGroup) {
16513
16016
  const storePosImg = pageChildren ? (() => {
16514
16017
  const node = findNodeById(pageChildren, element.id);
16515
- return node && isElement(node) ? getElementFabricPlacement(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16516
- })() : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16018
+ return node ? getAbsoluteBounds(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
16019
+ })() : { left: element.left ?? 0, top: element.top ?? 0 };
16517
16020
  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 };
16518
16021
  const hasExplicitSize = typeof element.width === "number" && Number.isFinite(element.width) && element.width > 0 && typeof element.height === "number" && Number.isFinite(element.height) && element.height > 0;
16519
16022
  const minVisiblePlaceholder = hasExplicitSize ? 1 : 20;
@@ -16527,7 +16030,7 @@ const PageCanvas = forwardRef(
16527
16030
  top: storePosImg.top + nextHeight / 2,
16528
16031
  originX: "center",
16529
16032
  originY: "center",
16530
- angle: storePosImg.angle ?? element.angle ?? 0,
16033
+ angle: element.angle ?? 0,
16531
16034
  opacity: isHidden ? 0 : element.opacity ?? 1,
16532
16035
  flipX: element.flipX ?? false,
16533
16036
  flipY: element.flipY ?? false,
@@ -16576,8 +16079,8 @@ const PageCanvas = forwardRef(
16576
16079
  const visibilityChanged = previousVisible !== currentVisible;
16577
16080
  const storePosForImg = pageChildren ? (() => {
16578
16081
  const node = findNodeById(pageChildren, element.id);
16579
- return node && isElement(node) ? getElementFabricPlacement(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16580
- })() : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16082
+ return node ? getAbsoluteBounds(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
16083
+ })() : { left: element.left ?? 0, top: element.top ?? 0 };
16581
16084
  const positionChanged = Math.abs((existingObj.left ?? 0) - storePosForImg.left) > 0.1 || Math.abs((existingObj.top ?? 0) - storePosForImg.top) > 0.1;
16582
16085
  if (visibilityChanged && !positionChanged || visibilityUpdateInProgressRef.current) {
16583
16086
  const isDynamicField = dynamicFieldIds.includes(element.id);
@@ -16619,7 +16122,7 @@ const PageCanvas = forwardRef(
16619
16122
  const fabricTop = existingObj.top ?? 0;
16620
16123
  const storePos = pageChildren ? (() => {
16621
16124
  const node = findNodeById(pageChildren, element.id);
16622
- return node && isElement(node) ? getElementFabricPlacement(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
16125
+ return node ? getAbsoluteBounds(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
16623
16126
  })() : { left: element.left ?? 0, top: element.top ?? 0 };
16624
16127
  const storeLeft = storePos.left;
16625
16128
  const storeTop = storePos.top;
@@ -16746,7 +16249,7 @@ const PageCanvas = forwardRef(
16746
16249
  setObjectData(placeholder, element.id);
16747
16250
  const absPosImg = pageTree.length > 0 ? (() => {
16748
16251
  const node = findNodeById(pageTree, element.id);
16749
- return node && isElement(node) ? getElementFabricPlacement(node, pageTree) : { left: element.left ?? 0, top: element.top ?? 0 };
16252
+ return node ? getAbsoluteBounds(node, pageTree) : { left: element.left ?? 0, top: element.top ?? 0 };
16750
16253
  })() : { left: element.left ?? 0, top: element.top ?? 0 };
16751
16254
  const placeholderWidth = Number((placeholder.width ?? 0) * (placeholder.scaleX ?? 1));
16752
16255
  const placeholderHeight = Number((placeholder.height ?? 0) * (placeholder.scaleY ?? 1));
@@ -16795,7 +16298,7 @@ const PageCanvas = forwardRef(
16795
16298
  if (obj) {
16796
16299
  const absPos = pageTree.length > 0 ? (() => {
16797
16300
  const node = findNodeById(pageTree, element.id);
16798
- return node && isElement(node) ? getElementFabricPlacement(node, pageTree) : { left: element.left ?? 0, top: element.top ?? 0 };
16301
+ return node ? getAbsoluteBounds(node, pageTree) : { left: element.left ?? 0, top: element.top ?? 0 };
16799
16302
  })() : { left: element.left ?? 0, top: element.top ?? 0 };
16800
16303
  obj.set({ left: absPos.left, top: absPos.top });
16801
16304
  obj.setCoords();
@@ -17185,7 +16688,9 @@ const PageCanvas = forwardRef(
17185
16688
  if (sameSelection && isFlatGroupSelection) {
17186
16689
  if (selectedGroupSelectionId && active instanceof fabric.ActiveSelection) {
17187
16690
  if (isPureSingleGroupSelection) {
17188
- applyLogicalGroupSelectionVisualState(active, selectedGroupSelectionId);
16691
+ active.__pixldocsGroupSelection = selectedGroupSelectionId;
16692
+ delete active.__pixldocsLogicalGroupIds;
16693
+ suppressGroupMemberBordersRef.current = active.getObjects();
17189
16694
  } else {
17190
16695
  delete active.__pixldocsGroupSelection;
17191
16696
  active.__pixldocsLogicalGroupIds = selectedGroupIds;
@@ -17225,7 +16730,8 @@ const PageCanvas = forwardRef(
17225
16730
  const selection = new fabric.ActiveSelection(toSelect, { canvas: fc });
17226
16731
  if (selectedGroupSelectionId) {
17227
16732
  if (isPureSingleGroupSelection) {
17228
- applyLogicalGroupSelectionVisualState(selection, selectedGroupSelectionId);
16733
+ selection.__pixldocsGroupSelection = selectedGroupSelectionId;
16734
+ suppressGroupMemberBordersRef.current = toSelect;
17229
16735
  } else {
17230
16736
  selection.__pixldocsLogicalGroupIds = selectedGroupIds;
17231
16737
  selection.hasBorders = true;
@@ -17283,8 +16789,8 @@ const PageCanvas = forwardRef(
17283
16789
  const currentPageTree = ((pageChildren == null ? void 0 : pageChildren.length) ? pageChildren : (_a2 = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _a2.children) ?? [];
17284
16790
  const fabricPos = currentPageTree.length > 0 ? (() => {
17285
16791
  const node = findNodeById(currentPageTree, element.id);
17286
- return node && isElement(node) ? getElementFabricPlacement(node, currentPageTree) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
17287
- })() : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
16792
+ return node ? getAbsoluteBounds(node, currentPageTree) : { left: element.left ?? 0, top: element.top ?? 0 };
16793
+ })() : { left: element.left ?? 0, top: element.top ?? 0 };
17288
16794
  const resolvedSize = currentPageTree.length > 0 ? getNodeBounds(element, currentPageTree) : { width: typeof element.width === "number" ? element.width : 200, height: typeof element.height === "number" ? element.height : 50 };
17289
16795
  const shouldPreserveSmallSize = typeof element.width === "number" && Number.isFinite(element.width) && element.width > 0 && typeof element.height === "number" && Number.isFinite(element.height) && element.height > 0;
17290
16796
  const minVisible = shouldPreserveSmallSize ? 1 : 20;
@@ -17319,9 +16825,8 @@ const PageCanvas = forwardRef(
17319
16825
  ct.shape = clipShape === "circle" ? "circle" : clipShape === "rounded" ? "roundRect" : "rect";
17320
16826
  ct.rx = rxRatio;
17321
16827
  obj.__maintainResolution = element.maintainResolution !== false;
17322
- const center = rotatedTopLeftToCenter(fabricPos.left, fabricPos.top, elementWidth, elementHeight, element.angle ?? 0);
17323
- const centerX = center.x;
17324
- const centerY = center.y;
16828
+ const centerX = fabricPos.left + elementWidth / 2;
16829
+ const centerY = fabricPos.top + elementHeight / 2;
17325
16830
  const cropSetProps = {
17326
16831
  width: elementWidth,
17327
16832
  height: elementHeight,
@@ -17561,8 +17066,7 @@ const PageCanvas = forwardRef(
17561
17066
  if (!skipPositionUpdate && (obj instanceof fabric.FabricImage && obj.originX === "center" || obj instanceof fabric.Group && obj.__cropGroup)) {
17562
17067
  const vW = rW * effectiveScaleX;
17563
17068
  const vH = rH * effectiveScaleY;
17564
- const center = rotatedTopLeftToCenter(fabricPos.left, fabricPos.top, vW, vH, element.angle ?? 0);
17565
- posIfNotSkipped = { left: center.x, top: center.y };
17069
+ posIfNotSkipped = { left: fabricPos.left + vW / 2, top: fabricPos.top + vH / 2 };
17566
17070
  }
17567
17071
  if (element.transformMatrix && element.transformMatrix.length === 6) {
17568
17072
  if (isTextbox) {
@@ -18353,14 +17857,14 @@ const PageCanvas = forwardRef(
18353
17857
  const pageTreeForCreate = ((pageChildren == null ? void 0 : pageChildren.length) ? pageChildren : (_f = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _f.children) ?? [];
18354
17858
  const createPos = pageTreeForCreate.length > 0 ? (() => {
18355
17859
  const node = findNodeById(pageTreeForCreate, element.id);
18356
- return node && isElement(node) ? getElementFabricPlacement(node, pageTreeForCreate, pageBoundsOptions) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
18357
- })() : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
17860
+ return node ? getAbsoluteBounds(node, pageTreeForCreate) : { left: element.left ?? 0, top: element.top ?? 0 };
17861
+ })() : { left: element.left ?? 0, top: element.top ?? 0 };
18358
17862
  img.set({
18359
17863
  left: createPos.left,
18360
17864
  top: createPos.top,
18361
17865
  scaleX: finalScaleX,
18362
17866
  scaleY: finalScaleY,
18363
- angle: createPos.angle ?? element.angle ?? 0,
17867
+ angle: element.angle ?? 0,
18364
17868
  skewX: element.skewX ?? 0,
18365
17869
  skewY: element.skewY ?? 0,
18366
17870
  flipX: element.flipX ?? false,
@@ -18447,8 +17951,8 @@ const PageCanvas = forwardRef(
18447
17951
  const pageTreeForCrop = ((pageChildren == null ? void 0 : pageChildren.length) ? pageChildren : (_n = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _n.children) ?? [];
18448
17952
  const createPosForCrop = pageTreeForCrop.length > 0 ? (() => {
18449
17953
  const node = findNodeById(pageTreeForCrop, element.id);
18450
- return node && isElement(node) ? getElementFabricPlacement(node, pageTreeForCrop, pageBoundsOptions) : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
18451
- })() : { left: element.left ?? 0, top: element.top ?? 0, angle: element.angle ?? 0 };
17954
+ return node ? getAbsoluteBounds(node, pageTreeForCrop) : { left: element.left ?? 0, top: element.top ?? 0 };
17955
+ })() : { left: element.left ?? 0, top: element.top ?? 0 };
18452
17956
  const nodeForCreate = pageTreeForCrop.length ? findNodeById(pageTreeForCrop, element.id) : null;
18453
17957
  const createW = nodeForCreate && isElement(nodeForCreate) ? nodeForCreate.width : elementWidth;
18454
17958
  const createH = nodeForCreate && isElement(nodeForCreate) ? nodeForCreate.height : elementHeight;
@@ -18456,9 +17960,8 @@ const PageCanvas = forwardRef(
18456
17960
  const createSy = nodeForCreate && isElement(nodeForCreate) ? nodeForCreate.scaleY ?? 1 : element.scaleY ?? 1;
18457
17961
  const frameW = Math.max(1, Number(createW) || 200) * createSx;
18458
17962
  const frameH = Math.max(1, Number(createH) || 50) * createSy;
18459
- const createCenter = rotatedTopLeftToCenter(createPosForCrop.left, createPosForCrop.top, frameW, frameH, createPosForCrop.angle ?? element.angle ?? 0);
18460
- const createCenterX = createCenter.x;
18461
- const createCenterY = createCenter.y;
17963
+ const createCenterX = createPosForCrop.left + frameW / 2;
17964
+ const createCenterY = createPosForCrop.top + frameH / 2;
18462
17965
  const cropGroup = await createMaskedImageElement({
18463
17966
  image: img,
18464
17967
  frameW,
@@ -18471,7 +17974,7 @@ const PageCanvas = forwardRef(
18471
17974
  strokeWidth: 0,
18472
17975
  left: createCenterX,
18473
17976
  top: createCenterY,
18474
- angle: createPosForCrop.angle ?? element.angle ?? 0,
17977
+ angle: element.angle ?? 0,
18475
17978
  opacity: isHidden ? 0 : element.opacity ?? 1,
18476
17979
  selectable: allowSelection && !isHidden,
18477
17980
  evented: canBeEvented && !isHidden,
@@ -24861,9 +24364,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
24861
24364
  }
24862
24365
  return svgString;
24863
24366
  }
24864
- const resolvedPackageVersion = "0.5.353";
24367
+ const resolvedPackageVersion = "0.5.355";
24865
24368
  const PACKAGE_VERSION = resolvedPackageVersion;
24866
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.353";
24369
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.355";
24867
24370
  const roundParityValue = (value) => {
24868
24371
  if (typeof value !== "number") return value;
24869
24372
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -25677,7 +25180,7 @@ class PixldocsRenderer {
25677
25180
  await this.waitForCanvasScene(container, cloned, i);
25678
25181
  }
25679
25182
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
25680
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-BvY4a5sT.js");
25183
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-CIYQWsck.js");
25681
25184
  const prepared = preparePagesForExport(
25682
25185
  cloned.pages,
25683
25186
  canvasWidth,
@@ -27997,7 +27500,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
27997
27500
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
27998
27501
  sanitizeSvgTreeForPdf(svgToDraw);
27999
27502
  try {
28000
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-BvY4a5sT.js");
27503
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-CIYQWsck.js");
28001
27504
  try {
28002
27505
  await logTextMeasurementDiagnostic(svgToDraw);
28003
27506
  } catch {
@@ -28397,4 +27900,4 @@ export {
28397
27900
  buildTeaserBlurFlatKeys as y,
28398
27901
  collectFontDescriptorsFromConfig as z
28399
27902
  };
28400
- //# sourceMappingURL=index-C32C3XZP.js.map
27903
+ //# sourceMappingURL=index-CJNRmC-X.js.map