UNPKG

tldraw

Version:

A tiny little drawing editor.

120 lines (119 loc) 3.79 kB
import { StateNode, Vec, getPointInArcT } from "@tldraw/editor"; import { getArrowInfo } from "../../../shapes/arrow/shared.mjs"; class PointingArrowLabel extends StateNode { static id = "pointing_arrow_label"; shapeId = ""; markId = ""; wasAlreadySelected = false; didDrag = false; didCtrlOnEnter = false; info = {}; updateCursor() { this.editor.setCursor({ type: "grabbing", rotation: 0 }); } onEnter(info) { const { shape } = info; this.parent.setCurrentToolIdMask(info.onInteractionEnd); this.info = info; this.shapeId = shape.id; this.didDrag = false; this.didCtrlOnEnter = info.accelKey; this.wasAlreadySelected = this.editor.getOnlySelectedShapeId() === shape.id; this.updateCursor(); const geometry = this.editor.getShapeGeometry(shape); const labelGeometry = geometry.children[1]; if (!labelGeometry) { throw Error(`Expected to find an arrow label geometry for shape: ${shape.id}`); } const { currentPagePoint } = this.editor.inputs; const pointInShapeSpace = this.editor.getPointInShapeSpace(shape, currentPagePoint); this._labelDragOffset = Vec.Sub(labelGeometry.center, pointInShapeSpace); this.markId = this.editor.markHistoryStoppingPoint("label-drag start"); this.editor.setSelectedShapes([this.shapeId]); } onExit() { this.parent.setCurrentToolIdMask(void 0); this.editor.setCursor({ type: "default", rotation: 0 }); } _labelDragOffset = new Vec(0, 0); onPointerMove() { const { isDragging } = this.editor.inputs; if (!isDragging) return; if (this.didCtrlOnEnter) { this.parent.transition("brushing", this.info); return; } const shape = this.editor.getShape(this.shapeId); if (!shape) return; const info = getArrowInfo(this.editor, shape); const groupGeometry = this.editor.getShapeGeometry(shape); const bodyGeometry = groupGeometry.children[0]; const pointInShapeSpace = this.editor.getPointInShapeSpace( shape, this.editor.inputs.currentPagePoint ); const nearestPoint = bodyGeometry.nearestPoint( Vec.Add(pointInShapeSpace, this._labelDragOffset) ); let nextLabelPosition; if (info.isStraight) { const lineLength = Vec.Dist(info.start.point, info.end.point); const segmentLength = Vec.Dist(info.end.point, nearestPoint); nextLabelPosition = 1 - segmentLength / lineLength; } else { const { _center, measure, angleEnd, angleStart } = groupGeometry.children[0]; nextLabelPosition = getPointInArcT(measure, angleStart, angleEnd, _center.angle(nearestPoint)); } if (isNaN(nextLabelPosition)) { nextLabelPosition = 0.5; } this.didDrag = true; this.editor.updateShape({ id: shape.id, type: shape.type, props: { labelPosition: nextLabelPosition } }); } onPointerUp() { const shape = this.editor.getShape(this.shapeId); if (!shape) return; if (this.didDrag || !this.wasAlreadySelected) { this.complete(); } else if (!this.editor.getIsReadonly()) { this.editor.setEditingShape(shape.id); this.editor.setCurrentTool("select.editing_shape"); } } onCancel() { this.cancel(); } onComplete() { this.cancel(); } onInterrupt() { this.cancel(); } complete() { if (this.info.onInteractionEnd) { this.editor.setCurrentTool(this.info.onInteractionEnd, {}); } else { this.parent.transition("idle"); } } cancel() { this.editor.bailToMark(this.markId); if (this.info.onInteractionEnd) { this.editor.setCurrentTool(this.info.onInteractionEnd, {}); } else { this.parent.transition("idle"); } } } export { PointingArrowLabel }; //# sourceMappingURL=PointingArrowLabel.mjs.map