@pixldocs/canvas-renderer 0.5.358 → 0.5.360

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.
@@ -11087,6 +11087,136 @@ const logGroupTextResizeDebug = (phase, payload) => {
11087
11087
  console.log(GROUP_TEXT_RESIZE_DEBUG_PREFIX, phase, payload);
11088
11088
  }
11089
11089
  };
11090
+ const ROT_GROUP_IMAGE_DRIFT_DEBUG_PREFIX = "[Pixldocs][rot-group-image-drift]";
11091
+ const ROT_GROUP_IMAGE_DRIFT_DEBUG_MAX_ENTRIES = 500;
11092
+ const roundRotDriftNumber = (value) => {
11093
+ if (typeof value !== "number") return value;
11094
+ return Number.isFinite(value) ? Math.round(value * 1e3) / 1e3 : String(value);
11095
+ };
11096
+ const normalizeRotDriftPayload = (value) => {
11097
+ const seen = /* @__PURE__ */ new WeakSet();
11098
+ const normalize = (entry) => {
11099
+ if (entry == null) return entry;
11100
+ const valueType = typeof entry;
11101
+ if (valueType === "number") return roundRotDriftNumber(entry);
11102
+ if (valueType === "string" || valueType === "boolean") return entry;
11103
+ if (Array.isArray(entry)) return entry.map((item) => normalize(item));
11104
+ if (valueType === "object") {
11105
+ if (seen.has(entry)) return "[Circular]";
11106
+ seen.add(entry);
11107
+ if (entry instanceof fabric.FabricObject) return normalize(summarizeRotDriftObject(entry));
11108
+ const output = {};
11109
+ Object.entries(entry).forEach(([key, item]) => {
11110
+ output[key] = normalize(item);
11111
+ });
11112
+ return output;
11113
+ }
11114
+ return String(entry);
11115
+ };
11116
+ return normalize(value);
11117
+ };
11118
+ const matrixForRotDriftLog = (matrix) => {
11119
+ if (!matrix) return void 0;
11120
+ return matrix.map((entry) => roundRotDriftNumber(entry));
11121
+ };
11122
+ const summarizeRotDriftObject = (obj, worldMatrix) => {
11123
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
11124
+ if (!obj) return null;
11125
+ const anyObj = obj;
11126
+ try {
11127
+ const ownMatrix = (_a2 = obj.calcOwnMatrix) == null ? void 0 : _a2.call(obj);
11128
+ const calcWorld = worldMatrix ?? ((_b2 = obj.calcTransformMatrix) == null ? void 0 : _b2.call(obj));
11129
+ const decomposed = calcWorld ? fabric.util.qrDecompose(calcWorld) : null;
11130
+ const center = (_c = obj.getCenterPoint) == null ? void 0 : _c.call(obj);
11131
+ const rect = (_d = obj.getBoundingRect) == null ? void 0 : _d.call(obj);
11132
+ return {
11133
+ id: getObjectId(obj),
11134
+ type: anyObj.type ?? ((_e = obj.constructor) == null ? void 0 : _e.name),
11135
+ isAS: obj instanceof fabric.ActiveSelection,
11136
+ isGroup: obj instanceof fabric.Group,
11137
+ isImage: obj instanceof fabric.FabricImage,
11138
+ isCropGroup: Boolean(anyObj.__cropGroup || ((_f = anyObj._ct) == null ? void 0 : _f.isCropGroup)),
11139
+ hasLayoutManager: Boolean(anyObj.layoutManager),
11140
+ left: obj.left,
11141
+ top: obj.top,
11142
+ angle: obj.angle,
11143
+ scaleX: obj.scaleX,
11144
+ scaleY: obj.scaleY,
11145
+ width: obj.width,
11146
+ height: obj.height,
11147
+ originX: obj.originX,
11148
+ originY: obj.originY,
11149
+ centerX: center == null ? void 0 : center.x,
11150
+ centerY: center == null ? void 0 : center.y,
11151
+ brLeft: rect == null ? void 0 : rect.left,
11152
+ brTop: rect == null ? void 0 : rect.top,
11153
+ brWidth: rect == null ? void 0 : rect.width,
11154
+ brHeight: rect == null ? void 0 : rect.height,
11155
+ worldTx: decomposed == null ? void 0 : decomposed.translateX,
11156
+ worldTy: decomposed == null ? void 0 : decomposed.translateY,
11157
+ worldAngle: decomposed == null ? void 0 : decomposed.angle,
11158
+ worldScaleX: decomposed == null ? void 0 : decomposed.scaleX,
11159
+ worldScaleY: decomposed == null ? void 0 : decomposed.scaleY,
11160
+ ownMatrix: matrixForRotDriftLog(ownMatrix ?? null),
11161
+ worldMatrix: matrixForRotDriftLog(calcWorld ?? null),
11162
+ cropFrameW: (_g = anyObj.__cropData) == null ? void 0 : _g.frameW,
11163
+ cropFrameH: (_h = anyObj.__cropData) == null ? void 0 : _h.frameH,
11164
+ cropPanX: (_k = (_j = (_i = anyObj.__cropData) == null ? void 0 : _i._img) == null ? void 0 : _j._ct) == null ? void 0 : _k.panX,
11165
+ cropPanY: (_n = (_m = (_l = anyObj.__cropData) == null ? void 0 : _l._img) == null ? void 0 : _m._ct) == null ? void 0 : _n.panY,
11166
+ cropZoom: (_q = (_p = (_o = anyObj.__cropData) == null ? void 0 : _o._img) == null ? void 0 : _p._ct) == null ? void 0 : _q.zoom
11167
+ };
11168
+ } catch (error) {
11169
+ return { id: getObjectId(obj), type: anyObj.type, error: String(error) };
11170
+ }
11171
+ };
11172
+ const logRotGroupImageDrift = (phase, payload) => {
11173
+ if (typeof console === "undefined") return;
11174
+ try {
11175
+ const line = `${ROT_GROUP_IMAGE_DRIFT_DEBUG_PREFIX} ${phase} ${JSON.stringify(normalizeRotDriftPayload(payload))}`;
11176
+ if (typeof window !== "undefined") {
11177
+ const debugWindow = window;
11178
+ debugWindow.__pixldocsRotGroupImageDriftLogs = Array.isArray(debugWindow.__pixldocsRotGroupImageDriftLogs) ? debugWindow.__pixldocsRotGroupImageDriftLogs.slice(-ROT_GROUP_IMAGE_DRIFT_DEBUG_MAX_ENTRIES + 1) : [];
11179
+ debugWindow.__pixldocsRotGroupImageDriftLogs.push(line);
11180
+ }
11181
+ console.log(line);
11182
+ } catch {
11183
+ console.log(ROT_GROUP_IMAGE_DRIFT_DEBUG_PREFIX, phase, payload);
11184
+ }
11185
+ };
11186
+ const shouldLogRotDriftLiveTick = (target, phase) => {
11187
+ if (!target) return false;
11188
+ const anyTarget = target;
11189
+ const key = `__pixldocsRotDrift_${phase}_count`;
11190
+ const count = (anyTarget[key] ?? 0) + 1;
11191
+ anyTarget[key] = count;
11192
+ return count <= 3 || count % 8 === 0;
11193
+ };
11194
+ const logRotDriftSelectionSnapshot = (phase, target, extra = {}) => {
11195
+ if (!target) return;
11196
+ const anyTarget = target;
11197
+ const kids = typeof anyTarget.getObjects === "function" ? anyTarget.getObjects() : [];
11198
+ const selectionMatrix = target instanceof fabric.ActiveSelection ? target.calcTransformMatrix() : null;
11199
+ logRotGroupImageDrift(phase, {
11200
+ ...extra,
11201
+ target: summarizeRotDriftObject(target),
11202
+ childCount: kids.length,
11203
+ groupSelectionId: anyTarget.__pixldocsGroupSelection,
11204
+ alignedAngle: anyTarget.__pixldocsAlignedAngle
11205
+ });
11206
+ kids.forEach((kid, childIndex) => {
11207
+ var _a2, _b2;
11208
+ const childWorldMatrix = selectionMatrix ? fabric.util.multiplyTransformMatrices(
11209
+ selectionMatrix,
11210
+ kid.calcOwnMatrix()
11211
+ ) : (_a2 = kid.calcTransformMatrix) == null ? void 0 : _a2.call(kid);
11212
+ logRotGroupImageDrift(`${phase}-child`, {
11213
+ ...extra,
11214
+ childIndex,
11215
+ parentType: anyTarget.type ?? ((_b2 = target.constructor) == null ? void 0 : _b2.name),
11216
+ child: summarizeRotDriftObject(kid, childWorldMatrix ?? null)
11217
+ });
11218
+ });
11219
+ };
11090
11220
  const bakeTextboxScaleIntoTypography = (obj, sourceElement) => {
11091
11221
  const sx = Math.abs(obj.scaleX ?? 1) || 1;
11092
11222
  const sy = Math.abs(obj.scaleY ?? 1) || 1;
@@ -11196,6 +11326,7 @@ function applyWarpAwareSelectionBorders(selection) {
11196
11326
  selection.calcTransformMatrix()
11197
11327
  );
11198
11328
  kids.forEach((k, index) => {
11329
+ const beforeRestore = summarizeRotDriftObject(k);
11199
11330
  const localMatrix = fabric.util.multiplyTransformMatrices(
11200
11331
  invSelection,
11201
11332
  worldMatrices[index]
@@ -11214,8 +11345,19 @@ function applyWarpAwareSelectionBorders(selection) {
11214
11345
  }
11215
11346
  k.setCoords();
11216
11347
  k.dirty = true;
11348
+ logRotGroupImageDrift("aligned-restore-child", {
11349
+ targetAngle,
11350
+ childIndex: index,
11351
+ before: beforeRestore,
11352
+ expectedLocal: fabric.util.qrDecompose(localMatrix),
11353
+ after: summarizeRotDriftObject(k)
11354
+ });
11217
11355
  });
11218
11356
  };
11357
+ logRotDriftSelectionSnapshot("aligned-before", selection, {
11358
+ targetAngle,
11359
+ worldAngles
11360
+ });
11219
11361
  selection.set({ angle: targetAngle, scaleX: 1, scaleY: 1, skewX: 0, skewY: 0 });
11220
11362
  restoreKidsFromWorld();
11221
11363
  try {
@@ -11226,37 +11368,10 @@ function applyWarpAwareSelectionBorders(selection) {
11226
11368
  selection.setCoords();
11227
11369
  selection.dirty = true;
11228
11370
  selection.__pixldocsAlignedAngle = targetAngle;
11229
- try {
11230
- const payload = {
11231
- targetAngle,
11232
- selection: {
11233
- left: selection.left,
11234
- top: selection.top,
11235
- angle: selection.angle,
11236
- scaleX: selection.scaleX,
11237
- scaleY: selection.scaleY,
11238
- width: selection.width,
11239
- height: selection.height,
11240
- originX: selection.originX,
11241
- originY: selection.originY
11242
- },
11243
- kids: kids.map((c) => ({
11244
- id: c.id ?? c.__pixldocsId,
11245
- type: c.type,
11246
- left: c.left,
11247
- top: c.top,
11248
- angle: c.angle,
11249
- scaleX: c.scaleX,
11250
- scaleY: c.scaleY,
11251
- originX: c.originX,
11252
- originY: c.originY,
11253
- width: c.width,
11254
- height: c.height
11255
- }))
11256
- };
11257
- console.info("[Pixldocs][rot-group-image-drift] aligned-on-select " + JSON.stringify(payload));
11258
- } catch {
11259
- }
11371
+ logRotDriftSelectionSnapshot("aligned-after", selection, {
11372
+ targetAngle,
11373
+ worldAngles
11374
+ });
11260
11375
  }
11261
11376
  }
11262
11377
  }
