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

Edit Image

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