@tldraw/editor 5.2.0-next.355d68cf24e8 → 5.2.0-next.43d958280e72
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.
- package/README.md +7 -1
- package/dist-cjs/index.d.ts +44 -40
- package/dist-cjs/index.js +4 -4
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/components/MenuClickCapture.js +8 -5
- package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +91 -44
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js +3 -3
- package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js +24 -2
- package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +14 -3
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js +4 -2
- package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +7 -3
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +0 -1
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +15 -2
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/editor/overlays/strokeShapeIndicators.js +79 -0
- package/dist-cjs/lib/editor/overlays/strokeShapeIndicators.js.map +7 -0
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +3 -0
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +14 -7
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePresence.js.map +2 -2
- package/dist-cjs/lib/utils/getPointerInfo.js +2 -1
- package/dist-cjs/lib/utils/getPointerInfo.js.map +2 -2
- package/dist-cjs/lib/utils/pointer.js +32 -0
- package/dist-cjs/lib/utils/pointer.js.map +7 -0
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +44 -40
- package/dist-esm/index.mjs +5 -7
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/components/MenuClickCapture.mjs +8 -5
- package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +91 -44
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs +3 -3
- package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs +24 -2
- package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +14 -3
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs +4 -2
- package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +7 -3
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +0 -1
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +15 -2
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/editor/overlays/strokeShapeIndicators.mjs +59 -0
- package/dist-esm/lib/editor/overlays/strokeShapeIndicators.mjs.map +7 -0
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +3 -0
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +14 -7
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePresence.mjs.map +2 -2
- package/dist-esm/lib/utils/getPointerInfo.mjs +2 -1
- package/dist-esm/lib/utils/getPointerInfo.mjs.map +2 -2
- package/dist-esm/lib/utils/pointer.mjs +12 -0
- package/dist-esm/lib/utils/pointer.mjs.map +7 -0
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +5 -3
- package/package.json +8 -8
- package/src/index.ts +2 -5
- package/src/lib/components/MenuClickCapture.tsx +8 -4
- package/src/lib/editor/Editor.ts +115 -53
- package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.test.ts +43 -16
- package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.ts +8 -5
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +13 -9
- package/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts +32 -0
- package/src/lib/editor/managers/HistoryManager/HistoryManager.ts +34 -4
- package/src/lib/editor/managers/InputsManager/InputsManager.test.ts +61 -0
- package/src/lib/editor/managers/InputsManager/InputsManager.ts +16 -4
- package/src/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.ts +9 -2
- package/src/lib/editor/managers/TextManager/TextManager.test.ts +16 -14
- package/src/lib/editor/managers/TextManager/TextManager.ts +17 -2
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +0 -40
- package/src/lib/editor/managers/TickManager/TickManager.ts +0 -1
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +12 -2
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +27 -2
- package/src/lib/editor/overlays/strokeShapeIndicators.ts +86 -0
- package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +4 -0
- package/src/lib/hooks/useCanvasEvents.ts +19 -12
- package/src/lib/hooks/usePresence.ts +2 -2
- package/src/lib/utils/getPointerInfo.ts +2 -1
- package/src/lib/utils/pointer.test.ts +48 -0
- package/src/lib/utils/pointer.ts +18 -0
- package/src/version.ts +3 -3
- package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js +0 -161
- package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js.map +0 -7
- package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs +0 -141
- package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs.map +0 -7
- package/src/lib/editor/overlays/ShapeIndicatorOverlayUtil.ts +0 -216
|
@@ -188,12 +188,12 @@ class Editor extends EventEmitter {
|
|
|
188
188
|
this._tickManager = new TickManager(this);
|
|
189
189
|
this.disposables.add(() => this._tickManager.dispose());
|
|
190
190
|
this.disposables.add(() => {
|
|
191
|
-
this.off("tick", this._decayCameraStateTimeout);
|
|
192
191
|
this._setCameraState("idle");
|
|
193
192
|
});
|
|
194
193
|
this.fonts = new FontManager(this, fontAssetUrls);
|
|
195
194
|
this.disposables.add(() => this.fonts.dispose());
|
|
196
195
|
this.inputs = new InputsManager(this);
|
|
196
|
+
this.disposables.add(() => this.inputs.dispose());
|
|
197
197
|
this.performance = new PerformanceManager(this);
|
|
198
198
|
this.disposables.add(() => this.performance.dispose());
|
|
199
199
|
this.collaborators = new CollaboratorsManager(this);
|
|
@@ -822,6 +822,7 @@ class Editor extends EventEmitter {
|
|
|
822
822
|
this.store.dispose();
|
|
823
823
|
this.isDisposed = true;
|
|
824
824
|
this.emit("dispose");
|
|
825
|
+
this.removeAllListeners();
|
|
825
826
|
}
|
|
826
827
|
/* ------------------ Themes (shadowing the theme manager) ------------------ */
|
|
827
828
|
/**
|
|
@@ -1091,6 +1092,14 @@ class Editor extends EventEmitter {
|
|
|
1091
1092
|
getMarkIdMatching(idSubstring) {
|
|
1092
1093
|
return this.history.getMarkIdMatching(idSubstring);
|
|
1093
1094
|
}
|
|
1095
|
+
/**
|
|
1096
|
+
* Whether the editor is currently replaying history (i.e. an undo or redo is being applied).
|
|
1097
|
+
*
|
|
1098
|
+
* @internal
|
|
1099
|
+
*/
|
|
1100
|
+
isReplayingHistory() {
|
|
1101
|
+
return this.history.isReplaying();
|
|
1102
|
+
}
|
|
1094
1103
|
/**
|
|
1095
1104
|
* Coalesces all changes since the given mark into a single change, removing any intermediate marks.
|
|
1096
1105
|
*
|
|
@@ -2185,7 +2194,7 @@ class Editor extends EventEmitter {
|
|
|
2185
2194
|
return baseCamera;
|
|
2186
2195
|
}
|
|
2187
2196
|
_getFollowingPresence(targetUserId) {
|
|
2188
|
-
const visited = [this.user.
|
|
2197
|
+
const visited = [this.user.getRecordId()];
|
|
2189
2198
|
const collaborators = this.getCollaborators();
|
|
2190
2199
|
let leaderPresence = null;
|
|
2191
2200
|
while (targetUserId && !visited.includes(targetUserId)) {
|
|
@@ -2895,14 +2904,25 @@ class Editor extends EventEmitter {
|
|
|
2895
2904
|
this.off("stop-camera-animation", cancel);
|
|
2896
2905
|
};
|
|
2897
2906
|
this.once("stop-camera-animation", cancel);
|
|
2907
|
+
const dirZ = direction.z ?? 0;
|
|
2898
2908
|
const moveCamera = (elapsed) => {
|
|
2899
2909
|
const { x: cx, y: cy, z: cz } = this.getCamera();
|
|
2900
|
-
const
|
|
2910
|
+
const dx = direction.x * (currentSpeed * elapsed) / cz;
|
|
2911
|
+
const dy = direction.y * (currentSpeed * elapsed) / cz;
|
|
2912
|
+
let newCx = cx + dx;
|
|
2913
|
+
let newCy = cy + dy;
|
|
2914
|
+
let newCz = cz;
|
|
2915
|
+
if (dirZ !== 0) {
|
|
2916
|
+
newCz = cz * (1 + dirZ * currentSpeed * elapsed);
|
|
2917
|
+
const center = this.getViewportScreenCenter();
|
|
2918
|
+
newCx += center.x / newCz - center.x / cz;
|
|
2919
|
+
newCy += center.y / newCz - center.y / cz;
|
|
2920
|
+
}
|
|
2901
2921
|
currentSpeed *= 1 - friction;
|
|
2902
2922
|
if (currentSpeed < speedThreshold) {
|
|
2903
2923
|
cancel();
|
|
2904
2924
|
} else {
|
|
2905
|
-
this._setCamera(new Vec(
|
|
2925
|
+
this._setCamera(new Vec(newCx, newCy, newCz));
|
|
2906
2926
|
}
|
|
2907
2927
|
};
|
|
2908
2928
|
this.on("tick", moveCamera);
|
|
@@ -3222,7 +3242,7 @@ class Editor extends EventEmitter {
|
|
|
3222
3242
|
*/
|
|
3223
3243
|
startFollowingUser(userId) {
|
|
3224
3244
|
this.stopFollowingUser();
|
|
3225
|
-
const thisUserId = this.user.
|
|
3245
|
+
const thisUserId = this.user.getExternalId();
|
|
3226
3246
|
if (!thisUserId) {
|
|
3227
3247
|
console.warn("You should set the userId for the current instance before following a user");
|
|
3228
3248
|
}
|
|
@@ -5926,24 +5946,40 @@ class Editor extends EventEmitter {
|
|
|
5926
5946
|
* @public
|
|
5927
5947
|
*/
|
|
5928
5948
|
resizeShape(shape, scale, opts = {}) {
|
|
5949
|
+
const partial = this.getResizeShapePartial(shape, scale, opts);
|
|
5950
|
+
if (partial) this.updateShapes([partial]);
|
|
5951
|
+
return this;
|
|
5952
|
+
}
|
|
5953
|
+
/**
|
|
5954
|
+
* Get the update for a resized shape without committing it to the store. Interactions that
|
|
5955
|
+
* resize many shapes at once use this to collect all of the updates and commit them in a
|
|
5956
|
+
* single batch. Returns null when there is nothing to update.
|
|
5957
|
+
*
|
|
5958
|
+
* Shapes that are rotated out of alignment with the scale axis cannot be resized with a
|
|
5959
|
+
* single update; those shapes are resized immediately (as `resizeShape` would do) and null
|
|
5960
|
+
* is returned.
|
|
5961
|
+
*
|
|
5962
|
+
* @internal
|
|
5963
|
+
*/
|
|
5964
|
+
getResizeShapePartial(shape, scale, opts = {}) {
|
|
5929
5965
|
const id = typeof shape === "string" ? shape : shape.id;
|
|
5930
|
-
if (this.getIsReadonly()) return
|
|
5966
|
+
if (this.getIsReadonly()) return null;
|
|
5931
5967
|
if (!Number.isFinite(scale.x)) scale = new Vec(1, scale.y);
|
|
5932
5968
|
if (!Number.isFinite(scale.y)) scale = new Vec(scale.x, 1);
|
|
5933
5969
|
const initialShape = opts.initialShape ?? this.getShape(id);
|
|
5934
|
-
if (!initialShape) return
|
|
5970
|
+
if (!initialShape) return null;
|
|
5935
5971
|
const scaleOrigin = opts.scaleOrigin ?? this.getShapePageBounds(id)?.center;
|
|
5936
|
-
if (!scaleOrigin) return
|
|
5972
|
+
if (!scaleOrigin) return null;
|
|
5937
5973
|
const pageTransform = opts.initialPageTransform ? Mat.Cast(opts.initialPageTransform) : this.getShapePageTransform(id);
|
|
5938
|
-
if (!pageTransform) return
|
|
5974
|
+
if (!pageTransform) return null;
|
|
5939
5975
|
const pageRotation = pageTransform.rotation();
|
|
5940
|
-
if (pageRotation == null) return
|
|
5976
|
+
if (pageRotation == null) return null;
|
|
5941
5977
|
const scaleAxisRotation = opts.scaleAxisRotation ?? pageRotation;
|
|
5942
5978
|
const initialBounds = opts.initialBounds ?? this.getShapeGeometry(id).bounds;
|
|
5943
|
-
if (!initialBounds) return
|
|
5979
|
+
if (!initialBounds) return null;
|
|
5944
5980
|
const isAspectRatioLocked = opts.isAspectRatioLocked ?? this.getShapeUtil(initialShape).isAspectRatioLocked(initialShape);
|
|
5945
5981
|
if (!areAnglesCompatible(pageRotation, scaleAxisRotation)) {
|
|
5946
|
-
|
|
5982
|
+
this._resizeUnalignedShape(id, scale, {
|
|
5947
5983
|
...opts,
|
|
5948
5984
|
initialBounds,
|
|
5949
5985
|
scaleOrigin,
|
|
@@ -5952,6 +5988,7 @@ class Editor extends EventEmitter {
|
|
|
5952
5988
|
isAspectRatioLocked,
|
|
5953
5989
|
initialShape
|
|
5954
5990
|
});
|
|
5991
|
+
return null;
|
|
5955
5992
|
}
|
|
5956
5993
|
const util = this.getShapeUtil(initialShape);
|
|
5957
5994
|
if (isAspectRatioLocked) {
|
|
@@ -5961,7 +5998,7 @@ class Editor extends EventEmitter {
|
|
|
5961
5998
|
scale = new Vec(Math.sign(scale.x) * Math.abs(scale.y), scale.y);
|
|
5962
5999
|
}
|
|
5963
6000
|
}
|
|
5964
|
-
let
|
|
6001
|
+
let workingShape = null;
|
|
5965
6002
|
if (util.onResize && util.canResize(initialShape)) {
|
|
5966
6003
|
const newPagePoint = this._scalePagePoint(
|
|
5967
6004
|
Mat.applyToPoint(pageTransform, new Vec(0, 0)),
|
|
@@ -5979,7 +6016,7 @@ class Editor extends EventEmitter {
|
|
|
5979
6016
|
myScale.y = areWidthAndHeightAlignedWithCorrectAxis ? scale.y : scale.x;
|
|
5980
6017
|
const initialPagePoint = Mat.applyToPoint(pageTransform, new Vec());
|
|
5981
6018
|
const { x, y } = this.getPointInParentSpace(initialShape.id, initialPagePoint);
|
|
5982
|
-
|
|
6019
|
+
workingShape = initialShape;
|
|
5983
6020
|
if (!opts.skipStartAndEndCallbacks) {
|
|
5984
6021
|
workingShape = applyPartialToRecordWithProps(
|
|
5985
6022
|
initialShape,
|
|
@@ -5999,9 +6036,6 @@ class Editor extends EventEmitter {
|
|
|
5999
6036
|
initialShape
|
|
6000
6037
|
}
|
|
6001
6038
|
);
|
|
6002
|
-
if (resizedShape) {
|
|
6003
|
-
didResize = true;
|
|
6004
|
-
}
|
|
6005
6039
|
workingShape = applyPartialToRecordWithProps(workingShape, {
|
|
6006
6040
|
id,
|
|
6007
6041
|
type: initialShape.type,
|
|
@@ -6015,32 +6049,36 @@ class Editor extends EventEmitter {
|
|
|
6015
6049
|
util.onResizeEnd?.(initialShape, workingShape) ?? void 0
|
|
6016
6050
|
);
|
|
6017
6051
|
}
|
|
6018
|
-
|
|
6052
|
+
if (resizedShape) {
|
|
6053
|
+
return workingShape;
|
|
6054
|
+
}
|
|
6019
6055
|
}
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
y: initialShape.y + delta.y
|
|
6040
|
-
}
|
|
6041
|
-
]);
|
|
6056
|
+
const initialPageCenter = Mat.applyToPoint(pageTransform, initialBounds.center);
|
|
6057
|
+
const newPageCenter = this._scalePagePoint(
|
|
6058
|
+
initialPageCenter,
|
|
6059
|
+
scaleOrigin,
|
|
6060
|
+
scale,
|
|
6061
|
+
scaleAxisRotation
|
|
6062
|
+
);
|
|
6063
|
+
const initialPageCenterInParentSpace = this.getPointInParentSpace(
|
|
6064
|
+
initialShape.id,
|
|
6065
|
+
initialPageCenter
|
|
6066
|
+
);
|
|
6067
|
+
const newPageCenterInParentSpace = this.getPointInParentSpace(initialShape.id, newPageCenter);
|
|
6068
|
+
const delta = Vec.Sub(newPageCenterInParentSpace, initialPageCenterInParentSpace);
|
|
6069
|
+
if (workingShape) {
|
|
6070
|
+
return {
|
|
6071
|
+
...workingShape,
|
|
6072
|
+
x: initialShape.x + delta.x,
|
|
6073
|
+
y: initialShape.y + delta.y
|
|
6074
|
+
};
|
|
6042
6075
|
}
|
|
6043
|
-
return
|
|
6076
|
+
return {
|
|
6077
|
+
id,
|
|
6078
|
+
type: initialShape.type,
|
|
6079
|
+
x: initialShape.x + delta.x,
|
|
6080
|
+
y: initialShape.y + delta.y
|
|
6081
|
+
};
|
|
6044
6082
|
}
|
|
6045
6083
|
/** @internal */
|
|
6046
6084
|
_scalePagePoint(point, scaleOrigin, scale, scaleAxisRotation) {
|
|
@@ -8159,7 +8197,10 @@ class Editor extends EventEmitter {
|
|
|
8159
8197
|
inputs.buttons.add(info.button);
|
|
8160
8198
|
inputs.setIsPointing(true);
|
|
8161
8199
|
inputs.setIsDragging(false);
|
|
8162
|
-
if (!isPenMode && isPen)
|
|
8200
|
+
if (!isPenMode && isPen) {
|
|
8201
|
+
this.updateInstanceState({ isPenMode: true });
|
|
8202
|
+
this.interrupt();
|
|
8203
|
+
}
|
|
8163
8204
|
if (info.button === STYLUS_ERASER_BUTTON) {
|
|
8164
8205
|
this._restoreToolId = this.getCurrentToolId();
|
|
8165
8206
|
this.complete();
|
|
@@ -8262,7 +8303,10 @@ class Editor extends EventEmitter {
|
|
|
8262
8303
|
this.setCursor({ type: this._prevCursor, rotation: 0 });
|
|
8263
8304
|
}
|
|
8264
8305
|
if (slideSpeed > 0) {
|
|
8265
|
-
this.slideCamera({
|
|
8306
|
+
this.slideCamera({
|
|
8307
|
+
speed: slideSpeed,
|
|
8308
|
+
direction: { x: slideDirection.x, y: slideDirection.y, z: 0 }
|
|
8309
|
+
});
|
|
8266
8310
|
}
|
|
8267
8311
|
this._selectedShapeIdsAtPointerDown = [];
|
|
8268
8312
|
this._didCaptureSelectionAtPointerDown = false;
|
|
@@ -8270,7 +8314,10 @@ class Editor extends EventEmitter {
|
|
|
8270
8314
|
}
|
|
8271
8315
|
}
|
|
8272
8316
|
if (slideSpeed > 0) {
|
|
8273
|
-
this.slideCamera({
|
|
8317
|
+
this.slideCamera({
|
|
8318
|
+
speed: slideSpeed,
|
|
8319
|
+
direction: { x: slideDirection.x, y: slideDirection.y, z: 0 }
|
|
8320
|
+
});
|
|
8274
8321
|
}
|
|
8275
8322
|
} else {
|
|
8276
8323
|
if (info.button === STYLUS_ERASER_BUTTON) {
|