UNPKG

tldraw

Version:

A tiny little drawing editor.

148 lines (147 loc) 4.02 kB
import { StateNode, Vec, createShapeId, isShapeId, maybeSnapToGrid } from "@tldraw/editor"; class Pointing extends StateNode { static id = "pointing"; shape; markId = ""; enterTime = 0; onEnter() { this.enterTime = Date.now(); } onExit() { this.editor.setHintingShapes([]); } onPointerMove(info) { if (Date.now() - this.enterTime < 150) return; const { editor } = this; const { isPointing } = editor.inputs; if (!isPointing) return; const { originPagePoint, currentPagePoint } = editor.inputs; const currentDragDist = Math.abs(originPagePoint.x - currentPagePoint.x); const baseMinDragDistForFixedWidth = Math.sqrt( editor.getInstanceState().isCoarsePointer ? editor.options.coarseDragDistanceSquared : editor.options.dragDistanceSquared ); const minSquaredDragDist = baseMinDragDistForFixedWidth * 6 / editor.getZoomLevel(); if (currentDragDist > minSquaredDragDist) { const id = createShapeId(); this.markId = editor.markHistoryStoppingPoint(`creating_text:${id}`); const shape = this.createTextShape(id, originPagePoint, false, currentDragDist); if (!shape) { this.cancel(); return; } this.shape = editor.getShape(shape); editor.select(id); editor.setCurrentTool("select.resizing", { ...info, target: "selection", handle: "right", isCreating: true, creatingMarkId: this.markId, // Make sure the cursor offset takes into account how far we've already dragged creationCursorOffset: { x: currentDragDist, y: 1 }, onInteractionEnd: "text", onCreate: () => { editor.setEditingShape(shape.id); } }); } } onPointerUp() { this.complete(); } onComplete() { this.cancel(); } onCancel() { this.cancel(); } onInterrupt() { this.cancel(); } complete() { this.editor.markHistoryStoppingPoint("creating text shape"); const id = createShapeId(); const { originPagePoint } = this.editor.inputs; const shape = this.createTextShape(id, originPagePoint, true, 20); if (!shape) return; this.editor.select(id); this.editor.setEditingShape(id); } cancel() { this.parent.transition("idle"); this.editor.bailToMark(this.markId); } createTextShape(id, point, autoSize, width) { this.editor.createShape({ id, type: "text", x: point.x, y: point.y, props: { text: "", autoSize, w: width, scale: this.editor.user.getIsDynamicResizeMode() ? 1 / this.editor.getZoomLevel() : 1 } }); const shape = this.editor.getShape(id); if (!shape) { this.cancel(); return; } const bounds = this.editor.getShapePageBounds(shape); const delta = new Vec(); if (autoSize) { switch (shape.props.textAlign) { case "start": { delta.x = 0; break; } case "middle": { delta.x = -bounds.width / 2; break; } case "end": { delta.x = -bounds.width; break; } } } else { delta.x = 0; } delta.y = -bounds.height / 2; if (isShapeId(shape.parentId)) { const transform = this.editor.getShapeParentTransform(shape); delta.rot(-transform.rotation()); } const shapeX = shape.x + delta.x; const shapeY = shape.y + delta.y; if (this.editor.getInstanceState().isGridMode) { const topLeft = new Vec(shapeX, shapeY); const gridSnappedPoint = maybeSnapToGrid(topLeft, this.editor); const gridDelta = Vec.Sub(topLeft, gridSnappedPoint); this.editor.updateShape({ ...shape, x: shapeX - gridDelta.x, y: shapeY - gridDelta.y }); } else { this.editor.updateShape({ ...shape, x: shapeX, y: shapeY }); } return shape; } } export { Pointing }; //# sourceMappingURL=Pointing.mjs.map