UNPKG

tldraw

Version:

A tiny little drawing editor.

110 lines (83 loc) 2.52 kB
import { isAccelKey, StateNode, TLPointerEventInfo, TLShapeId } from '@tldraw/editor' export class Pointing extends StateNode { static override id = 'pointing' _isHoldingAccelKey = false override onEnter() { this._isHoldingAccelKey = isAccelKey(this.editor.inputs) const zoomLevel = this.editor.getZoomLevel() const currentPageShapesSorted = this.editor.getCurrentPageRenderingShapesSorted() const currentPagePoint = this.editor.inputs.getCurrentPagePoint() const erasing = new Set<TLShapeId>() const initialSize = erasing.size for (let n = currentPageShapesSorted.length, i = n - 1; i >= 0; i--) { const shape = currentPageShapesSorted[i] if (this.editor.isShapeOrAncestorLocked(shape) || this.editor.isShapeOfType(shape, 'group')) { continue } if ( this.editor.isPointInShape(shape, currentPagePoint, { hitInside: false, margin: this.editor.options.hitTestMargin / zoomLevel, }) ) { const hitShape = this.editor.getOutermostSelectableShape(shape) // If we've hit a frame after hitting any other shape, stop here if (this.editor.isShapeOfType(hitShape, 'frame') && erasing.size > initialSize) { break } erasing.add(hitShape.id) // If the user is holding the meta / ctrl key, stop after the first shape if (this._isHoldingAccelKey) { break } } } this.editor.setErasingShapes([...erasing]) } override onKeyUp() { this._isHoldingAccelKey = isAccelKey(this.editor.inputs) } override onKeyDown() { this._isHoldingAccelKey = isAccelKey(this.editor.inputs) } override onLongPress(info: TLPointerEventInfo) { this.startErasing(info) } override onExit(_info: any, to: string) { if (to !== 'erasing') { this.editor.setErasingShapes([]) } } override onPointerMove(info: TLPointerEventInfo) { if (this._isHoldingAccelKey) return if (this.editor.inputs.getIsDragging()) { this.startErasing(info) } } override onPointerUp() { this.complete() } override onCancel() { this.cancel() } override onComplete() { this.complete() } override onInterrupt() { this.cancel() } private startErasing(info: TLPointerEventInfo) { this.parent.transition('erasing', info) } complete() { const erasingShapeIds = this.editor.getErasingShapeIds() if (erasingShapeIds.length) { this.editor.markHistoryStoppingPoint('erase end') this.editor.deleteShapes(erasingShapeIds) } this.parent.transition('idle') } cancel() { this.parent.transition('idle') } }