leaky-ships/leaky-ships/hooks/useDraw.ts
2023-06-07 11:51:33 +02:00

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 }
}