import React, { useMemo, useRef, useState } from "react"; const LensViewer = ({ sanitizedImagePath, sanitizedUpscaledImagePath, }: { sanitizedImagePath: string; sanitizedUpscaledImagePath: string; }) => { const originalImageContainerRef = useRef(null); const originalImageRef = useRef(null); const [hoverPosition, setHoverPosition] = useState({ relativeMouseX: 0, // To show the lens horizontally within the image mouseY: 0, // To show the lens vertically in the viewport relativeMouseXPercent: 0, relativeMouseYPercent: 0, originalImageMouseX: 0, originalImageMouseY: 0, }); const zoomLevel = 4; const handleMouseMove = (e: React.MouseEvent) => { if (!originalImageRef.current || !originalImageContainerRef.current) return; const containerRect = originalImageContainerRef.current.getBoundingClientRect(); // Image w-h is actually equal to container w-h, even in object-fit: contain let viewportImageWidth = originalImageRef.current.width; let viewportImageHeight = originalImageRef.current.height; let imageTop = 0; const mouseX = e.clientX; const mouseY = e.clientY; const containerHeight = containerRect.height; const containerLeft = containerRect.left; // Since sidebar pushes the container to the right const containerTop = containerRect.top; // Image is width-constrained const originalImageAspectRatio = originalImageRef.current.naturalWidth / originalImageRef.current.naturalHeight; viewportImageHeight = viewportImageWidth / originalImageAspectRatio; // Divide by 2 because image is centered imageTop = (containerHeight - viewportImageHeight) / 2; // Find relative mouse position within the image const relativeMouseX = mouseX - containerLeft; const relativeMouseY = mouseY - imageTop; // Check if the mouse is within the actual image boundaries const isWithinImage = relativeMouseX >= 0 && relativeMouseX <= viewportImageWidth && relativeMouseY >= 0 && relativeMouseY <= viewportImageHeight; if (!isWithinImage) { // Hide the lens if the mouse is outside the image setHoverPosition({ relativeMouseXPercent: -1000, relativeMouseYPercent: -1000, relativeMouseX: -1000, mouseY: -1000, originalImageMouseX: -1000, originalImageMouseY: -1000, }); return; } // Find image-relative mouse position as percentage const relativeMouseXPercent = (relativeMouseX / viewportImageWidth) * 100; const relativeMouseYPercent = (relativeMouseY / viewportImageHeight) * 100; // Find the pixel position within the image relative to the original image const bgPosX = (relativeMouseX / viewportImageWidth) * originalImageRef.current.naturalWidth; const bgPosY = (relativeMouseY / viewportImageHeight) * originalImageRef.current.naturalHeight; setHoverPosition({ relativeMouseXPercent, relativeMouseYPercent, relativeMouseX, mouseY, originalImageMouseX: bgPosX, originalImageMouseY: bgPosY, }); }; const originalImage = useMemo( () => "file:///" + sanitizedImagePath, [sanitizedImagePath], ); const upscaledImage = useMemo( () => "file:///" + sanitizedUpscaledImagePath, [sanitizedUpscaledImagePath], ); return (
{/* Main image container */}
Original
{/* Enlarged views for original and upscaled images */}
Original
Upscayl AI
); }; export default LensViewer;