1
0
mirror of https://github.com/upscayl/upscayl.git synced 2024-11-28 01:10:52 +01:00
upscayl/renderer/components/main-content/lens-view.tsx

105 lines
2.9 KiB
TypeScript
Raw Normal View History

import React, { useRef, useState } from "react";
const LensImage = ({
src,
alt,
lensPosition,
zoomAmount,
}: {
src: string;
alt: string;
lensPosition: { x: number; y: number };
zoomAmount: number;
}) => (
<div className="h-full w-full overflow-hidden">
<img
src={src}
alt={alt}
className="h-full w-full"
style={{
objectFit: "contain",
objectPosition: `${-lensPosition.x}px ${-lensPosition.y}px`,
transform: `scale(${zoomAmount / 100})`,
transformOrigin: "top left",
}}
/>
</div>
);
const LensViewer = ({
zoomAmount,
lensSize,
sanitizedImagePath,
sanitizedUpscaledImagePath,
}: {
zoomAmount: string;
lensSize: number;
sanitizedImagePath: string;
sanitizedUpscaledImagePath: string;
}) => {
const upscaledImageRef = useRef<HTMLImageElement>(null);
const [lensPosition, setLensPosition] = useState({ x: 0, y: 0 });
const handleMouseMoveCompare = (e: React.MouseEvent) => {
if (upscaledImageRef.current) {
const { left, top, width, height } =
upscaledImageRef.current.getBoundingClientRect();
const x = e.clientX - left;
const y = e.clientY - top;
setLensPosition({
x: Math.max(0, Math.min(x - lensSize, width - lensSize * 2)),
y: Math.max(0, Math.min(y - lensSize / 2, height - lensSize)),
});
}
};
return (
<div
className="group relative h-full w-full overflow-hidden"
onMouseMove={handleMouseMoveCompare}
>
{/* UPSCALED IMAGE */}
<img
className="h-full w-full object-contain"
src={"file:///" + sanitizedUpscaledImagePath}
alt="Upscaled"
ref={upscaledImageRef}
/>
{/* LENS */}
<div
className="pointer-events-none absolute opacity-0 transition-opacity before:absolute before:left-1/2 before:h-full before:w-[2px] before:bg-white group-hover:opacity-100"
style={{
left: `${lensPosition.x}px`,
top: `${lensPosition.y}px`,
width: lensSize * 2,
height: lensSize,
border: "2px solid white",
boxShadow: "0 0 0 9999px rgba(0, 0, 0, 0.5)",
}}
>
<div className="flex h-full w-full">
<LensImage
src={"file:///" + sanitizedImagePath}
alt="Original"
lensPosition={lensPosition}
zoomAmount={parseInt(zoomAmount)}
/>
<LensImage
src={"file:///" + sanitizedUpscaledImagePath}
alt="Upscaled"
lensPosition={lensPosition}
zoomAmount={parseInt(zoomAmount)}
/>
</div>
<div className="absolute bottom-0 left-0 flex w-full items-center justify-around bg-black bg-opacity-50 p-1 px-2 text-center text-xs text-white backdrop-blur-sm">
<span>Original</span>
<span>Upscayl</span>
</div>
</div>
</div>
);
};
export default LensViewer;