tldraw
Version:
A tiny little drawing editor.
8 lines (7 loc) • 8.14 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../../../src/lib/shapes/text/toolStates/Pointing.ts"],
"sourcesContent": ["import {\n\tStateNode,\n\tTLPointerEventInfo,\n\tTLShapeId,\n\tTLTextShape,\n\tVec,\n\tcreateShapeId,\n\tisShapeId,\n\tmaybeSnapToGrid,\n} from '@tldraw/editor'\n\nexport class Pointing extends StateNode {\n\tstatic override id = 'pointing'\n\n\tshape?: TLTextShape\n\n\tmarkId = ''\n\n\tenterTime = 0\n\toverride onEnter(): void {\n\t\tthis.enterTime = Date.now()\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.setHintingShapes([])\n\t}\n\n\toverride onPointerMove(info: TLPointerEventInfo) {\n\t\t// Create a fixed width shape if the user wants to do that.\n\n\t\t// Don't create a fixed width shape unless the the drag is a little larger,\n\t\t// otherwise you get a vertical column of single characters if you accidentally\n\t\t// drag a bit unintentionally.\n\n\t\t// If the user hasn't been pointing for more than 150ms, don't create a fixed width shape\n\t\tif (Date.now() - this.enterTime < 150) return\n\n\t\tconst { editor } = this\n\t\tconst { isPointing } = editor.inputs\n\n\t\tif (!isPointing) return\n\n\t\tconst { originPagePoint, currentPagePoint } = editor.inputs\n\n\t\tconst currentDragDist = Math.abs(originPagePoint.x - currentPagePoint.x)\n\n\t\tconst baseMinDragDistForFixedWidth = Math.sqrt(\n\t\t\teditor.getInstanceState().isCoarsePointer\n\t\t\t\t? editor.options.coarseDragDistanceSquared\n\t\t\t\t: editor.options.dragDistanceSquared\n\t\t)\n\n\t\t// Ten times the base drag distance for fixed width\n\t\tconst minSquaredDragDist = (baseMinDragDistForFixedWidth * 6) / editor.getZoomLevel()\n\n\t\tif (currentDragDist > minSquaredDragDist) {\n\t\t\tconst id = createShapeId()\n\t\t\tthis.markId = editor.markHistoryStoppingPoint(`creating_text:${id}`)\n\n\t\t\t// create the initial shape with the width that we've dragged\n\t\t\tconst shape = this.createTextShape(id, originPagePoint, false, currentDragDist)\n\n\t\t\tif (!shape) {\n\t\t\t\tthis.cancel()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Now save the fresh reference\n\t\t\tthis.shape = editor.getShape(shape)\n\n\t\t\teditor.select(id)\n\n\t\t\teditor.setCurrentTool('select.resizing', {\n\t\t\t\t...info,\n\t\t\t\ttarget: 'selection',\n\t\t\t\thandle: 'right',\n\t\t\t\tisCreating: true,\n\t\t\t\tcreatingMarkId: this.markId,\n\t\t\t\t// Make sure the cursor offset takes into account how far we've already dragged\n\t\t\t\tcreationCursorOffset: { x: currentDragDist, y: 1 },\n\t\t\t\tonInteractionEnd: 'text',\n\t\t\t\tonCreate: () => {\n\t\t\t\t\teditor.setEditingShape(shape.id)\n\t\t\t\t\t// this will automatically set the state to 'select.editing_shape'\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onComplete() {\n\t\tthis.cancel()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onInterrupt() {\n\t\tthis.cancel()\n\t}\n\n\tprivate complete() {\n\t\tthis.editor.markHistoryStoppingPoint('creating text shape')\n\t\tconst id = createShapeId()\n\t\tconst { originPagePoint } = this.editor.inputs\n\t\tconst shape = this.createTextShape(id, originPagePoint, true, 20)\n\t\tif (!shape) return\n\n\t\tthis.editor.select(id)\n\t\tthis.editor.setEditingShape(id)\n\t\t// this will automatically set the state to 'select.editing_shape'\n\t}\n\n\tprivate cancel() {\n\t\tthis.parent.transition('idle')\n\t\tthis.editor.bailToMark(this.markId)\n\t}\n\n\tprivate createTextShape(id: TLShapeId, point: Vec, autoSize: boolean, width: number) {\n\t\tthis.editor.createShape<TLTextShape>({\n\t\t\tid,\n\t\t\ttype: 'text',\n\t\t\tx: point.x,\n\t\t\ty: point.y,\n\t\t\tprops: {\n\t\t\t\ttext: '',\n\t\t\t\tautoSize,\n\t\t\t\tw: width,\n\t\t\t\tscale: this.editor.user.getIsDynamicResizeMode() ? 1 / this.editor.getZoomLevel() : 1,\n\t\t\t},\n\t\t})\n\n\t\tconst shape = this.editor.getShape<TLTextShape>(id)\n\t\tif (!shape) {\n\t\t\tthis.cancel()\n\t\t\treturn\n\t\t}\n\n\t\tconst bounds = this.editor.getShapePageBounds(shape)!\n\n\t\tconst delta = new Vec()\n\n\t\tif (autoSize) {\n\t\t\tswitch (shape.props.textAlign) {\n\t\t\t\tcase 'start': {\n\t\t\t\t\tdelta.x = 0\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'middle': {\n\t\t\t\t\tdelta.x = -bounds.width / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'end': {\n\t\t\t\t\tdelta.x = -bounds.width\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tdelta.x = 0\n\t\t}\n\n\t\tdelta.y = -bounds.height / 2\n\n\t\tif (isShapeId(shape.parentId)) {\n\t\t\tconst transform = this.editor.getShapeParentTransform(shape)\n\t\t\tdelta.rot(-transform.rotation())\n\t\t}\n\n\t\tconst shapeX = shape.x + delta.x\n\t\tconst shapeY = shape.y + delta.y\n\t\tif (this.editor.getInstanceState().isGridMode) {\n\t\t\tconst topLeft = new Vec(shapeX, shapeY)\n\t\t\tconst gridSnappedPoint = maybeSnapToGrid(topLeft, this.editor)\n\t\t\tconst gridDelta = Vec.Sub(topLeft, gridSnappedPoint)\n\t\t\tthis.editor.updateShape({\n\t\t\t\t...shape,\n\t\t\t\tx: shapeX - gridDelta.x,\n\t\t\t\ty: shapeY - gridDelta.y,\n\t\t\t})\n\t\t} else {\n\t\t\tthis.editor.updateShape({\n\t\t\t\t...shape,\n\t\t\t\tx: shapeX,\n\t\t\t\ty: shapeY,\n\t\t\t})\n\t\t}\n\n\t\treturn shape\n\t}\n}\n"],
"mappings": "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",
"names": []
}