mirror of
https://github.com/upscayl/upscayl.git
synced 2024-11-12 01:40:53 +01:00
Fix lens
This commit is contained in:
parent
602cb72fdb
commit
fad4560c12
8439
package-lock.json
generated
8439
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -210,9 +210,9 @@
|
|||||||
"@types/react-dom": "^18.0.11",
|
"@types/react-dom": "^18.0.11",
|
||||||
"autoprefixer": "^10.4.16",
|
"autoprefixer": "^10.4.16",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"daisyui": "^3.9.3",
|
"daisyui": "^3.9.4",
|
||||||
"electron": "^27.0.2",
|
"electron": "^27.2.4",
|
||||||
"electron-builder": "^24.6.4",
|
"electron-builder": "^24.9.1",
|
||||||
"next": "^13.5.6",
|
"next": "^13.5.6",
|
||||||
"postcss": "^8.4.31",
|
"postcss": "^8.4.31",
|
||||||
"prettier": "^3.0.0",
|
"prettier": "^3.0.0",
|
||||||
|
@ -33,3 +33,10 @@ export const turnOffNotificationsAtom = atomWithStorage(
|
|||||||
"turnOffNotifications",
|
"turnOffNotifications",
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const viewTypeAtom = atomWithStorage<"slider" | "lens">(
|
||||||
|
"viewType",
|
||||||
|
"lens"
|
||||||
|
);
|
||||||
|
|
||||||
|
export const lensSizeAtom = atomWithStorage<number>("lensSize", 100);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
import { lensSizeAtom, viewTypeAtom } from "@/atoms/userSettingsAtom";
|
||||||
import SidebarClosed from "@/components/icons/SidebarClosed";
|
import SidebarClosed from "@/components/icons/SidebarClosed";
|
||||||
import SidebarOpened from "@/components/icons/SidebarOpened";
|
import SidebarOpened from "@/components/icons/SidebarOpened";
|
||||||
|
import { useAtom } from "jotai";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
|
|
||||||
const ImageOptions = ({
|
const ImageOptions = ({
|
||||||
@ -14,6 +16,8 @@ const ImageOptions = ({
|
|||||||
hideZoomOptions?: boolean;
|
hideZoomOptions?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const [openSidebar, setOpenSidebar] = useState(false);
|
const [openSidebar, setOpenSidebar] = useState(false);
|
||||||
|
const [viewType, setViewType] = useAtom(viewTypeAtom);
|
||||||
|
const [lensSize, setLensSize] = useAtom(lensSizeAtom);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!localStorage.getItem("zoomAmount")) {
|
if (!localStorage.getItem("zoomAmount")) {
|
||||||
@ -24,13 +28,11 @@ const ImageOptions = ({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="">
|
<div
|
||||||
{/* <div
|
onDoubleClick={(e) => {
|
||||||
className={`bg-base-100 p-4 rounded-btn rounded-r-none fixed top-1/2 right-0 z-50 shadow-xl shadow-black group flex items-center gap-2`}
|
e.stopPropagation();
|
||||||
onClick={() => setOpenSidebar(!openSidebar)}>
|
}}
|
||||||
<Sidebar className="text-white text-xl" />
|
className="w-full h-full absolute">
|
||||||
</div> */}
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={`transition-all duration-500 bg-base-100 text-base-content h-screen w-[28rem] fixed right-0 top-0 z-50 shadow-xl shadow-black ${
|
className={`transition-all duration-500 bg-base-100 text-base-content h-screen w-[28rem] fixed right-0 top-0 z-50 shadow-xl shadow-black ${
|
||||||
openSidebar ? "right-0" : "-right-full translate-x-full"
|
openSidebar ? "right-0" : "-right-full translate-x-full"
|
||||||
@ -46,65 +48,43 @@ const ImageOptions = ({
|
|||||||
<SidebarClosed className="text-white text-xl" />
|
<SidebarClosed className="text-white text-xl" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col justify-center gap-5 overflow-auto p-5">
|
<div className="flex flex-col justify-center gap-5 overflow-auto p-5">
|
||||||
<button className="btn-primary btn" onClick={resetImagePaths}>
|
<button className="btn-primary btn" onClick={resetImagePaths}>
|
||||||
Reset Image
|
Reset Image
|
||||||
</button>
|
</button>
|
||||||
{!hideZoomOptions && (
|
{!hideZoomOptions && (
|
||||||
<div className="flex flex-row items-center gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<p className="w-20">Zoom:</p>
|
<p className="font-medium text-sm">Zoom Amount ({zoomAmount}%)</p>
|
||||||
<button
|
<input
|
||||||
className={`btn-primary btn ${
|
type="range"
|
||||||
zoomAmount === "100%" ? "btn-secondary" : "btn-primary"
|
min="100"
|
||||||
}`}
|
max="990"
|
||||||
onClick={() => {
|
step={10}
|
||||||
setZoomAmount("100%");
|
className="range range-md"
|
||||||
localStorage.setItem("zoomAmount", "100%");
|
value={parseInt(zoomAmount)}
|
||||||
}}>
|
onChange={(e) => {
|
||||||
100%
|
setZoomAmount(e.target.value);
|
||||||
</button>
|
localStorage.setItem("zoomAmount", e.target.value);
|
||||||
<button
|
}}
|
||||||
className={`btn-primary btn ${
|
/>
|
||||||
zoomAmount === "125%" ? "btn-secondary" : "btn-primary"
|
|
||||||
}`}
|
|
||||||
onClick={() => {
|
|
||||||
setZoomAmount("125%");
|
|
||||||
localStorage.setItem("zoomAmount", "125%");
|
|
||||||
}}>
|
|
||||||
125%
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className={`btn-primary btn ${
|
|
||||||
zoomAmount === "150%" ? "btn-secondary" : "btn-primary"
|
|
||||||
}`}
|
|
||||||
onClick={() => {
|
|
||||||
setZoomAmount("150%");
|
|
||||||
localStorage.setItem("zoomAmount", "150%");
|
|
||||||
}}>
|
|
||||||
150%
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className={`btn-primary btn ${
|
|
||||||
zoomAmount === "175%" ? "btn-secondary" : "btn-primary"
|
|
||||||
}`}
|
|
||||||
onClick={() => {
|
|
||||||
setZoomAmount("175%");
|
|
||||||
localStorage.setItem("zoomAmount", "175%");
|
|
||||||
}}>
|
|
||||||
175%
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className={`btn-primary btn ${
|
|
||||||
zoomAmount === "200%" ? "btn-secondary" : "btn-primary"
|
|
||||||
}`}
|
|
||||||
onClick={() => {
|
|
||||||
setZoomAmount("200%");
|
|
||||||
localStorage.setItem("zoomAmount", "200%");
|
|
||||||
}}>
|
|
||||||
200%
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<p className="font-medium text-sm">Lens Size ({lensSize / 10})</p>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
min="20"
|
||||||
|
max="400"
|
||||||
|
step={10}
|
||||||
|
className="range range-md"
|
||||||
|
value={lensSize}
|
||||||
|
onChange={(e) => {
|
||||||
|
setLensSize(parseInt(e.target.value));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { useState, useEffect, useCallback } from "react";
|
import { useState, useEffect, useCallback, useRef } from "react";
|
||||||
import COMMAND from "../../common/commands";
|
import COMMAND from "../../common/commands";
|
||||||
import { ReactCompareSlider } from "react-compare-slider";
|
import { ReactCompareSlider } from "react-compare-slider";
|
||||||
import Header from "../components/Header";
|
import Header from "../components/Header";
|
||||||
@ -15,6 +15,7 @@ import { logAtom } from "../atoms/logAtom";
|
|||||||
import { modelsListAtom } from "../atoms/modelsListAtom";
|
import { modelsListAtom } from "../atoms/modelsListAtom";
|
||||||
import {
|
import {
|
||||||
batchModeAtom,
|
batchModeAtom,
|
||||||
|
lensSizeAtom,
|
||||||
compressionAtom,
|
compressionAtom,
|
||||||
dontShowCloudModalAtom,
|
dontShowCloudModalAtom,
|
||||||
noImageProcessingAtom,
|
noImageProcessingAtom,
|
||||||
@ -22,6 +23,7 @@ import {
|
|||||||
overwriteAtom,
|
overwriteAtom,
|
||||||
progressAtom,
|
progressAtom,
|
||||||
scaleAtom,
|
scaleAtom,
|
||||||
|
viewTypeAtom,
|
||||||
} from "../atoms/userSettingsAtom";
|
} from "../atoms/userSettingsAtom";
|
||||||
import useLog from "../components/hooks/useLog";
|
import useLog from "../components/hooks/useLog";
|
||||||
import { UpscaylCloudModal } from "../components/UpscaylCloudModal";
|
import { UpscaylCloudModal } from "../components/UpscaylCloudModal";
|
||||||
@ -51,7 +53,7 @@ const Home = () => {
|
|||||||
const [doubleUpscaylCounter, setDoubleUpscaylCounter] = useState(0);
|
const [doubleUpscaylCounter, setDoubleUpscaylCounter] = useState(0);
|
||||||
const [gpuId, setGpuId] = useState("");
|
const [gpuId, setGpuId] = useState("");
|
||||||
const [saveImageAs, setSaveImageAs] = useState("png");
|
const [saveImageAs, setSaveImageAs] = useState("png");
|
||||||
const [zoomAmount, setZoomAmount] = useState("100%");
|
const [zoomAmount, setZoomAmount] = useState("100");
|
||||||
const [backgroundPosition, setBackgroundPosition] = useState("0% 0%");
|
const [backgroundPosition, setBackgroundPosition] = useState("0% 0%");
|
||||||
const [dimensions, setDimensions] = useState({
|
const [dimensions, setDimensions] = useState({
|
||||||
width: null,
|
width: null,
|
||||||
@ -61,6 +63,8 @@ const Home = () => {
|
|||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [showCloudModal, setShowCloudModal] = useState(false);
|
const [showCloudModal, setShowCloudModal] = useState(false);
|
||||||
|
|
||||||
|
const [cursorPosition, setCursorPosition] = useState({ x: 0, y: 0 });
|
||||||
|
|
||||||
// ATOMIC STATES
|
// ATOMIC STATES
|
||||||
const [outputPath, setOutputPath] = useAtom(outputPathAtom);
|
const [outputPath, setOutputPath] = useAtom(outputPathAtom);
|
||||||
const [compression, setCompression] = useAtom(compressionAtom);
|
const [compression, setCompression] = useAtom(compressionAtom);
|
||||||
@ -75,10 +79,22 @@ const Home = () => {
|
|||||||
const noImageProcessing = useAtomValue(noImageProcessingAtom);
|
const noImageProcessing = useAtomValue(noImageProcessingAtom);
|
||||||
const [news, setNews] = useAtom(newsAtom);
|
const [news, setNews] = useAtom(newsAtom);
|
||||||
const [showNewsModal, setShowNewsModal] = useAtom(showNewsModalAtom);
|
const [showNewsModal, setShowNewsModal] = useAtom(showNewsModalAtom);
|
||||||
|
const viewType = useAtomValue(viewTypeAtom);
|
||||||
|
const lensSize = useAtomValue(lensSizeAtom);
|
||||||
|
|
||||||
const { logit } = useLog();
|
const { logit } = useLog();
|
||||||
|
|
||||||
// * EFFECTS
|
const handleMouseMoveCompare = (e: React.MouseEvent) => {
|
||||||
|
const { left, top, height, width } =
|
||||||
|
e.currentTarget.getBoundingClientRect();
|
||||||
|
const x = e.clientX - left;
|
||||||
|
const y = e.clientY - top;
|
||||||
|
setCursorPosition({ x, y });
|
||||||
|
const xZoom = ((e.pageX - left) / width) * 100;
|
||||||
|
const yZoom = ((e.pageY - top) / height) * 100;
|
||||||
|
setBackgroundPosition(`${xZoom}% ${yZoom}%`);
|
||||||
|
};
|
||||||
|
|
||||||
// SET CONFIG VARIABLES ON FIRST RUN
|
// SET CONFIG VARIABLES ON FIRST RUN
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// UPSCAYL VERSION
|
// UPSCAYL VERSION
|
||||||
@ -611,7 +627,6 @@ const Home = () => {
|
|||||||
stopHandler={stopHandler}
|
stopHandler={stopHandler}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{/* DEFAULT PANE INFO */}
|
{/* DEFAULT PANE INFO */}
|
||||||
{((!batchMode &&
|
{((!batchMode &&
|
||||||
imagePath.length === 0 &&
|
imagePath.length === 0 &&
|
||||||
@ -621,7 +636,6 @@ const Home = () => {
|
|||||||
upscaledBatchFolderPath.length === 0)) && (
|
upscaledBatchFolderPath.length === 0)) && (
|
||||||
<RightPaneInfo version={version} batchMode={batchMode} />
|
<RightPaneInfo version={version} batchMode={batchMode} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* SHOW SELECTED IMAGE */}
|
{/* SHOW SELECTED IMAGE */}
|
||||||
{!batchMode &&
|
{!batchMode &&
|
||||||
upscaledImagePath.length === 0 &&
|
upscaledImagePath.length === 0 &&
|
||||||
@ -647,7 +661,6 @@ const Home = () => {
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* BATCH UPSCALE SHOW SELECTED FOLDER */}
|
{/* BATCH UPSCALE SHOW SELECTED FOLDER */}
|
||||||
{batchMode &&
|
{batchMode &&
|
||||||
upscaledBatchFolderPath.length === 0 &&
|
upscaledBatchFolderPath.length === 0 &&
|
||||||
@ -657,7 +670,6 @@ const Home = () => {
|
|||||||
{batchFolderPath}
|
{batchFolderPath}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* BATCH UPSCALE DONE INFO */}
|
{/* BATCH UPSCALE DONE INFO */}
|
||||||
{batchMode && upscaledBatchFolderPath.length > 0 && (
|
{batchMode && upscaledBatchFolderPath.length > 0 && (
|
||||||
<>
|
<>
|
||||||
@ -671,15 +683,61 @@ const Home = () => {
|
|||||||
</button>
|
</button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* COMPARISON SLIDER */}
|
|
||||||
{!batchMode && imagePath.length > 0 && upscaledImagePath.length > 0 && (
|
|
||||||
<>
|
|
||||||
<ImageOptions
|
<ImageOptions
|
||||||
zoomAmount={zoomAmount}
|
zoomAmount={zoomAmount}
|
||||||
setZoomAmount={setZoomAmount}
|
setZoomAmount={setZoomAmount}
|
||||||
resetImagePaths={resetImagePaths}
|
resetImagePaths={resetImagePaths}
|
||||||
/>
|
/>
|
||||||
|
{!batchMode &&
|
||||||
|
viewType === "lens" &&
|
||||||
|
upscaledImagePath &&
|
||||||
|
imagePath && (
|
||||||
|
<div
|
||||||
|
className="relative group overflow-hidden h-full w-full"
|
||||||
|
onMouseMove={handleMouseMoveCompare}>
|
||||||
|
<img
|
||||||
|
className={`absolute left-0 top-0 object-contain w-full h-full group-hover:scale-[${
|
||||||
|
zoomAmount + "%"
|
||||||
|
}]`}
|
||||||
|
src={"file:///" + imagePath}
|
||||||
|
style={{
|
||||||
|
backgroundPosition: "0% 0%",
|
||||||
|
transformOrigin: backgroundPosition,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className={`absolute left-0 top-0 bg-white mix-blend-difference w-full h-full group-hover:visible invisible group-hover:scale-[${
|
||||||
|
zoomAmount + "%"
|
||||||
|
}]`}
|
||||||
|
style={{
|
||||||
|
clipPath: `circle(${
|
||||||
|
(lensSize + 2) / (parseInt(zoomAmount) / 100)
|
||||||
|
}px at ${cursorPosition.x}px ${cursorPosition.y}px)`,
|
||||||
|
backgroundPosition: "0% 0%",
|
||||||
|
transformOrigin: backgroundPosition,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
className={`absolute top-0 object-contain left-0 w-full h-full group-hover:scale-[${
|
||||||
|
zoomAmount + "%"
|
||||||
|
}]`}
|
||||||
|
src={"file:///" + upscaledImagePath}
|
||||||
|
style={{
|
||||||
|
clipPath: `circle(${
|
||||||
|
lensSize / (parseInt(zoomAmount) / 100)
|
||||||
|
}px at ${cursorPosition.x}px ${cursorPosition.y}px)`,
|
||||||
|
backgroundPosition: "0% 0%",
|
||||||
|
transformOrigin: backgroundPosition,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{/* COMPARISON SLIDER */}
|
||||||
|
{!batchMode &&
|
||||||
|
viewType === "slider" &&
|
||||||
|
imagePath.length > 0 &&
|
||||||
|
upscaledImagePath.length > 0 && (
|
||||||
|
<>
|
||||||
<ReactCompareSlider
|
<ReactCompareSlider
|
||||||
itemOne={
|
itemOne={
|
||||||
<>
|
<>
|
||||||
@ -697,7 +755,9 @@ const Home = () => {
|
|||||||
backgroundPosition: "0% 0%",
|
backgroundPosition: "0% 0%",
|
||||||
transformOrigin: backgroundPosition,
|
transformOrigin: backgroundPosition,
|
||||||
}}
|
}}
|
||||||
className={`h-full w-full bg-gradient-to-br from-base-300 to-base-100 transition-transform group-hover:scale-[${zoomAmount}]`}
|
className={`h-full w-full bg-gradient-to-br from-base-300 to-base-100 transition-transform group-hover:scale-[${
|
||||||
|
parseInt(zoomAmount.slice(0, -1)) / 100
|
||||||
|
}]`}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
@ -716,7 +776,9 @@ const Home = () => {
|
|||||||
transformOrigin: backgroundPosition,
|
transformOrigin: backgroundPosition,
|
||||||
}}
|
}}
|
||||||
onMouseMove={handleMouseMove}
|
onMouseMove={handleMouseMove}
|
||||||
className={`h-full w-full bg-gradient-to-br from-base-300 to-base-100 transition-transform group-hover:scale-[${zoomAmount}]`}
|
className={`h-full w-full bg-gradient-to-br from-base-300 to-base-100 transition-transform group-hover:scale-[${
|
||||||
|
zoomAmount || "100%"
|
||||||
|
}%]`}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,10 @@ module.exports = {
|
|||||||
"./renderer/components/**/*.{js,ts,jsx,tsx}",
|
"./renderer/components/**/*.{js,ts,jsx,tsx}",
|
||||||
],
|
],
|
||||||
safelist: [
|
safelist: [
|
||||||
"group-hover:scale-[100%]",
|
...[...Array(99).keys()].flatMap((index) => [
|
||||||
"group-hover:scale-[125%]",
|
`group-hover:scale-[${index * 10}%]`,
|
||||||
"group-hover:scale-[150%]",
|
`group-hover:scale-[${index * 10}%]`,
|
||||||
"group-hover:scale-[175%]",
|
]),
|
||||||
"group-hover:scale-[200%]",
|
|
||||||
],
|
],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
|
Loading…
Reference in New Issue
Block a user