import React, { useCallback } from 'react'; import { getBlankCanvasDataURL } from '../utils/canvasUtils'; import { CanvasHistoryHook } from './useCanvasHistory'; import { ConfirmModalHook } from './useConfirmModal'; import { ToastMessage } from './useToasts'; interface UseCanvasFileUtilsProps { canvasState: { currentDataURL: string | null; canvasWidth: number; canvasHeight: number; }; historyActions: { updateCanvasState: CanvasHistoryHook['updateCanvasState']; }; uiActions: { showToast: (message: string, type: ToastMessage['type']) => void; setZoomLevel: (zoom: number) => void; }; confirmModalActions: { requestConfirmation: ConfirmModalHook['requestConfirmation']; }; } export interface CanvasFileUtilsHook { handleLoadImageFile: (event: React.ChangeEvent) => void; handleExportImage: () => void; handleClearCanvas: () => void; handleCanvasSizeChange: (newWidth: number, newHeight: number) => void; } export const useCanvasFileUtils = ({ canvasState, historyActions, uiActions, confirmModalActions, }: UseCanvasFileUtilsProps): CanvasFileUtilsHook => { const { currentDataURL, canvasWidth, canvasHeight } = canvasState; const { updateCanvasState } = historyActions; const { showToast, setZoomLevel } = uiActions; const { requestConfirmation } = confirmModalActions; const handleLoadImageFile = useCallback((event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (file) { const reader = new FileReader(); reader.onload = (e) => { const imageDataUrl = e.target?.result as string; if (imageDataUrl) { const img = new Image(); img.onload = () => { let imageToDrawWidth = img.naturalWidth; let imageToDrawHeight = img.naturalHeight; if (img.naturalWidth > canvasWidth || img.naturalHeight > canvasHeight) { const widthRatio = canvasWidth / img.naturalWidth; const heightRatio = canvasHeight / img.naturalHeight; const scaleFactor = Math.min(widthRatio, heightRatio); imageToDrawWidth = Math.max(1, Math.floor(img.naturalWidth * scaleFactor)); imageToDrawHeight = Math.max(1, Math.floor(img.naturalHeight * scaleFactor)); } const finalCanvasWidth = canvasWidth; const finalCanvasHeight = canvasHeight; const tempCanvas = document.createElement('canvas'); tempCanvas.width = finalCanvasWidth; tempCanvas.height = finalCanvasHeight; const tempCtx = tempCanvas.getContext('2d'); if (tempCtx) { tempCtx.fillStyle = '#FFFFFF'; tempCtx.fillRect(0, 0, finalCanvasWidth, finalCanvasHeight); // Change: Draw image at top-left (0,0) const drawX = 0; const drawY = 0; tempCtx.drawImage(img, drawX, drawY, imageToDrawWidth, imageToDrawHeight); const compositeDataURL = tempCanvas.toDataURL('image/png'); updateCanvasState(compositeDataURL, finalCanvasWidth, finalCanvasHeight); showToast('Image loaded successfully.', 'success'); } }; img.onerror = () => showToast("Error loading image file for processing.", 'error'); img.src = imageDataUrl; } }; reader.onerror = () => showToast("Error reading image file.", 'error'); reader.readAsDataURL(file); if(event.target) event.target.value = ''; } }, [canvasWidth, canvasHeight, updateCanvasState, showToast]); const handleExportImage = useCallback(() => { if (currentDataURL) { const link = document.createElement('a'); link.href = currentDataURL; link.download = `paint-masterpiece-${Date.now()}.png`; document.body.appendChild(link); link.click(); document.body.removeChild(link); showToast('Image exported!', 'success'); } else { showToast('No image to export.', 'info'); } }, [currentDataURL, showToast]); const handleClearCanvas = useCallback(() => { const blankCanvas = getBlankCanvasDataURL(canvasWidth, canvasHeight); updateCanvasState(blankCanvas, canvasWidth, canvasHeight); showToast("Canvas cleared.", "info"); }, [canvasWidth, canvasHeight, updateCanvasState, showToast]); const handleCanvasSizeChange = useCallback((newWidth: number, newHeight: number) => { if (newWidth === canvasWidth && newHeight === canvasHeight) { return; } requestConfirmation( "Confirm Canvas Size Change", "Changing canvas size will clear the current drawing and history. Are you sure you want to continue?", () => { const blankCanvas = getBlankCanvasDataURL(newWidth, newHeight); updateCanvasState(blankCanvas, newWidth, newHeight); setZoomLevel(0.5); showToast(`Canvas resized to ${newWidth}x${newHeight}px. Drawing cleared.`, 'info'); }, { isDestructive: true } ); }, [canvasWidth, canvasHeight, requestConfirmation, updateCanvasState, setZoomLevel, showToast]); return { handleLoadImageFile, handleExportImage, handleClearCanvas, handleCanvasSizeChange }; };