Zoom in letter modal done

This commit is contained in:
2024-02-20 13:13:59 +05:00
parent 4dc43ff56e
commit 070950859b
6 changed files with 146 additions and 20 deletions
@@ -50,7 +50,7 @@ const ClientsPageCarousel = () => {
<h1 className="font-bold text-[67px] text-center">
Благодарственные письма
</h1>
<div className="py-24">
<div className="py-24 select-none">
<div className="flex h-[450px] w-[calc(100vw-20px)] overflow-hidden relative">
<div
className="flex transition-all duration-500 justify-center w-full"
@@ -1,8 +1,10 @@
import { useEffect, useRef, useState } from "react";
import { Image } from "../../types";
import CrossIcon from "../../icons/CrossIcon";
import useStore from "../../store/store";
import CrossIcon from "../../icons/CrossIcon";
import ArrowCarouselIcon from "../../icons/ArrowCarouselIcon";
import { useState } from "react";
import ZoomInIcon from "../../icons/ZoomInIcon";
import ZoomOutIcon from "../../icons/ZoomOutIcon";
type ZoomInLetterModalProps = {
images: Image[];
@@ -15,6 +17,19 @@ const ZoomInLetterModal = ({
}: ZoomInLetterModalProps) => {
const { setModal } = useStore();
const [selectedImage, setSelectedImage] = useState(currentImage);
const [isZoomed, setIsZoomed] = useState(false);
const currentImageRef = useRef<null | HTMLImageElement>(null);
useEffect(() => {
setIsZoomed(false);
if (!currentImageRef || !currentImageRef?.current) return;
currentImageRef.current.style.transform = ``;
}, [selectedImage]);
useEffect(() => {
if (!currentImageRef || !currentImageRef?.current || isZoomed) return;
currentImageRef.current.style.transform = ``;
}, [isZoomed]);
const handleOnRightClick = () => {
setSelectedImage((prev) => prev + 1);
@@ -28,8 +43,29 @@ const ZoomInLetterModal = ({
setModal(null);
};
const handleOnZoomSwitch = (
event: React.MouseEvent<HTMLImageElement, MouseEvent>
) => {
if (!currentImageRef || !currentImageRef?.current) return;
setIsZoomed((prev) => !prev);
currentImageRef.current.style.transform = `scale(1.5) translate(-5vw, ${
200 - 300 * (event.clientY / window.innerHeight)
}px)`;
};
function handleOnMouseMove(
event: React.MouseEvent<HTMLImageElement, MouseEvent>
): void {
if (!currentImageRef || !currentImageRef?.current || !isZoomed) return;
currentImageRef.current.style.transform = `scale(1.5) translate(-5vw, ${
200 - 300 * (event.clientY / window.innerHeight)
}px)`;
}
return (
<div className="fixed w-screen h-screen bg-[#fff] z-30 flex justify-center items-center">
<div className="fixed w-screen h-screen bg-[#fff] z-30 flex justify-center items-center select-none">
<div
className="flex w-fit duration-300 transition-all"
style={{
@@ -39,23 +75,45 @@ const ZoomInLetterModal = ({
}}
>
{images.map((image) => {
const isCurrentImage = selectedImage === image.id;
return (
<div key={image.id} className="h-screen w-screen">
<img
key={image.id}
src={image.image}
alt=""
className="h-full mx-auto"
/>
</div>
<>
{isCurrentImage ? (
<div key={`${image.id}-current`} className="h-screen w-screen">
<img
ref={currentImageRef}
onClick={handleOnZoomSwitch}
onMouseMove={handleOnMouseMove}
key={image.id}
src={image.image}
alt=""
className={`h-full mx-auto ${
isZoomed ? "cursor-zoom-out" : "cursor-zoom-in"
}`}
/>
</div>
) : (
<div key={image.id} className="h-screen w-screen">
<img
key={image.id}
src={image.image}
alt=""
className={`h-full mx-auto`}
/>
</div>
)}
</>
);
})}
</div>
<div
className="absolute top-2 right-2 z-30 cursor-pointer p-[10px]"
onClick={handleOnCloseModal}
>
<CrossIcon color="#000" />
<div className="absolute top-2 right-2 z-30 flex gap-6">
<div className="p-[10px] cursor-pointer" onClick={handleOnZoomSwitch}>
{!isZoomed ? <ZoomInIcon /> : <ZoomOutIcon />}
</div>
<div className="p-[10px] cursor-pointer" onClick={handleOnCloseModal}>
<CrossIcon color="#000" />
</div>
</div>
<div
className="z-30 absolute top-1/2 right-2 p-[10px] cursor-pointer"
+2 -2
View File
@@ -8,8 +8,8 @@ const CrossIcon = ({ color, className }: CrossIconProps) => {
<svg
className={`${className ? className : ""}`}
role="presentation"
width="23px"
height="23px"
width="20"
height="20"
viewBox="0 0 23 23"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
+37
View File
@@ -0,0 +1,37 @@
const ZoomInIcon = () => {
return (
<svg
width="20"
height="20"
viewBox="0 0 25 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M22.832 22L17.8592 17.0273"
stroke="#000000"
strokeWidth="2"
strokeLinecap="square"
></path>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M4.58591 3.7511C0.917768 7.41924 0.917768 13.367 4.58591 17.0352C8.25405 20.7033 14.2019 20.7033 17.87 17.0352C21.5381 13.367 21.5381 7.41924 17.87 3.7511C14.2019 0.0829653 8.25405 0.0829653 4.58591 3.7511Z"
stroke="#000000"
strokeWidth="2"
></path>
<path
d="M6.25781 10.3931H16.2035"
stroke="#000000"
strokeWidth="2"
></path>
<path
d="M11.2305 15.3662V5.42053"
stroke="#000000"
strokeWidth="2"
></path>
</svg>
);
};
export default ZoomInIcon;
+32
View File
@@ -0,0 +1,32 @@
const ZoomOutIcon = () => {
return (
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M21.9961 22L17.0233 17.0273"
stroke="#000000"
strokeWidth="2"
strokeLinecap="square"
></path>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M3.74997 3.7511C0.0818308 7.41924 0.0818308 13.367 3.74997 17.0352C7.41811 20.7033 13.3659 20.7033 17.0341 17.0352C20.7022 13.367 20.7022 7.41924 17.0341 3.7511C13.3659 0.0829653 7.41811 0.0829653 3.74997 3.7511Z"
stroke="#000000"
strokeWidth="2"
></path>
<path
d="M5.41797 10.3931H15.3637"
stroke="#000000"
strokeWidth="2"
></path>
</svg>
);
};
export default ZoomOutIcon;
@@ -3,7 +3,6 @@ import ClientsContainer from "../../components/ClientsPage/ClientsContainer";
import ClientsPageCarousel from "../../components/ClientsPage/ClientsPageCarousel";
const ClientsPage = () => {
console.log("Array.from(5)");
return (
<>
<div>