@tldraw/editor 5.1.0 → 5.2.0-canary.05c017c18b15

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.
Files changed (138) hide show
  1. package/README.md +7 -1
  2. package/dist-cjs/index.d.ts +50 -50
  3. package/dist-cjs/index.js +4 -4
  4. package/dist-cjs/index.js.map +2 -2
  5. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +4 -1
  6. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +3 -3
  7. package/dist-cjs/lib/components/default-components/DefaultLoadingScreen.js +2 -2
  8. package/dist-cjs/lib/components/default-components/DefaultLoadingScreen.js.map +2 -2
  9. package/dist-cjs/lib/components/default-components/DefaultShapeErrorFallback.js +1 -1
  10. package/dist-cjs/lib/components/default-components/DefaultShapeErrorFallback.js.map +3 -3
  11. package/dist-cjs/lib/components/default-components/DefaultSvgDefs.js +2 -2
  12. package/dist-cjs/lib/components/default-components/DefaultSvgDefs.js.map +2 -2
  13. package/dist-cjs/lib/editor/Editor.js +123 -55
  14. package/dist-cjs/lib/editor/Editor.js.map +3 -3
  15. package/dist-cjs/lib/editor/derivations/bindingsIndex.js +2 -2
  16. package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
  17. package/dist-cjs/lib/editor/derivations/parentsToChildren.js +2 -2
  18. package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
  19. package/dist-cjs/lib/editor/derivations/shapeIdsInCurrentPage.js +2 -2
  20. package/dist-cjs/lib/editor/derivations/shapeIdsInCurrentPage.js.map +2 -2
  21. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +8 -58
  22. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
  23. package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js +3 -3
  24. package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js.map +2 -2
  25. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +1 -2
  26. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +2 -2
  27. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js +24 -2
  28. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +2 -2
  29. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js +4 -2
  30. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js.map +2 -2
  31. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +7 -3
  32. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
  33. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +15 -2
  34. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
  35. package/dist-cjs/lib/editor/overlays/strokeShapeIndicators.js +79 -0
  36. package/dist-cjs/lib/editor/overlays/strokeShapeIndicators.js.map +7 -0
  37. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +3 -0
  38. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +2 -2
  39. package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
  40. package/dist-cjs/lib/editor/types/event-types.js +0 -2
  41. package/dist-cjs/lib/editor/types/event-types.js.map +2 -2
  42. package/dist-cjs/lib/hooks/usePresence.js.map +2 -2
  43. package/dist-cjs/lib/license/LicenseProvider.js +3 -1
  44. package/dist-cjs/lib/license/LicenseProvider.js.map +2 -2
  45. package/dist-cjs/lib/primitives/utils.js +2 -2
  46. package/dist-cjs/lib/primitives/utils.js.map +2 -2
  47. package/dist-cjs/lib/utils/dom.js +5 -3
  48. package/dist-cjs/lib/utils/dom.js.map +2 -2
  49. package/dist-cjs/version.js +3 -3
  50. package/dist-cjs/version.js.map +1 -1
  51. package/dist-esm/index.d.mts +50 -50
  52. package/dist-esm/index.mjs +5 -7
  53. package/dist-esm/index.mjs.map +2 -2
  54. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +4 -1
  55. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +3 -3
  56. package/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs +2 -2
  57. package/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs.map +2 -2
  58. package/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs +1 -1
  59. package/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs.map +3 -3
  60. package/dist-esm/lib/components/default-components/DefaultSvgDefs.mjs +2 -2
  61. package/dist-esm/lib/components/default-components/DefaultSvgDefs.mjs.map +2 -2
  62. package/dist-esm/lib/editor/Editor.mjs +123 -55
  63. package/dist-esm/lib/editor/Editor.mjs.map +3 -3
  64. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs +2 -2
  65. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
  66. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs +2 -2
  67. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
  68. package/dist-esm/lib/editor/derivations/shapeIdsInCurrentPage.mjs +2 -2
  69. package/dist-esm/lib/editor/derivations/shapeIdsInCurrentPage.mjs.map +2 -2
  70. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +8 -58
  71. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
  72. package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs +3 -3
  73. package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs.map +2 -2
  74. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +1 -2
  75. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +2 -2
  76. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs +24 -2
  77. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +2 -2
  78. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs +4 -2
  79. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs.map +2 -2
  80. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +7 -3
  81. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
  82. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +15 -2
  83. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
  84. package/dist-esm/lib/editor/overlays/strokeShapeIndicators.mjs +59 -0
  85. package/dist-esm/lib/editor/overlays/strokeShapeIndicators.mjs.map +7 -0
  86. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +3 -0
  87. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +2 -2
  88. package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
  89. package/dist-esm/lib/editor/types/event-types.mjs +0 -2
  90. package/dist-esm/lib/editor/types/event-types.mjs.map +2 -2
  91. package/dist-esm/lib/hooks/usePresence.mjs.map +2 -2
  92. package/dist-esm/lib/license/LicenseProvider.mjs +3 -1
  93. package/dist-esm/lib/license/LicenseProvider.mjs.map +2 -2
  94. package/dist-esm/lib/primitives/utils.mjs +2 -2
  95. package/dist-esm/lib/primitives/utils.mjs.map +2 -2
  96. package/dist-esm/lib/utils/dom.mjs +5 -3
  97. package/dist-esm/lib/utils/dom.mjs.map +2 -2
  98. package/dist-esm/version.mjs +3 -3
  99. package/dist-esm/version.mjs.map +1 -1
  100. package/editor.css +2 -0
  101. package/package.json +8 -8
  102. package/src/index.ts +2 -5
  103. package/src/lib/components/default-components/DefaultErrorFallback.tsx +4 -1
  104. package/src/lib/components/default-components/DefaultLoadingScreen.tsx +1 -1
  105. package/src/lib/components/default-components/DefaultShapeErrorFallback.tsx +4 -3
  106. package/src/lib/components/default-components/DefaultSvgDefs.tsx +1 -1
  107. package/src/lib/editor/Editor.ts +172 -70
  108. package/src/lib/editor/derivations/bindingsIndex.ts +1 -1
  109. package/src/lib/editor/derivations/parentsToChildren.ts +1 -1
  110. package/src/lib/editor/derivations/shapeIdsInCurrentPage.ts +1 -1
  111. package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +54 -74
  112. package/src/lib/editor/managers/ClickManager/ClickManager.ts +15 -65
  113. package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.test.ts +43 -16
  114. package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.ts +8 -5
  115. package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +4 -4
  116. package/src/lib/editor/managers/FocusManager/FocusManager.ts +1 -2
  117. package/src/lib/editor/managers/FontManager/FontManager.test.ts +13 -9
  118. package/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts +32 -0
  119. package/src/lib/editor/managers/HistoryManager/HistoryManager.ts +34 -4
  120. package/src/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.ts +9 -2
  121. package/src/lib/editor/managers/TextManager/TextManager.test.ts +16 -14
  122. package/src/lib/editor/managers/TextManager/TextManager.ts +17 -2
  123. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +12 -2
  124. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +27 -2
  125. package/src/lib/editor/overlays/strokeShapeIndicators.ts +86 -0
  126. package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +4 -0
  127. package/src/lib/editor/tools/StateNode.ts +0 -2
  128. package/src/lib/editor/types/event-types.ts +2 -6
  129. package/src/lib/hooks/usePresence.ts +2 -2
  130. package/src/lib/license/LicenseProvider.tsx +3 -1
  131. package/src/lib/primitives/utils.ts +1 -1
  132. package/src/lib/utils/dom.ts +5 -3
  133. package/src/version.ts +3 -3
  134. package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js +0 -161
  135. package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js.map +0 -7
  136. package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs +0 -141
  137. package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs.map +0 -7
  138. package/src/lib/editor/overlays/ShapeIndicatorOverlayUtil.ts +0 -216
