import { useCallback, useRef, useState, MouseEvent, useEffect } from "react" import { FocalPoint } from "~/types/imagevault" interface UseFocalPointProps { focalPoint?: FocalPoint onChange: (focalPoint: FocalPoint) => void } const DEFAULT_PERCENTAGE = 50 export default function useFocalPoint({ focalPoint, onChange, }: UseFocalPointProps) { const ref = useRef(null) const [x, setX] = useState(DEFAULT_PERCENTAGE) const [y, setY] = useState(DEFAULT_PERCENTAGE) const [canMove, setCanMove] = useState(false) useEffect(() => { if (focalPoint) { setX(focalPoint.x) setY(focalPoint.y) } }, [focalPoint]) const onMove = useCallback( (e: MouseEvent) => { if (canMove) { const containerBoundingRectangle = ref.current!.getBoundingClientRect() const xPixels = e.clientX - containerBoundingRectangle.left const yPixels = e.clientY - containerBoundingRectangle.top let x = Math.min( Math.max((xPixels * 100) / ref.current!.clientWidth, 0), 100 ) let y = Math.min( Math.max((yPixels * 100) / ref.current!.clientHeight, 0), 100 ) x = parseFloat(x.toFixed(2)) y = parseFloat(y.toFixed(2)) setX(x) setY(y) onChange({ x, y }) } }, [canMove, onChange] ) return { ref, x, y, onMove, canMove, setCanMove, } }