UNPKG

@tldraw/editor

Version:

tldraw infinite canvas SDK (editor).

144 lines (143 loc) 4.76 kB
import { useValue } from "@tldraw/state-react"; import { useMemo } from "react"; import { RIGHT_MOUSE_BUTTON } from "../constants.mjs"; import { preventDefault, releasePointerCapture, setPointerCapture, stopEventPropagation } from "../utils/dom.mjs"; import { getPointerInfo } from "../utils/getPointerInfo.mjs"; import { useEditor } from "./useEditor.mjs"; function useCanvasEvents() { const editor = useEditor(); const currentTool = useValue("current tool", () => editor.getCurrentTool(), [editor]); const events = useMemo( function canvasEvents() { let lastX, lastY; function onPointerDown(e) { if (e.isKilled) return; if (e.button === RIGHT_MOUSE_BUTTON) { editor.dispatch({ type: "pointer", target: "canvas", name: "right_click", ...getPointerInfo(e) }); return; } if (e.button !== 0 && e.button !== 1 && e.button !== 5) return; setPointerCapture(e.currentTarget, e); editor.dispatch({ type: "pointer", target: "canvas", name: "pointer_down", ...getPointerInfo(e) }); } function onPointerMove(e) { if (e.isKilled) return; if (e.clientX === lastX && e.clientY === lastY) return; lastX = e.clientX; lastY = e.clientY; const events2 = currentTool.useCoalescedEvents && e.nativeEvent.getCoalescedEvents ? e.nativeEvent.getCoalescedEvents() : [e]; for (const singleEvent of events2) { editor.dispatch({ type: "pointer", target: "canvas", name: "pointer_move", ...getPointerInfo(singleEvent) }); } } function onPointerUp(e) { if (e.isKilled) return; if (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return; lastX = e.clientX; lastY = e.clientY; releasePointerCapture(e.currentTarget, e); editor.dispatch({ type: "pointer", target: "canvas", name: "pointer_up", ...getPointerInfo(e) }); } function onPointerEnter(e) { if (e.isKilled) 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 (e.isKilled) 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) { ; e.isKilled = true; preventDefault(e); } function onTouchEnd(e) { ; e.isKilled = true; if (!(e.target instanceof HTMLElement)) return; if (e.target.tagName !== "A" && e.target.tagName !== "TEXTAREA" && !e.target.isContentEditable && // When in EditingShape state, we are actually clicking on a 'DIV' // not A/TEXTAREA/contenteditable element yet. So, to preserve cursor position // for edit mode on mobile we need to not preventDefault. // TODO: Find out if we still need this preventDefault in general though. !(editor.getEditingShape() && e.target.className.includes("tl-text-content"))) { preventDefault(e); } } function onDragOver(e) { preventDefault(e); } async function onDrop(e) { preventDefault(e); stopEventPropagation(e); if (e.dataTransfer?.files?.length) { const files = Array.from(e.dataTransfer.files); await editor.putExternalContent({ type: "files", files, point: editor.screenToPage({ x: e.clientX, y: e.clientY }) }); return; } const url = e.dataTransfer.getData("url"); if (url) { await editor.putExternalContent({ type: "url", url, point: editor.screenToPage({ x: e.clientX, y: e.clientY }) }); return; } } function onClick(e) { stopEventPropagation(e); } return { onPointerDown, onPointerMove, onPointerUp, onPointerEnter, onPointerLeave, onDragOver, onDrop, onTouchStart, onTouchEnd, onClick }; }, [editor, currentTool] ); return events; } export { useCanvasEvents }; //# sourceMappingURL=useCanvasEvents.mjs.map