'use client' import { useRef, useEffect, useCallback, useState } from 'react' import { useAppStore } from '@/store' import { cn } from '@/utils/helpers' interface SplitViewProps { width?: number height?: number className?: string } export function SplitView({ width = 800, height = 600, className }: SplitViewProps) { const canvasRef = useRef(null) const { originalImageData, processedImageData } = useAppStore() const { splitPosition, mode, setComparisonViewMode, setSplitPosition } = useAppStore((state) => ({ splitPosition: state.comparison.splitPosition, mode: state.comparison.mode, setComparisonViewMode: state.setComparisonViewMode, setSplitPosition: state.setSplitPosition, })) const [isDragging, setIsDragging] = useState(false) const drawCanvas = useCallback(() => { const canvas = canvasRef.current const ctx = canvas?.getContext('2d', { willReadFrequently: true }) if (!canvas || !ctx || !originalImageData) return const displayWidth = width const displayHeight = height canvas.width = displayWidth canvas.height = displayHeight ctx.clearRect(0, 0, displayWidth, displayHeight) const splitX = displayWidth * splitPosition if (mode === 'split' || mode === 'overlay') { // Draw original on left if (originalImageData) { const tempCanvas = document.createElement('canvas') tempCanvas.width = originalImageData.width tempCanvas.height = originalImageData.height const tempCtx = tempCanvas.getContext('2d') if (tempCtx) { tempCtx.putImageData(originalImageData, 0, 0) ctx.drawImage( tempCanvas, 0, 0, originalImageData.width, originalImageData.height, 0, 0, splitX, displayHeight ) } } // Draw processed on right if (processedImageData) { const tempCanvas = document.createElement('canvas') tempCanvas.width = processedImageData.width tempCanvas.height = processedImageData.height const tempCtx = tempCanvas.getContext('2d') if (tempCtx) { tempCtx.putImageData(processedImageData, 0, 0) ctx.drawImage( tempCanvas, splitX * (originalImageData.width / displayWidth), 0, processedImageData.width - splitX * (originalImageData.width / displayWidth), processedImageData.height, splitX, 0, displayWidth - splitX, displayHeight ) } } // Draw divider ctx.strokeStyle = '#fff' ctx.lineWidth = 3 ctx.setLineDash([10, 5]) ctx.beginPath() ctx.moveTo(splitX, 0) ctx.lineTo(splitX, displayHeight) ctx.stroke() ctx.setLineDash([]) // Draw handle ctx.fillStyle = '#3b82f6' ctx.beginPath() ctx.arc(splitX, displayHeight / 2, 12, 0, Math.PI * 2) ctx.fill() ctx.strokeStyle = '#fff' ctx.lineWidth = 2 ctx.stroke() } else if (mode === 'side-by-side') { // Side by side view const halfWidth = displayWidth / 2 if (originalImageData) { const tempCanvas = document.createElement('canvas') tempCanvas.width = originalImageData.width tempCanvas.height = originalImageData.height const tempCtx = tempCanvas.getContext('2d') if (tempCtx) { tempCtx.putImageData(originalImageData, 0, 0) ctx.drawImage(tempCanvas, 0, 0, halfWidth, displayHeight) } } if (processedImageData) { const tempCanvas = document.createElement('canvas') tempCanvas.width = processedImageData.width tempCanvas.height = processedImageData.height const tempCtx = tempCanvas.getContext('2d') if (tempCtx) { tempCtx.putImageData(processedImageData, 0, 0) ctx.drawImage(tempCanvas, halfWidth, 0, halfWidth, displayHeight) } } // Draw center line ctx.strokeStyle = 'rgba(255,255,255,0.5)' ctx.lineWidth = 1 ctx.beginPath() ctx.moveTo(halfWidth, 0) ctx.lineTo(halfWidth, displayHeight) ctx.stroke() } }, [originalImageData, processedImageData, splitPosition, mode, width, height]) useEffect(() => { drawCanvas() }, [drawCanvas]) const handleMouseDown = useCallback((e: React.MouseEvent) => { if (mode !== 'split') return const rect = canvasRef.current?.getBoundingClientRect() if (!rect) return const x = e.clientX - rect.left if (Math.abs(x - width * splitPosition) < 20) { setIsDragging(true) } }, [mode, splitPosition, width]) const handleMouseMove = useCallback( (e: React.MouseEvent) => { if (!isDragging || mode !== 'split') return const rect = canvasRef.current?.getBoundingClientRect() if (!rect) return const x = e.clientX - rect.left const newPosition = Math.max(0.1, Math.min(0.9, x / width)) setSplitPosition(newPosition) }, [isDragging, mode, width, setSplitPosition] ) const handleMouseUp = useCallback(() => { setIsDragging(false) }, []) return (
) }