import React, { useState, useCallback } from 'react'; import Cropper from 'react-easy-crop'; import { ImageIcon, Maximize2, RefreshCw, Copy, Check, X } from 'lucide-react'; const ASPECT_RATIOS = [ { id: 'hero', label: 'Hero Banner (21:9)', ratio: 21 / 9 }, { id: 'news', label: 'Notícia/Media (16:9)', ratio: 16 / 9 }, { id: 'square', label: 'Quadrado/Social (1:1)', ratio: 1 / 1 }, ]; const MultiAspectEditor = ({ image, onClose, onExport }: { image: string, onClose: () => void, onExport: (results: Record) => void }) => { const [crops, setCrops] = useState( ASPECT_RATIOS.reduce((acc, curr) => ({ ...acc, [curr.id]: { crop: { x: 0, y: 0 }, zoom: 1, croppedAreaPixels: null } }), {}) ); const onCropChange = (id: string, crop: any) => { setCrops(prev => ({ ...prev, [id]: { ...(prev as any)[id], crop } })); }; const onZoomChange = (id: string, zoom: number) => { setCrops(prev => ({ ...prev, [id]: { ...(prev as any)[id], zoom } })); }; const onCropComplete = useCallback((id: string, _: any, croppedAreaPixels: any) => { setCrops(prev => ({ ...prev, [id]: { ...(prev as any)[id], croppedAreaPixels } })); }, []); const generateBase64 = async () => { const results: Record = {}; for (const ratio of ASPECT_RATIOS) { const pixelCrop = (crops as any)[ratio.id].croppedAreaPixels; if (pixelCrop) { results[ratio.id as keyof typeof results] = await getCroppedImg(image, pixelCrop); } } onExport(results); }; return (
{/* Header do Modal */}

Editor de Enquadramento

Ajuste a imagem para os diferentes formatos do portal

{/* Área de Edição - Grid de Croppers */}
{ASPECT_RATIOS.map((r) => (
{r.label}
{/* Container do Cropper */}
onCropChange(r.id, c)} onCropComplete={(_, pix) => onCropComplete(r.id, _, pix)} onZoomChange={(z) => onZoomChange(r.id, z)} />
{/* Slider de Zoom Customizado */}
onZoomChange(r.id, Number(e.target.value))} className="w-full h-1.5 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-blue-600" />
))}
{/* Footer com Ações */}
); }; // Função Utilitária para Canvas -> Base64 async function getCroppedImg(imageSrc: string, pixelCrop: any) { const image = await new Promise((resolve, reject) => { const img = new Image(); img.addEventListener('load', () => resolve(img)); img.addEventListener('error', (error) => reject(error)); img.setAttribute('crossOrigin', 'anonymous'); img.src = imageSrc; }); const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d') as CanvasRenderingContext2D | null; if (!ctx) return ''; canvas.width = pixelCrop.width; canvas.height = pixelCrop.height; ctx.drawImage( image as CanvasImageSource, pixelCrop.x, pixelCrop.y, pixelCrop.width, pixelCrop.height, 0, 0, pixelCrop.width, pixelCrop.height ); return canvas.toDataURL('image/jpeg', 0.9); } export default MultiAspectEditor;