"use client"; import { useCallback, useEffect, useRef, useState } from "react"; import ReactCrop, { Crop } from "react-image-crop"; import { Icon } from "@iconify/react"; interface Props { isOpen: boolean; setIsOpen: React.Dispatch>; image: string | undefined; setImage: React.Dispatch>; } export default function CropPortrait({ isOpen, setIsOpen, image, setImage }: Props) { const [isVisible, setIsVisible] = useState(false); const [crop, setCrop] = useState(); const imageRef = useRef(null); const canvasRef = useRef(null); const applyCrop = useCallback(() => { if (!imageRef.current || !canvasRef.current || !crop) return; const image = imageRef.current; const canvas = canvasRef.current; if (!crop.width || !crop.height || image.naturalWidth === 0 || image.naturalHeight === 0) return; const ctx = canvas.getContext("2d"); if (!ctx) return; const scaleX = image.naturalWidth / image.width; const scaleY = image.naturalHeight / image.height; canvas.width = crop.width; canvas.height = crop.height; ctx.drawImage(image, crop.x * scaleX, crop.y * scaleY, crop.width * scaleX, crop.height * scaleY, 0, 0, crop.width, crop.height); setImage(canvas.toDataURL()); close(); }, [crop, setImage]); const close = () => { setIsVisible(false); setTimeout(() => { setIsOpen(false); }, 300); }; useEffect(() => { if (isOpen) { // slight delay to trigger animation setTimeout(() => setIsVisible(true), 10); } }, [isOpen]); return (

Crop Portrait

setCrop(c)} className="rounded-2xl border-2 border-amber-500 overflow-hidden max-h-96">
); }