@@ -12304,6 +12419,10 @@ const PageCanvas = forwardRef(
12304
12419
  selectionLeft: rect.left,
12305
12420
  selectionTop: rect.top
12306
12421
  };
12422
+ logRotDriftSelectionSnapshot("mouse-down-active-selection", active, {
12423
+ time: Math.round(performance.now()),
12424
+ selectedStoreIds: useEditorStore.getState().canvas.selectedIds
12425
+ });
12307
12426
  }
12308
12427
  if (fabricCanvas._currentTransform) {
12309
12428
  fabricCanvas.__isUserTransforming = true;
@@ -12916,6 +13035,14 @@ const PageCanvas = forwardRef(
12916
13035
  groupTop: groupAbs.top,
12917
13036
  selectionAngle: ((active.angle ?? 0) % 360 + 360) % 360
12918
13037
  };
13038
+ logRotDriftSelectionSnapshot("transform-start", active, {
13039
+ time: Math.round(performance.now()),
13040
+ groupId,
13041
+ groupAbs,
13042
+ selectionRect: rect,
13043
+ transformStart: groupSelectionTransformStartRef.current,
13044
+ selectedStoreIds: useEditorStore.getState().canvas.selectedIds
13045
+ });
12919
13046
  };
12920
13047
  const restoreGroupSelectionVisualState = (selection, groupId) => {
12921
13048
  applyLogicalGroupSelectionVisualState(selection, groupId);
@@ -13702,13 +13829,22 @@ const PageCanvas = forwardRef(
13702
13829
  fabricCanvas.on("selection:cleared", () => {
13703
13830
  });
13704
13831
  fabricCanvas.on("object:scaling", (e) => {
13705
- var _a2, _b2, _c, _d, _e, _f;
13832
+ var _a2, _b2, _c, _d, _e, _f, _g, _h;
13706
13833
  if (!isActiveRef.current) return;
13707
13834
  const t = e.target;
13708
13835
  if (t) lastResizeScaleTargetRef.current = t;
13709
13836
  prepareGroupSelectionTransformStart(t);
13710
13837
  markTransforming(t);
13711
13838
  didTransformRef.current = true;
13839
+ if (shouldLogRotDriftLiveTick(t, "scaling")) {
13840
+ logRotDriftSelectionSnapshot("scaling", t, {
13841
+ time: Math.round(performance.now()),
13842
+ corner: t == null ? void 0 : t.__corner,
13843
+ transformAction: (_a2 = fabricCanvas._currentTransform) == null ? void 0 : _a2.action,
13844
+ transformCorner: (_b2 = fabricCanvas._currentTransform) == null ? void 0 : _b2.corner,
13845
+ transformStart: groupSelectionTransformStartRef.current
13846
+ });
13847
+ }
13712
13848
  const transformTargetId = t ? getObjectId(t) : null;
13713
13849
  if (transformTargetId && transformTargetId !== "__background__") {
13714
13850
  preserveSelectionAfterTransformIdRef.current = transformTargetId;
@@ -13869,7 +14005,7 @@ const PageCanvas = forwardRef(
13869
14005
  time: Math.round(performance.now()),
13870
14006
  corner,
13871
14007
  groupSelectionId: obj.__pixldocsGroupSelection,
13872
- currentTransformAction: (_a2 = fabricCanvas._currentTransform) == null ? void 0 : _a2.action,
14008
+ currentTransformAction: (_c = fabricCanvas._currentTransform) == null ? void 0 : _c.action,
13873
14009
  selection: summarizeFabricObjectForResizeDebug(obj),
13874
14010
  textChildren: obj.getObjects().filter((child) => child instanceof fabric.Textbox).map((child) => summarizeFabricObjectForResizeDebug(child))
13875
14011
  };
@@ -13879,13 +14015,13 @@ const PageCanvas = forwardRef(
13879
14015
  const isXSide = corner === "ml" || corner === "mr";
13880
14016
  const sAxis = isXSide ? Math.abs(obj.scaleX ?? 1) : Math.abs(obj.scaleY ?? 1);
13881
14017
  if (sAxis > 1e-3) {
13882
- if (isXSide && ((_b2 = groupShiftReflowSnapshotRef.current) == null ? void 0 : _b2.selection) !== obj) {
14018
+ if (isXSide && ((_d = groupShiftReflowSnapshotRef.current) == null ? void 0 : _d.selection) !== obj) {
13883
14019
  groupShiftReflowSnapshotRef.current = null;
13884
14020
  const logicalGroupId = obj.__pixldocsGroupSelection;
13885
14021
  if (logicalGroupId) {
13886
14022
  try {
13887
14023
  const state = useEditorStore.getState();
13888
- const pageChildren2 = ((_c = state.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _c.children) ?? [];
14024
+ const pageChildren2 = ((_e = state.canvas.pages.find((p) => p.id === pageId)) == null ? void 0 : _e.children) ?? [];
13889
14025
  const groupNode = findNodeById(pageChildren2, logicalGroupId);
13890
14026
  if (groupNode && isGroup(groupNode) && !isStackLayoutMode(groupNode.layoutMode)) {
13891
14027
  const entries = obj.getObjects().map((c) => ({
@@ -13915,7 +14051,7 @@ const PageCanvas = forwardRef(
13915
14051
  const asRect0 = obj.getBoundingRect();
13916
14052
  let didReflowTextChild = false;
13917
14053
  for (const child of obj.getObjects()) {
13918
- if (child instanceof fabric.Group && (child.__cropGroup || ((_d = child._ct) == null ? void 0 : _d.isCropGroup))) {
14054
+ if (child instanceof fabric.Group && (child.__cropGroup || ((_f = child._ct) == null ? void 0 : _f.isCropGroup))) {
13919
14055
  const ct = child.__cropData;
13920
14056
  if (!ct) continue;
13921
14057
  if (isXSide) {
@@ -14020,7 +14156,7 @@ const PageCanvas = forwardRef(
14020
14156
  didReflowTextChild = true;
14021
14157
  }
14022
14158
  }
14023
- if (isXSide && ((_e = groupShiftReflowSnapshotRef.current) == null ? void 0 : _e.selection) === obj) {
14159
+ if (isXSide && ((_g = groupShiftReflowSnapshotRef.current) == null ? void 0 : _g.selection) === obj) {
14024
14160
  const snap = groupShiftReflowSnapshotRef.current;
14025
14161
  const anchorEntry = snap.children[0];
14026
14162
  const anchorTopLive = anchorEntry.obj.top ?? 0;
@@ -14176,7 +14312,7 @@ const PageCanvas = forwardRef(
14176
14312
  setGuides(gridGuidesForScale.length ? [...scaleGuides, ...gridGuidesForScale] : scaleGuides);
14177
14313
  if (drilledGroupIdRef.current) {
14178
14314
  try {
14179
- (_f = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _f.call(fabricCanvas);
14315
+ (_h = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _h.call(fabricCanvas);
14180
14316
  } catch {
14181
14317
  }
14182
14318
  }
@@ -14267,42 +14403,17 @@ const PageCanvas = forwardRef(
14267
14403
  }
14268
14404
  });
14269
14405
  fabricCanvas.on("object:rotating", (e) => {
14406
+ var _a2, _b2;
14270
14407
  markSimpleTransform(e);
14271
14408
  didTransformRef.current = true;
14272
14409
  const tr = e.target;
14273
- try {
14274
- const t = tr;
14275
- if (t) {
14276
- const payload = {
14277
- targetType: t.type,
14278
- isAS: t instanceof fabric.ActiveSelection,
14279
- left: t.left,
14280
- top: t.top,
14281
- angle: t.angle,
14282
- scaleX: t.scaleX,
14283
- scaleY: t.scaleY,
14284
- width: t.width,
14285
- height: t.height,
14286
- originX: t.originX,
14287
- originY: t.originY,
14288
- childCount: (t._objects ?? []).length,
14289
- children: (t._objects ?? []).map((c) => ({
14290
- id: getObjectId(c),
14291
- type: c.type,
14292
- left: c.left,
14293
- top: c.top,
14294
- angle: c.angle,
14295
- scaleX: c.scaleX,
14296
- scaleY: c.scaleY,
14297
- originX: c.originX,
14298
- originY: c.originY,
14299
- width: c.width,
14300
- height: c.height
14301
- }))
14302
- };
14303
- console.info("[Pixldocs][rot-group-image-drift] rotating " + JSON.stringify(payload));
14304
- }
14305
- } catch {
14410
+ if (shouldLogRotDriftLiveTick(tr, "rotating")) {
14411
+ logRotDriftSelectionSnapshot("rotating", tr, {
14412
+ time: Math.round(performance.now()),
14413
+ transformAction: (_a2 = fabricCanvas._currentTransform) == null ? void 0 : _a2.action,
14414
+ transformCorner: (_b2 = fabricCanvas._currentTransform) == null ? void 0 : _b2.corner,
14415
+ transformStart: groupSelectionTransformStartRef.current
14416
+ });
14306
14417
  }
14307
14418
  try {
14308
14419
  const getCursor = fabricCanvas.__pixldocsGetRotateCursor;
@@ -14332,43 +14443,18 @@ const PageCanvas = forwardRef(
14332
14443
  didTransformRef.current = true;
14333
14444
  });
14334
14445
  fabricCanvas.on("object:moving", (e) => {
14446
+ var _a2, _b2;
14335
14447
  if (!isActiveRef.current) return;
14336
14448
  prepareGroupSelectionTransformStart(e.target);
14337
14449
  markTransforming(e.target);
14338
14450
  didTransformRef.current = true;
14339
- try {
14340
- const t = e.target;
14341
- if (t && (t.angle ?? 0) !== 0) {
14342
- const payload = {
14343
- targetType: t.type,
14344
- isAS: t instanceof fabric.ActiveSelection,
14345
- left: t.left,
14346
- top: t.top,
14347
- angle: t.angle,
14348
- scaleX: t.scaleX,
14349
- scaleY: t.scaleY,
14350
- width: t.width,
14351
- height: t.height,
14352
- originX: t.originX,
14353
- originY: t.originY,
14354
- childCount: (t._objects ?? []).length,
14355
- children: (t._objects ?? []).map((c) => ({
14356
- id: getObjectId(c),
14357
- type: c.type,
14358
- left: c.left,
14359
- top: c.top,
14360
- angle: c.angle,
14361
- scaleX: c.scaleX,
14362
- scaleY: c.scaleY,
14363
- originX: c.originX,
14364
- originY: c.originY,
14365
- width: c.width,
14366
- height: c.height
14367
- }))
14368
- };
14369
- console.info("[Pixldocs][rot-group-image-drift] moving " + JSON.stringify(payload));
14370
- }
14371
- } catch {
14451
+ if (shouldLogRotDriftLiveTick(e.target, "moving")) {
14452
+ logRotDriftSelectionSnapshot("moving", e.target, {
14453
+ time: Math.round(performance.now()),
14454
+ transformAction: (_a2 = fabricCanvas._currentTransform) == null ? void 0 : _a2.action,
14455
+ transformCorner: (_b2 = fabricCanvas._currentTransform) == null ? void 0 : _b2.corner,
14456
+ transformStart: groupSelectionTransformStartRef.current
14457
+ });
14372
14458
  }
14373
14459
  const activeDuringMove = fabricCanvas.getActiveObject();
14374
14460
  const movingLogicalGroupId = activeDuringMove instanceof fabric.ActiveSelection ? activeDuringMove.__pixldocsGroupSelection : void 0;
@@ -14706,6 +14792,15 @@ const PageCanvas = forwardRef(
14706
14792
  activeObjects = activeObjects[0].getObjects();
14707
14793
  }
14708
14794
  const isActiveSelection = activeObj instanceof fabric.ActiveSelection || activeObjects.length > 1;
14795
+ if (activeObj instanceof fabric.ActiveSelection) {
14796
+ logRotDriftSelectionSnapshot("modified-start-active-selection", activeObj, {
14797
+ time: Math.round(performance.now()),
14798
+ modifiedTarget: summarizeRotDriftObject(modifiedTarget),
14799
+ activeObjectIds: activeObjects.map((candidate) => getObjectId(candidate)),
14800
+ selectedStoreIds: useEditorStore.getState().canvas.selectedIds,
14801
+ transformStart: groupSelectionTransformStartRef.current
14802
+ });
14803
+ }
14709
14804
  const activeSelectionResizeHandle = isActiveSelection ? activeSelectionResizeHandleRef.current : null;
14710
14805
  const debugGroupTextCornerResize = activeObj instanceof fabric.ActiveSelection && isCornerResizeHandle(activeSelectionResizeHandle) && activeObjects.some((candidate) => candidate instanceof fabric.Textbox);
14711
14806
  if (debugGroupTextCornerResize) {
@@ -15355,6 +15450,32 @@ const PageCanvas = forwardRef(
15355
15450
  objectBeforeStoreWrite: summarizeFabricObjectForResizeDebug(obj)
15356
15451
  });
15357
15452
  }
15453
+ if (isActiveSelection) {
15454
+ logRotGroupImageDrift("store-update-child", {
15455
+ time: Math.round(performance.now()),
15456
+ objId,
15457
+ sourceElement: sourceElement ? {
15458
+ id: sourceElement.id,
15459
+ type: sourceElement.type,
15460
+ left: sourceElement.left,
15461
+ top: sourceElement.top,
15462
+ width: sourceElement.width,
15463
+ height: sourceElement.height,
15464
+ angle: sourceElement.angle,
15465
+ scaleX: sourceElement.scaleX,
15466
+ scaleY: sourceElement.scaleY
15467
+ } : null,
15468
+ objectBeforeStoreWrite: summarizeRotDriftObject(obj, finalAbsoluteMatrix),
15469
+ activeSelection: summarizeRotDriftObject(activeObj),
15470
+ absoluteMatrix,
15471
+ finalAbsoluteMatrix,
15472
+ decomposed,
15473
+ absoluteLeft,
15474
+ absoluteTop,
15475
+ storePos,
15476
+ elementUpdate
15477
+ });
15478
+ }
15358
15479
  updateElement(objId, elementUpdate, { recordHistory: false, skipLayoutRecalc: true });
15359
15480
  obj.setCoords();
15360
15481
  }
@@ -15385,6 +15506,19 @@ const PageCanvas = forwardRef(
15385
15506
  renderOnAddRemove: fabricCanvas.renderOnAddRemove
15386
15507
  });
15387
15508
  }
15509
+ logRotDriftSelectionSnapshot("before-reselect", activeObj, {
15510
+ time: Math.round(performance.now()),
15511
+ wasGroupSel,
15512
+ memberIds: membersToReselect.map((member) => getObjectId(member)),
15513
+ pendingCropBakes: pendingCropGroupFrameBakes.map((bake) => ({
15514
+ id: getObjectId(bake.obj),
15515
+ width: bake.width,
15516
+ height: bake.height,
15517
+ left: bake.left,
15518
+ top: bake.top,
15519
+ angle: bake.angle
15520
+ }))
15521
+ });
15388
15522
  const prevRenderOnAddRemove = fabricCanvas.renderOnAddRemove;
15389
15523
  fabricCanvas.renderOnAddRemove = false;
15390
15524
  skipSelectionClearOnDiscardRef.current = true;
@@ -15418,6 +15552,11 @@ const PageCanvas = forwardRef(
15418
15552
  if (wasGroupSel) restoreGroupSelectionVisualState(newSel, wasGroupSel);
15419
15553
  fabricCanvas.setActiveObject(newSel);
15420
15554
  newSel.setCoords();
15555
+ logRotDriftSelectionSnapshot("after-reselect", newSel, {
15556
+ time: Math.round(performance.now()),
15557
+ wasGroupSel,
15558
+ memberIds: membersToReselect.map((member) => getObjectId(member))
15559
+ });
15421
15560
  if (debugGroupTextCornerResize) {
15422
15561
  logGroupTextResizeDebug("after-reselect", {
15423
15562
  time: Math.round(performance.now()),
@@ -16795,7 +16934,7 @@ const PageCanvas = forwardRef(
16795
16934
  const isFlatGroupSelection = toSelect.length > 1 && toSelect.every((o) => !(o instanceof fabric.Group));
16796
16935
  const active = fc.getActiveObject();
16797
16936
  const sameSelection = active instanceof fabric.ActiveSelection && active.getObjects().length === toSelect.length && toSelect.every((obj) => active.getObjects().includes(obj));
16798
- if (sameSelection && isFlatGroupSelection) {
16937
+ if (sameSelection && (isFlatGroupSelection || isPureSingleGroupSelection)) {
16799
16938
  if (selectedGroupSelectionId && active instanceof fabric.ActiveSelection) {
16800
16939
  if (isPureSingleGroupSelection) {
16801
16940
  active.__pixldocsGroupSelection = selectedGroupSelectionId;
@@ -16827,8 +16966,10 @@ const PageCanvas = forwardRef(
16827
16966
  });
16828
16967
  if (isPureSingleGroupSelection) {
16829
16968
  active.hasBorders = true;
16830
- active.setCoords();
16831
- applyWarpAwareSelectionBorders(active);
16969
+ if (active.__pixldocsAlignedAngle == null) {
16970
+ active.setCoords();
16971
+ applyWarpAwareSelectionBorders(active);
16972
+ }
16832
16973
  }
16833
16974
  }
16834
16975
  fc.requestRenderAll();
@@ -24474,9 +24615,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
24474
24615
  }
24475
24616
  return svgString;
24476
24617
  }
24477
- const resolvedPackageVersion = "0.5.358";
24618
+ const resolvedPackageVersion = "0.5.360";
24478
24619
  const PACKAGE_VERSION = resolvedPackageVersion;
24479
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.358";
24620
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.360";
24480
24621
  const roundParityValue = (value) => {
24481
24622
  if (typeof value !== "number") return value;
24482
24623
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -25290,7 +25431,7 @@ class PixldocsRenderer {
25290
25431
  await this.waitForCanvasScene(container, cloned, i);
25291
25432
  }
25292
25433
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
25293
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-Bk_ZPaK4.js");
25434
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-Cxjz5z00.js");
25294
25435
  const prepared = preparePagesForExport(
25295
25436
  cloned.pages,
25296
25437
  canvasWidth,
@@ -27610,7 +27751,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
27610
27751
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
27611
27752
  sanitizeSvgTreeForPdf(svgToDraw);
27612
27753
  try {
27613
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-Bk_ZPaK4.js");
27754
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-Cxjz5z00.js");
27614
27755
  try {
27615
27756
  await logTextMeasurementDiagnostic(svgToDraw);
27616
27757
  } catch {
@@ -28010,4 +28151,4 @@ export {
28010
28151
  buildTeaserBlurFlatKeys as y,
28011
28152
  collectFontDescriptorsFromConfig as z
28012
28153
  };
28013
- //# sourceMappingURL=index-D14RzE7l.js.map
28154
+ //# sourceMappingURL=index-UHlXMRk_.js.map