import { Draw, Point } from "../interfaces/frontend" import { useDrawProps } from "./useDrawProps" import { useEffect, useRef, useState } from "react" function onDraw({ prevPoint, currentPoint, ctx, color }: Draw) { const { x: currX, y: currY } = currentPoint const lineColor = color const lineWidth = 5 let startPoint = prevPoint ?? currentPoint ctx.beginPath() ctx.lineWidth = lineWidth ctx.strokeStyle = lineColor ctx.moveTo(startPoint.x, startPoint.y) ctx.lineTo(currX, currY) ctx.stroke() ctx.fillStyle = lineColor ctx.beginPath() ctx.arc(startPoint.x, startPoint.y, 2, 0, 2 * Math.PI) ctx.fill() } export const useDraw = () => { const [mouseDown, setMouseDown] = useState(false) const canvasRef = useRef(null) const prevPoint = useRef(null) const { color } = useDrawProps() const onMouseDown = () => setMouseDown(true) const clear = () => { const canvas = canvasRef.current if (!canvas) return const ctx = canvas.getContext("2d") if (!ctx) return ctx.clearRect(0, 0, canvas.width, canvas.height) } useEffect(() => { const canvas = canvasRef.current if (!canvas) return const handler = (e: MouseEvent) => { if (!mouseDown) return const currentPoint = computePointInCanvas(e) const ctx = canvasRef.current?.getContext("2d") if (!ctx || !currentPoint) return onDraw({ ctx, currentPoint, prevPoint: prevPoint.current, color }) prevPoint.current = currentPoint } const computePointInCanvas = (e: MouseEvent) => { const rect = canvas.getBoundingClientRect() const x = e.clientX - rect.left const y = e.clientY - rect.top return { x, y } } const mouseUpHandler = () => { setMouseDown(false) prevPoint.current = null } // Add event listeners canvas.addEventListener("mousemove", handler) window.addEventListener("mouseup", mouseUpHandler) // Remove event listeners return () => { canvas.removeEventListener("mousemove", handler) window.removeEventListener("mouseup", mouseUpHandler) } }, [color, mouseDown]) return { canvasRef, onMouseDown, clear } }