UNPKG

@tldraw/editor

Version:

tldraw infinite canvas SDK (editor).

563 lines (562 loc) • 17.4 kB
"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