import { useEffect, useRef } from 'react' export type DrawFn = (ctx: CanvasRenderingContext2D, width: number, height: number) => void /** * Returns a ref for a . The draw callback runs whenever it changes * identity (wrap it in useCallback) and whenever the canvas is resized. * Handles devicePixelRatio so lines stay crisp on high-DPI screens. */ export function useCanvas(draw: DrawFn) { const ref = useRef(null) useEffect(() => { const canvas = ref.current if (!canvas) return const render = () => { const dpr = window.devicePixelRatio || 1 const w = canvas.clientWidth const h = canvas.clientHeight if (w === 0 || h === 0) return canvas.width = Math.round(w * dpr) canvas.height = Math.round(h * dpr) const ctx = canvas.getContext('2d') if (!ctx) return ctx.setTransform(dpr, 0, 0, dpr, 0, 0) ctx.clearRect(0, 0, w, h) draw(ctx, w, h) } render() const ro = new ResizeObserver(render) ro.observe(canvas) return () => ro.disconnect() }, [draw]) return ref }