UNPKG

@tldraw/editor

Version:

tldraw infinite canvas SDK (editor).

184 lines (183 loc) • 6.48 kB
import { useValue } from "@tldraw/state-react"; import { useEffect, useMemo } from "react"; import { tlenv } from "../globals/environment.mjs"; import { elementShouldCaptureKeys, preventDefault, releasePointerCapture, setPointerCapture } from "../utils/dom.mjs"; import { getPointerInfo } from "../utils/getPointerInfo.mjs"; import { useEditor } from "./useEditor.mjs"; function useCanvasEvents() { const editor = useEditor(); const ownerDocument = editor.getContainerDocument(); const currentTool = useValue("current tool", () => editor.getCurrentTool(), [editor]); const events = useMemo( function canvasEvents() { function onPointerDown(e) { if (editor.wasEventAlreadyHandled(e)) return; if (e.button === 2 && !editor.options.rightClickPanning) { editor.dispatch({ type: "pointer", target: "canvas", name: "right_click", ...getPointerInfo(editor, e) }); return; } if (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return; setPointerCapture(e.currentTarget, e); editor.dispatch({ type: "pointer", target: "canvas", name: "pointer_down", ...getPointerInfo(editor, e) }); } function onPointerUp(e) { if (editor.wasEventAlreadyHandled(e)) return; if (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return; const rightClickPanning = editor.options.rightClickPanning; const wasRightClickPanning = rightClickPanning && e.button === 2 && editor.inputs.getIsPanning(); releasePointerCapture(e.currentTarget, e); editor.dispatch({ type: "pointer", target: "canvas", name: "pointer_up", ...getPointerInfo(editor, e) }); if (rightClickPanning && e.button === 2 && !wasRightClickPanning) { const contextMenuEvent = new PointerEvent("contextmenu", { bubbles: true, clientX: e.clientX, clientY: e.clientY, button: 2, buttons: 0, pointerId: e.pointerId, pointerType: e.pointerType, isPrimary: e.isPrimary }); e.currentTarget.dispatchEvent(contextMenuEvent); } } function onPointerEnter(e) { if (editor.wasEventAlreadyHandled(e)) return; if (editor.getInstanceState().isPenMode && e.pointerType !== "pen") return; const canHover = e.pointerType === "mouse" || e.pointerType === "pen"; editor.updateInstanceState({ isHoveringCanvas: canHover ? true : null }); } function onPointerLeave(e) { if (editor.wasEventAlreadyHandled(e)) return; if (editor.getInstanceState().isPenMode && e.pointerType !== "pen") return; const canHover = e.pointerType === "mouse" || e.pointerType === "pen"; editor.updateInstanceState({ isHoveringCanvas: canHover ? false : null }); } function onTouchStart(e) { if (editor.wasEventAlreadyHandled(e)) return; editor.markEventAsHandled(e); preventDefault(e); } function onTouchEnd(e) { if (editor.wasEventAlreadyHandled(e)) return; editor.markEventAsHandled(e); if (!(e.target instanceof editor.getContainerWindow().HTMLElement)) return; const editingShapeId = editor.getEditingShapeId(); if ( // if the target is not inside the editing shape !(editingShapeId && e.target.closest(`[data-shape-id="${editingShapeId}"]`)) && // and the target is not an clickable element e.target.tagName !== "A" && // and the target is not an editable element !elementShouldCaptureKeys(e.target, false) ) { preventDefault(e); } } function onDragOver(e) { if (editor.wasEventAlreadyHandled(e)) return; preventDefault(e); } async function onDrop(e) { if (editor.wasEventAlreadyHandled(e)) return; preventDefault(e); e.stopPropagation(); const pagePoint = editor.screenToPage({ x: e.clientX, y: e.clientY }); if (editor.options.experimental__onDropOnCanvas) { const handled = editor.options.experimental__onDropOnCanvas({ point: pagePoint, event: e }); if (handled) return; } if (e.dataTransfer?.files?.length) { const files = Array.from(e.dataTransfer.files); await editor.putExternalContent({ type: "files", files, point: pagePoint }); return; } const url = e.dataTransfer.getData("url"); if (url) { await editor.putExternalContent({ type: "url", url, point: pagePoint }); return; } } function onClick(e) { if (editor.wasEventAlreadyHandled(e)) return; e.stopPropagation(); } function onContextMenu(e) { if (!editor.options.rightClickPanning) return; if (!e.nativeEvent.isTrusted) return; if (e.button !== 2 || e.ctrlKey) return; preventDefault(e); } return { onPointerDown, onPointerUp, onPointerEnter, onPointerLeave, onDragOver, onDrop, onTouchStart, onTouchEnd, onClick, onContextMenu }; }, [editor] ); useEffect(() => { let lastX, lastY; function onPointerMove(e) { if (editor.wasEventAlreadyHandled(e)) return; editor.markEventAsHandled(e); if (e.clientX === lastX && e.clientY === lastY) return; lastX = e.clientX; lastY = e.clientY; const events2 = !tlenv.isIos && currentTool.useCoalescedEvents && e.getCoalescedEvents ? e.getCoalescedEvents() : [e]; for (const singleEvent of events2) { editor.dispatch({ type: "pointer", target: "canvas", name: "pointer_move", ...getPointerInfo(editor, singleEvent) }); } } ownerDocument.body.addEventListener("pointermove", onPointerMove); return () => { ownerDocument.body.removeEventListener("pointermove", onPointerMove); }; }, [editor, currentTool, ownerDocument]); return events; } export { useCanvasEvents }; //# sourceMappingURL=useCanvasEvents.mjs.map