@tldraw/editor
Version:
tldraw infinite canvas SDK (editor).
563 lines (562 loc) • 17.4 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __decorateClass = (decorators, target, key, kind) => {
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
for (var i = decorators.length - 1, decorator; i >= 0; i--)
if (decorator = decorators[i])
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
if (kind && result) __defProp(target, key, result);
return result;
};
var InputsManager_exports = {};
__export(InputsManager_exports, {
InputsManager: () => InputsManager
});
module.exports = __toCommonJS(InputsManager_exports);
var import_state = require("@tldraw/state");
var import_store = require("@tldraw/store");
var import_tlschema = require("@tldraw/tlschema");
var import_constants = require("../../../constants");
var import_Vec = require("../../../primitives/Vec");
var import_keyboard = require("../../../utils/keyboard");
class InputsManager {
constructor(editor) {
this.editor = editor;
}
editor;
_originPagePoint = (0, import_state.atom)("originPagePoint", new import_Vec.Vec());
/**
* The most recent pointer down's position in the current page space.
*/
getOriginPagePoint() {
return this._originPagePoint.get();
}
/**
* @deprecated Use `getOriginPagePoint()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get originPagePoint() {
return this.getOriginPagePoint();
}
_originScreenPoint = (0, import_state.atom)("originScreenPoint", new import_Vec.Vec());
/**
* The most recent pointer down's position in screen space.
*/
getOriginScreenPoint() {
return this._originScreenPoint.get();
}
/**
* @deprecated Use `getOriginScreenPoint()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get originScreenPoint() {
return this.getOriginScreenPoint();
}
_previousPagePoint = (0, import_state.atom)("previousPagePoint", new import_Vec.Vec());
/**
* The previous pointer position in the current page space.
*/
getPreviousPagePoint() {
return this._previousPagePoint.get();
}
/**
* @deprecated Use `getPreviousPagePoint()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get previousPagePoint() {
return this.getPreviousPagePoint();
}
_previousScreenPoint = (0, import_state.atom)("previousScreenPoint", new import_Vec.Vec());
/**
* The previous pointer position in screen space.
*/
getPreviousScreenPoint() {
return this._previousScreenPoint.get();
}
/**
* @deprecated Use `getPreviousScreenPoint()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get previousScreenPoint() {
return this.getPreviousScreenPoint();
}
_currentPagePoint = (0, import_state.atom)("currentPagePoint", new import_Vec.Vec());
/**
* The most recent pointer position in the current page space.
*/
getCurrentPagePoint() {
return this._currentPagePoint.get();
}
/**
* @deprecated Use `getCurrentPagePoint()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get currentPagePoint() {
return this.getCurrentPagePoint();
}
_currentScreenPoint = (0, import_state.atom)("currentScreenPoint", new import_Vec.Vec());
/**
* The most recent pointer position in screen space.
*/
getCurrentScreenPoint() {
return this._currentScreenPoint.get();
}
/**
* @deprecated Use `getCurrentScreenPoint()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get currentScreenPoint() {
return this.getCurrentScreenPoint();
}
_pointerVelocity = (0, import_state.atom)("pointerVelocity", new import_Vec.Vec());
/**
* Velocity of mouse pointer, in pixels per millisecond.
*/
getPointerVelocity() {
return this._pointerVelocity.get();
}
/**
* @deprecated Use `getPointerVelocity()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get pointerVelocity() {
return this.getPointerVelocity();
}
/**
* Normally you shouldn't need to set the pointer velocity directly, this is set by the tick manager.
* However, this is currently used in tests to fake pointer velocity.
* @param pointerVelocity - The pointer velocity.
* @internal
*/
setPointerVelocity(pointerVelocity) {
this._pointerVelocity.set(pointerVelocity);
}
/**
* A set containing the currently pressed keys.
*/
keys = new import_store.AtomSet("keys");
/**
* A set containing the currently pressed buttons.
*/
buttons = new import_store.AtomSet("buttons");
_isPen = (0, import_state.atom)("isPen", false);
/**
* Whether the input is from a pen.
*/
getIsPen() {
return this._isPen.get();
}
/**
* @deprecated Use `getIsPen()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get isPen() {
return this.getIsPen();
}
// eslint-disable-next-line tldraw/no-setter-getter
set isPen(isPen) {
this.setIsPen(isPen);
}
/**
* @param isPen - Whether the input is from a pen.
*/
setIsPen(isPen) {
this._isPen.set(isPen);
}
_shiftKey = (0, import_state.atom)("shiftKey", false);
/**
* Whether the shift key is currently pressed.
*/
getShiftKey() {
return this._shiftKey.get();
}
/**
* @deprecated Use `getShiftKey()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get shiftKey() {
return this.getShiftKey();
}
// eslint-disable-next-line tldraw/no-setter-getter
set shiftKey(shiftKey) {
this.setShiftKey(shiftKey);
}
/**
* @param shiftKey - Whether the shift key is pressed.
* @internal
*/
setShiftKey(shiftKey) {
this._shiftKey.set(shiftKey);
}
_metaKey = (0, import_state.atom)("metaKey", false);
/**
* Whether the meta key is currently pressed.
*/
getMetaKey() {
return this._metaKey.get();
}
/**
* @deprecated Use `getMetaKey()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get metaKey() {
return this.getMetaKey();
}
// eslint-disable-next-line tldraw/no-setter-getter
set metaKey(metaKey) {
this.setMetaKey(metaKey);
}
/**
* @param metaKey - Whether the meta key is pressed.
* @internal
*/
setMetaKey(metaKey) {
this._metaKey.set(metaKey);
}
_ctrlKey = (0, import_state.atom)("ctrlKey", false);
/**
* Whether the ctrl or command key is currently pressed.
*/
getCtrlKey() {
return this._ctrlKey.get();
}
/**
* @deprecated Use `getCtrlKey()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get ctrlKey() {
return this.getCtrlKey();
}
// eslint-disable-next-line tldraw/no-setter-getter
set ctrlKey(ctrlKey) {
this.setCtrlKey(ctrlKey);
}
/**
* @param ctrlKey - Whether the ctrl key is pressed.
* @internal
*/
setCtrlKey(ctrlKey) {
this._ctrlKey.set(ctrlKey);
}
_altKey = (0, import_state.atom)("altKey", false);
/**
* Whether the alt or option key is currently pressed.
*/
getAltKey() {
return this._altKey.get();
}
/**
* @deprecated Use `getAltKey()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get altKey() {
return this.getAltKey();
}
// eslint-disable-next-line tldraw/no-setter-getter
set altKey(altKey) {
this.setAltKey(altKey);
}
/**
* @param altKey - Whether the alt key is pressed.
* @internal
*/
setAltKey(altKey) {
this._altKey.set(altKey);
}
/**
* Is the accelerator key (cmd on mac, ctrl elsewhere) currently pressed.
*/
getAccelKey() {
return (0, import_keyboard.isAccelKey)({ metaKey: this.getMetaKey(), ctrlKey: this.getCtrlKey() });
}
/**
* @deprecated Use `getAccelKey()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get accelKey() {
return this.getAccelKey();
}
_isDragging = (0, import_state.atom)("isDragging", false);
/**
* Whether the user is dragging.
*/
getIsDragging() {
return this._isDragging.get();
}
/**
* Soon to be deprecated, use `getIsDragging()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get isDragging() {
return this.getIsDragging();
}
// eslint-disable-next-line tldraw/no-setter-getter
set isDragging(isDragging) {
this.setIsDragging(isDragging);
}
/**
* @param isDragging - Whether the user is dragging.
*/
setIsDragging(isDragging) {
this._isDragging.set(isDragging);
}
_isPointing = (0, import_state.atom)("isPointing", false);
/**
* Whether the user is pointing.
*/
getIsPointing() {
return this._isPointing.get();
}
/**
* @deprecated Use `getIsPointing()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get isPointing() {
return this.getIsPointing();
}
// eslint-disable-next-line tldraw/no-setter-getter
set isPointing(isPointing) {
this.setIsPointing(isPointing);
}
/**
* @param isPointing - Whether the user is pointing.
* @internal
*/
setIsPointing(isPointing) {
this._isPointing.set(isPointing);
}
_isRightPointing = (0, import_state.atom)("isRightPointing", false);
/**
* Whether the user is right-click pointing (before drag threshold).
*/
getIsRightPointing() {
return this._isRightPointing.get();
}
/** @internal */
setIsRightPointing(isRightPointing) {
this._isRightPointing.set(isRightPointing);
}
_isPinching = (0, import_state.atom)("isPinching", false);
/**
* Whether the user is pinching.
*/
getIsPinching() {
return this._isPinching.get();
}
/**
* @deprecated Use `getIsPinching()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get isPinching() {
return this.getIsPinching();
}
// eslint-disable-next-line tldraw/no-setter-getter
set isPinching(isPinching) {
this.setIsPinching(isPinching);
}
/**
* @param isPinching - Whether the user is pinching.
* @internal
*/
setIsPinching(isPinching) {
this._isPinching.set(isPinching);
}
_isEditing = (0, import_state.atom)("isEditing", false);
/**
* Whether the user is editing.
*/
getIsEditing() {
return this._isEditing.get();
}
/**
* @deprecated Use `getIsEditing()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get isEditing() {
return this.getIsEditing();
}
// eslint-disable-next-line tldraw/no-setter-getter
set isEditing(isEditing) {
this.setIsEditing(isEditing);
}
/**
* @param isEditing - Whether the user is editing.
*/
setIsEditing(isEditing) {
this._isEditing.set(isEditing);
}
_isPanning = (0, import_state.atom)("isPanning", false);
/**
* Whether the user is panning.
*/
getIsPanning() {
return this._isPanning.get();
}
/**
* @deprecated Use `getIsPanning()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get isPanning() {
return this.getIsPanning();
}
// eslint-disable-next-line tldraw/no-setter-getter
set isPanning(isPanning) {
this.setIsPanning(isPanning);
}
/**
* @param isPanning - Whether the user is panning.
* @internal
*/
setIsPanning(isPanning) {
this._isPanning.set(isPanning);
}
_isSpacebarPanning = (0, import_state.atom)("isSpacebarPanning", false);
/**
* Whether the user is spacebar panning.
*/
getIsSpacebarPanning() {
return this._isSpacebarPanning.get();
}
/**
* @deprecated Use `getIsSpacebarPanning()` instead.
*/
// eslint-disable-next-line tldraw/no-setter-getter
get isSpacebarPanning() {
return this.getIsSpacebarPanning();
}
// eslint-disable-next-line tldraw/no-setter-getter
set isSpacebarPanning(isSpacebarPanning) {
this.setIsSpacebarPanning(isSpacebarPanning);
}
/**
* @param isSpacebarPanning - Whether the user is spacebar panning.
* @internal
*/
setIsSpacebarPanning(isSpacebarPanning) {
this._isSpacebarPanning.set(isSpacebarPanning);
}
_getHasCollaborators() {
return this.editor.getCollaborators().length > 0;
}
/**
* The previous point used for velocity calculation (updated each tick, not each pointer event).
* @internal
*/
_velocityPrevPoint = new import_Vec.Vec();
/**
* Update the pointer velocity based on elapsed time. Called by the tick manager.
* @param elapsed - The time elapsed since the last tick in milliseconds.
* @internal
*/
updatePointerVelocity(elapsed) {
const currentScreenPoint = this.getCurrentScreenPoint();
const pointerVelocity = this.getPointerVelocity();
if (elapsed === 0) return;
const delta = import_Vec.Vec.Sub(currentScreenPoint, this._velocityPrevPoint);
this._velocityPrevPoint = currentScreenPoint.clone();
const length = delta.len();
const direction = length ? delta.div(length) : new import_Vec.Vec(0, 0);
const next = pointerVelocity.clone().lrp(direction.mul(length / elapsed), 0.5);
if (Math.abs(next.x) < 0.01) next.x = 0;
if (Math.abs(next.y) < 0.01) next.y = 0;
if (!pointerVelocity.equals(next)) {
this._pointerVelocity.set(next);
}
}
/**
* Update the input points from a pointer, pinch, or wheel event.
*
* @param info - The event info.
* @internal
*/
updateFromEvent(info) {
const currentScreenPoint = this._currentScreenPoint.__unsafe__getWithoutCapture();
const currentPagePoint = this._currentPagePoint.__unsafe__getWithoutCapture();
const isPinching = this._isPinching.__unsafe__getWithoutCapture();
const { screenBounds } = this.editor.store.unsafeGetWithoutCapture(import_tlschema.TLINSTANCE_ID);
const { x: cx, y: cy, z: cz } = (0, import_state.unsafe__withoutCapture)(() => this.editor.getCamera());
const sx = info.point.x - screenBounds.x;
const sy = info.point.y - screenBounds.y;
const sz = info.point.z ?? 0.5;
this._previousScreenPoint.set(currentScreenPoint);
this._previousPagePoint.set(currentPagePoint);
this._currentScreenPoint.set(new import_Vec.Vec(sx, sy));
const nx = sx / cz - cx;
const ny = sy / cz - cy;
if (isFinite(nx) && isFinite(ny)) {
this._currentPagePoint.set(new import_Vec.Vec(nx, ny, sz));
}
this._isPen.set(info.type === "pointer" && info.isPen);
if (info.name === "pointer_down" || isPinching) {
this._pointerVelocity.set(new import_Vec.Vec());
this._originScreenPoint.set(this._currentScreenPoint.__unsafe__getWithoutCapture());
this._originPagePoint.set(this._currentPagePoint.__unsafe__getWithoutCapture());
}
if (this._getHasCollaborators()) {
this.editor.run(
() => {
const pagePoint = this._currentPagePoint.__unsafe__getWithoutCapture();
this.editor.store.put([
{
id: import_tlschema.TLPOINTER_ID,
typeName: "pointer",
x: pagePoint.x,
y: pagePoint.y,
lastActivityTimestamp: (
// If our pointer moved only because we're following some other user, then don't
// update our last activity timestamp; otherwise, update it to the current timestamp.
info.type === "pointer" && info.pointerId === import_constants.INTERNAL_POINTER_IDS.CAMERA_MOVE ? this.editor.store.unsafeGetWithoutCapture(import_tlschema.TLPOINTER_ID)?.lastActivityTimestamp ?? Date.now() : Date.now()
),
meta: {}
}
]);
},
{ history: "ignore" }
);
}
}
toJson() {
return {
originPagePoint: this._originPagePoint.get().toJson(),
originScreenPoint: this._originScreenPoint.get().toJson(),
previousPagePoint: this._previousPagePoint.get().toJson(),
previousScreenPoint: this._previousScreenPoint.get().toJson(),
currentPagePoint: this._currentPagePoint.get().toJson(),
currentScreenPoint: this._currentScreenPoint.get().toJson(),
pointerVelocity: this._pointerVelocity.get().toJson(),
shiftKey: this._shiftKey.get(),
metaKey: this._metaKey.get(),
ctrlKey: this._ctrlKey.get(),
altKey: this._altKey.get(),
isPen: this._isPen.get(),
isDragging: this._isDragging.get(),
isPointing: this._isPointing.get(),
isPinching: this._isPinching.get(),
isEditing: this._isEditing.get(),
isPanning: this._isPanning.get(),
isSpacebarPanning: this._isSpacebarPanning.get(),
keys: Array.from(this.keys.keys()),
buttons: Array.from(this.buttons.keys())
};
}
}
__decorateClass([
import_state.computed
], InputsManager.prototype, "_getHasCollaborators", 1);
//# sourceMappingURL=InputsManager.js.map