84 lines
2.2 KiB
TypeScript
84 lines
2.2 KiB
TypeScript
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<HTMLCanvasElement>(null)
|
|
const prevPoint = useRef<null | Point>(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 }
|
|
}
|