@@ -1058,6 +1058,14 @@ class Editor extends import_eventemitter3.default {
1058
1058
  getMarkIdMatching(idSubstring) {
1059
1059
  return this.history.getMarkIdMatching(idSubstring);
1060
1060
  }
1061
+ /**
1062
+ * Whether the editor is currently replaying history (i.e. an undo or redo is being applied).
1063
+ *
1064
+ * @internal
1065
+ */
1066
+ isReplayingHistory() {
1067
+ return this.history.isReplaying();
1068
+ }
1061
1069
  /**
1062
1070
  * Coalesces all changes since the given mark into a single change, removing any intermediate marks.
1063
1071
  *
@@ -2152,7 +2160,7 @@ class Editor extends import_eventemitter3.default {
2152
2160
  return baseCamera;
2153
2161
  }
2154
2162
  _getFollowingPresence(targetUserId) {
2155
- const visited = [this.user.getId()];
2163
+ const visited = [this.user.getRecordId()];
2156
2164
  const collaborators = this.getCollaborators();
2157
2165
  let leaderPresence = null;
2158
2166
  while (targetUserId && !visited.includes(targetUserId)) {
@@ -2340,6 +2348,11 @@ class Editor extends import_eventemitter3.default {
2340
2348
  getConstrainedCamera(point, opts) {
2341
2349
  const currentCamera = this.getCamera();
2342
2350
  let { x, y, z = currentCamera.z } = point;
2351
+ const preserveFocalPoint = (current, requested, rz, z2) => {
2352
+ const cz = currentCamera.z;
2353
+ if (rz === cz) return current;
2354
+ return current + (requested - current) * (1 / z2 - 1 / cz) / (1 / rz - 1 / cz);
2355
+ };
2343
2356
  if (!opts?.force) {
2344
2357
  const cameraOptions = this.getCameraOptions();
2345
2358
  const zoomMin = cameraOptions.zoomSteps[0];
@@ -2359,14 +2372,10 @@ class Editor extends import_eventemitter3.default {
2359
2372
  z = this.getInitialZoom();
2360
2373
  }
2361
2374
  if (z < minZ || z > maxZ) {
2362
- const { x: cx, y: cy, z: cz } = currentCamera;
2363
- const cxA = -cx + vsb.w / cz / 2;
2364
- const cyA = -cy + vsb.h / cz / 2;
2375
+ const rz = z;
2365
2376
  z = (0, import_utils2.clamp)(z, minZ, maxZ);
2366
- const cxB = -cx + vsb.w / z / 2;
2367
- const cyB = -cy + vsb.h / z / 2;
2368
- x = cx + cxB - cxA;
2369
- y = cy + cyB - cyA;
2377
+ x = preserveFocalPoint(currentCamera.x, x, rz, z);
2378
+ y = preserveFocalPoint(currentCamera.y, y, rz, z);
2370
2379
  }
2371
2380
  const minX = px / z - bounds.x;
2372
2381
  const minY = py / z - bounds.y;
@@ -2435,10 +2444,10 @@ class Editor extends import_eventemitter3.default {
2435
2444
  }
2436
2445
  } else {
2437
2446
  if (z > zoomMax || z < zoomMin) {
2438
- const { x: cx, y: cy, z: cz } = currentCamera;
2447
+ const rz = z;
2439
2448
  z = (0, import_utils2.clamp)(z, zoomMin, zoomMax);
2440
- x = cx + (-cx + vsb.w / z / 2) - (-cx + vsb.w / cz / 2);
2441
- y = cy + (-cy + vsb.h / z / 2) - (-cy + vsb.h / cz / 2);
2449
+ x = preserveFocalPoint(currentCamera.x, x, rz, z);
2450
+ y = preserveFocalPoint(currentCamera.y, y, rz, z);
2442
2451
  }
2443
2452
  }
2444
2453
  }
@@ -2861,14 +2870,25 @@ class Editor extends import_eventemitter3.default {
2861
2870
  this.off("stop-camera-animation", cancel);
2862
2871
  };
2863
2872
  this.once("stop-camera-animation", cancel);
2873
+ const dirZ = direction.z ?? 0;
2864
2874
  const moveCamera = (elapsed) => {
2865
2875
  const { x: cx, y: cy, z: cz } = this.getCamera();
2866
- const movementVec = import_Vec.Vec.Mul(direction, currentSpeed * elapsed / cz);
2876
+ const dx = direction.x * (currentSpeed * elapsed) / cz;
2877
+ const dy = direction.y * (currentSpeed * elapsed) / cz;
2878
+ let newCx = cx + dx;
2879
+ let newCy = cy + dy;
2880
+ let newCz = cz;
2881
+ if (dirZ !== 0) {
2882
+ newCz = cz * (1 + dirZ * currentSpeed * elapsed);
2883
+ const center = this.getViewportScreenCenter();
2884
+ newCx += center.x / newCz - center.x / cz;
2885
+ newCy += center.y / newCz - center.y / cz;
2886
+ }
2867
2887
  currentSpeed *= 1 - friction;
2868
2888
  if (currentSpeed < speedThreshold) {
2869
2889
  cancel();
2870
2890
  } else {
2871
- this._setCamera(new import_Vec.Vec(cx + movementVec.x, cy + movementVec.y, cz));
2891
+ this._setCamera(new import_Vec.Vec(newCx, newCy, newCz));
2872
2892
  }
2873
2893
  };
2874
2894
  this.on("tick", moveCamera);
@@ -3188,7 +3208,7 @@ class Editor extends import_eventemitter3.default {
3188
3208
  */
3189
3209
  startFollowingUser(userId) {
3190
3210
  this.stopFollowingUser();
3191
- const thisUserId = this.user.getId();
3211
+ const thisUserId = this.user.getExternalId();
3192
3212
  if (!thisUserId) {
3193
3213
  console.warn("You should set the userId for the current instance before following a user");
3194
3214
  }
@@ -5892,24 +5912,40 @@ class Editor extends import_eventemitter3.default {
5892
5912
  * @public
5893
5913
  */
5894
5914
  resizeShape(shape, scale, opts = {}) {
5915
+ const partial = this.getResizeShapePartial(shape, scale, opts);
5916
+ if (partial) this.updateShapes([partial]);
5917
+ return this;
5918
+ }
5919
+ /**
5920
+ * Get the update for a resized shape without committing it to the store. Interactions that
5921
+ * resize many shapes at once use this to collect all of the updates and commit them in a
5922
+ * single batch. Returns null when there is nothing to update.
5923
+ *
5924
+ * Shapes that are rotated out of alignment with the scale axis cannot be resized with a
5925
+ * single update; those shapes are resized immediately (as `resizeShape` would do) and null
5926
+ * is returned.
5927
+ *
5928
+ * @internal
5929
+ */
5930
+ getResizeShapePartial(shape, scale, opts = {}) {
5895
5931
  const id = typeof shape === "string" ? shape : shape.id;
5896
- if (this.getIsReadonly()) return this;
5932
+ if (this.getIsReadonly()) return null;
5897
5933
  if (!Number.isFinite(scale.x)) scale = new import_Vec.Vec(1, scale.y);
5898
5934
  if (!Number.isFinite(scale.y)) scale = new import_Vec.Vec(scale.x, 1);
5899
5935
  const initialShape = opts.initialShape ?? this.getShape(id);
5900
- if (!initialShape) return this;
5936
+ if (!initialShape) return null;
5901
5937
  const scaleOrigin = opts.scaleOrigin ?? this.getShapePageBounds(id)?.center;
5902
- if (!scaleOrigin) return this;
5938
+ if (!scaleOrigin) return null;
5903
5939
  const pageTransform = opts.initialPageTransform ? import_Mat.Mat.Cast(opts.initialPageTransform) : this.getShapePageTransform(id);
5904
- if (!pageTransform) return this;
5940
+ if (!pageTransform) return null;
5905
5941
  const pageRotation = pageTransform.rotation();
5906
- if (pageRotation == null) return this;
5942
+ if (pageRotation == null) return null;
5907
5943
  const scaleAxisRotation = opts.scaleAxisRotation ?? pageRotation;
5908
5944
  const initialBounds = opts.initialBounds ?? this.getShapeGeometry(id).bounds;
5909
- if (!initialBounds) return this;
5945
+ if (!initialBounds) return null;
5910
5946
  const isAspectRatioLocked = opts.isAspectRatioLocked ?? this.getShapeUtil(initialShape).isAspectRatioLocked(initialShape);
5911
5947
  if (!(0, import_utils2.areAnglesCompatible)(pageRotation, scaleAxisRotation)) {
5912
- return this._resizeUnalignedShape(id, scale, {
5948
+ this._resizeUnalignedShape(id, scale, {
5913
5949
  ...opts,
5914
5950
  initialBounds,
5915
5951
  scaleOrigin,
@@ -5918,6 +5954,7 @@ class Editor extends import_eventemitter3.default {
5918
5954
  isAspectRatioLocked,
5919
5955
  initialShape
5920
5956
  });
5957
+ return null;
5921
5958
  }
5922
5959
  const util = this.getShapeUtil(initialShape);
5923
5960
  if (isAspectRatioLocked) {
@@ -5927,7 +5964,7 @@ class Editor extends import_eventemitter3.default {
5927
5964
  scale = new import_Vec.Vec(Math.sign(scale.x) * Math.abs(scale.y), scale.y);
5928
5965
  }
5929
5966
  }
5930
- let didResize = false;
5967
+ let workingShape = null;
5931
5968
  if (util.onResize && util.canResize(initialShape)) {
5932
5969
  const newPagePoint = this._scalePagePoint(
5933
5970
  import_Mat.Mat.applyToPoint(pageTransform, new import_Vec.Vec(0, 0)),
@@ -5945,7 +5982,7 @@ class Editor extends import_eventemitter3.default {
5945
5982
  myScale.y = areWidthAndHeightAlignedWithCorrectAxis ? scale.y : scale.x;
5946
5983
  const initialPagePoint = import_Mat.Mat.applyToPoint(pageTransform, new import_Vec.Vec());
5947
5984
  const { x, y } = this.getPointInParentSpace(initialShape.id, initialPagePoint);
5948
- let workingShape = initialShape;
5985
+ workingShape = initialShape;
5949
5986
  if (!opts.skipStartAndEndCallbacks) {
5950
5987
  workingShape = applyPartialToRecordWithProps(
5951
5988
  initialShape,
@@ -5965,9 +6002,6 @@ class Editor extends import_eventemitter3.default {
5965
6002
  initialShape
5966
6003
  }
5967
6004
  );
5968
- if (resizedShape) {
5969
- didResize = true;
5970
- }
5971
6005
  workingShape = applyPartialToRecordWithProps(workingShape, {
5972
6006
  id,
5973
6007
  type: initialShape.type,
@@ -5981,32 +6015,36 @@ class Editor extends import_eventemitter3.default {
5981
6015
  util.onResizeEnd?.(initialShape, workingShape) ?? void 0
5982
6016
  );
5983
6017
  }
5984
- this.updateShapes([workingShape]);
6018
+ if (resizedShape) {
6019
+ return workingShape;
6020
+ }
5985
6021
  }
5986
- if (!didResize) {
5987
- const initialPageCenter = import_Mat.Mat.applyToPoint(pageTransform, initialBounds.center);
5988
- const newPageCenter = this._scalePagePoint(
5989
- initialPageCenter,
5990
- scaleOrigin,
5991
- scale,
5992
- scaleAxisRotation
5993
- );
5994
- const initialPageCenterInParentSpace = this.getPointInParentSpace(
5995
- initialShape.id,
5996
- initialPageCenter
5997
- );
5998
- const newPageCenterInParentSpace = this.getPointInParentSpace(initialShape.id, newPageCenter);
5999
- const delta = import_Vec.Vec.Sub(newPageCenterInParentSpace, initialPageCenterInParentSpace);
6000
- this.updateShapes([
6001
- {
6002
- id,
6003
- type: initialShape.type,
6004
- x: initialShape.x + delta.x,
6005
- y: initialShape.y + delta.y
6006
- }
6007
- ]);
6022
+ const initialPageCenter = import_Mat.Mat.applyToPoint(pageTransform, initialBounds.center);
6023
+ const newPageCenter = this._scalePagePoint(
6024
+ initialPageCenter,
6025
+ scaleOrigin,
6026
+ scale,
6027
+ scaleAxisRotation
6028
+ );
6029
+ const initialPageCenterInParentSpace = this.getPointInParentSpace(
6030
+ initialShape.id,
6031
+ initialPageCenter
6032
+ );
6033
+ const newPageCenterInParentSpace = this.getPointInParentSpace(initialShape.id, newPageCenter);
6034
+ const delta = import_Vec.Vec.Sub(newPageCenterInParentSpace, initialPageCenterInParentSpace);
6035
+ if (workingShape) {
6036
+ return {
6037
+ ...workingShape,
6038
+ x: initialShape.x + delta.x,
6039
+ y: initialShape.y + delta.y
6040
+ };
6008
6041
  }
6009
- return this;
6042
+ return {
6043
+ id,
6044
+ type: initialShape.type,
6045
+ x: initialShape.x + delta.x,
6046
+ y: initialShape.y + delta.y
6047
+ };
6010
6048
  }
6011
6049
  /** @internal */
6012
6050
  _scalePagePoint(point, scaleOrigin, scale, scaleAxisRotation) {
@@ -7834,6 +7872,15 @@ class Editor extends import_eventemitter3.default {
7834
7872
  _didPinch = false;
7835
7873
  /** @internal */
7836
7874
  _selectedShapeIdsAtPointerDown = [];
7875
+ /**
7876
+ * Whether `_selectedShapeIdsAtPointerDown` holds a pre-gesture selection
7877
+ * captured by a `pointer_down` (the touch path) that a following pinch
7878
+ * should restore. False when no pointer_down preceded the pinch (the
7879
+ * Safari trackpad path uses gesture events), in which case `pinch_start`
7880
+ * captures the live selection instead.
7881
+ * @internal
7882
+ */
7883
+ _didCaptureSelectionAtPointerDown = false;
7837
7884
  /** @internal */
7838
7885
  _longPressTimeout = -1;
7839
7886
  /** @internal */
@@ -7966,10 +8013,15 @@ class Editor extends import_eventemitter3.default {
7966
8013
  case "pinch_start": {
7967
8014
  if (inputs.getIsPinching()) return;
7968
8015
  if (!inputs.getIsEditing()) {
7969
- this._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds];
8016
+ if (!this._didCaptureSelectionAtPointerDown) {
8017
+ this._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds];
8018
+ }
7970
8019
  this._didPinch = true;
7971
8020
  inputs.setIsPinching(true);
7972
8021
  this.interrupt();
8022
+ if (this._didCaptureSelectionAtPointerDown) {
8023
+ this.setSelectedShapes(this._selectedShapeIdsAtPointerDown);
8024
+ }
7973
8025
  }
7974
8026
  this.emit("event", info);
7975
8027
  return;
@@ -8009,6 +8061,7 @@ class Editor extends import_eventemitter3.default {
8009
8061
  const { _selectedShapeIdsAtPointerDown: shapesToReselect } = this;
8010
8062
  this.setSelectedShapes(this._selectedShapeIdsAtPointerDown);
8011
8063
  this._selectedShapeIdsAtPointerDown = [];
8064
+ this._didCaptureSelectionAtPointerDown = false;
8012
8065
  if (this._didPinch) {
8013
8066
  this._didPinch = false;
8014
8067
  if (shapesToReselect.length > 0) {
@@ -8102,12 +8155,18 @@ class Editor extends import_eventemitter3.default {
8102
8155
  });
8103
8156
  }, this.options.longPressDurationMs);
8104
8157
  }
8105
- this._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds();
8158
+ if (!this._didCaptureSelectionAtPointerDown) {
8159
+ this._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds();
8160
+ this._didCaptureSelectionAtPointerDown = true;
8161
+ }
8106
8162
  if (info.button === import_constants.LEFT_MOUSE_BUTTON) this.capturedPointerId = info.pointerId;
8107
8163
  inputs.buttons.add(info.button);
8108
8164
  inputs.setIsPointing(true);
8109
8165
  inputs.setIsDragging(false);
8110
- if (!isPenMode && isPen) this.updateInstanceState({ isPenMode: true });
8166
+ if (!isPenMode && isPen) {
8167
+ this.updateInstanceState({ isPenMode: true });
8168
+ this.interrupt();
8169
+ }
8111
8170
  if (info.button === import_constants.STYLUS_ERASER_BUTTON) {
8112
8171
  this._restoreToolId = this.getCurrentToolId();
8113
8172
  this.complete();
@@ -8175,6 +8234,7 @@ class Editor extends import_eventemitter3.default {
8175
8234
  if (this.inputs.getIsRightPointing() && !this.inputs.getIsPanning()) {
8176
8235
  this.inputs.setIsRightPointing(false);
8177
8236
  this._selectedShapeIdsAtPointerDown = [];
8237
+ this._didCaptureSelectionAtPointerDown = false;
8178
8238
  break;
8179
8239
  }
8180
8240
  this.inputs.setIsRightPointing(false);
@@ -8209,14 +8269,21 @@ class Editor extends import_eventemitter3.default {
8209
8269
  this.setCursor({ type: this._prevCursor, rotation: 0 });
8210
8270
  }
8211
8271
  if (slideSpeed > 0) {
8212
- this.slideCamera({ speed: slideSpeed, direction: slideDirection });
8272
+ this.slideCamera({
8273
+ speed: slideSpeed,
8274
+ direction: { x: slideDirection.x, y: slideDirection.y, z: 0 }
8275
+ });
8213
8276
  }
8214
8277
  this._selectedShapeIdsAtPointerDown = [];
8278
+ this._didCaptureSelectionAtPointerDown = false;
8215
8279
  return this;
8216
8280
  }
8217
8281
  }
8218
8282
  if (slideSpeed > 0) {
8219
- this.slideCamera({ speed: slideSpeed, direction: slideDirection });
8283
+ this.slideCamera({
8284
+ speed: slideSpeed,
8285
+ direction: { x: slideDirection.x, y: slideDirection.y, z: 0 }
8286
+ });
8220
8287
  }
8221
8288
  } else {
8222
8289
  if (info.button === import_constants.STYLUS_ERASER_BUTTON) {
@@ -8225,6 +8292,7 @@ class Editor extends import_eventemitter3.default {
8225
8292
  }
8226
8293
  }
8227
8294
  this._selectedShapeIdsAtPointerDown = [];
8295
+ this._didCaptureSelectionAtPointerDown = false;
8228
8296
  break;
8229
8297
  }
8230
8298
  }