Skip to content

Commit

Permalink
Adding zoom img
Browse files Browse the repository at this point in the history
  • Loading branch information
SamuelPelletierEvraire committed Jun 17, 2024
1 parent db74d6a commit 64e1192
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 21 deletions.
1 change: 1 addition & 0 deletions src/Components/Carousel/Carousel.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
transition: all 750ms linear;
width: 100%;
height: fit-content;
max-height: 100px;
object-fit: contain;
}

Expand Down
9 changes: 7 additions & 2 deletions src/Components/Carousel/Carousel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState } from "react";
import "./Carousel.css";
import ImageZoomInOut from "../ImageZoomInOut/ImageZoomInOut";
interface CarouselProps {
imgs: {
url: string;
Expand Down Expand Up @@ -45,11 +46,15 @@ const Carousel: React.FC<CarouselProps> = ({ imgs }) => {
<a className="prev" onClick={() => selectImg(currImg - 1)}>
&#10094;
</a>
<img
<ImageZoomInOut
className="main-img"

Check failure on line 50 in src/Components/Carousel/Carousel.tsx

View workflow job for this annotation

GitHub Actions / lint-test / lint-test

Delete `····`
imageUrl={imgList.length > 0 ? imgList[currImg].url : ""}

Check failure on line 51 in src/Components/Carousel/Carousel.tsx

View workflow job for this annotation

GitHub Actions / lint-test / lint-test

Replace `··············imageUrl={imgList.length·>·0·?·imgList[currImg].url·:·""}·` with `··········imageUrl={imgList.length·>·0·?·imgList[currImg].url·:·""}`
alt="no picture"/>

Check failure on line 52 in src/Components/Carousel/Carousel.tsx

View workflow job for this annotation

GitHub Actions / lint-test / lint-test

Replace `··············alt="no·picture"` with `··········alt="no·picture"⏎········`
{/*<img
id="main-img"
src={imgList.length > 0 ? imgList[currImg].url : ""}
alt={imgList.length > 0 ? imgList[currImg].title : "No picture"}
></img>
></img>*/}
<a className="next" onClick={() => selectImg(currImg + 1)}>
&#10095;
</a>
Expand Down
21 changes: 21 additions & 0 deletions src/Components/ImageZoomInOut/ImageZoomInOut.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.btn-container {
display: flex;
flex-direction: column;
gap: 8px;
background-color: #fff;
border-radius: 8px;
overflow: hidden;
position: absolute;
top: 0;
left: 0;
z-index: 1;
border:1px solid black;
}

.btn-container button {
border: none;
color: #737373;
background-color: #fff;
padding: 10px;
cursor: pointer;
}
127 changes: 127 additions & 0 deletions src/Components/ImageZoomInOut/ImageZoomInOut.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { useState, useRef, useEffect } from "react";
import "./ImageZoomInOut.css";

interface ImageProps {
imageUrl: string;
className?: string; // Optional class name
onClick?: () => void; // Optional click handler function
}

function ImageZoomInOut({ imageUrl, className, onClick }: ImageProps) {
const [scale, setScale] = useState(1);
const [position, setPosition] = useState({ x: 0, y: 0 });
const imageRef = useRef(null);
const intervalRef = useRef<NodeJS.Timeout | null>(null)||scale>1;

Check failure on line 14 in src/Components/ImageZoomInOut/ImageZoomInOut.tsx

View workflow job for this annotation

GitHub Actions / lint-test / lint-test

Replace `||scale>` with `·||·scale·>·`

const handleHoldZoomIn = () => {
if (intervalRef.current && (scale + 0.05 < 1)) return;

Check failure on line 17 in src/Components/ImageZoomInOut/ImageZoomInOut.tsx

View workflow job for this annotation

GitHub Actions / lint-test / lint-test

Replace `(scale·+·0.05·<·1)` with `scale·+·0.05·<·1`
intervalRef.current = setInterval(() => {
handleZoomIn();
}, 1);
};

const handleHoldZoomOut = () => {
if (intervalRef.current && (scale + 0.05 < 1)) return;

Check failure on line 24 in src/Components/ImageZoomInOut/ImageZoomInOut.tsx

View workflow job for this annotation

GitHub Actions / lint-test / lint-test

Replace `(scale·+·0.05·<·1)` with `scale·+·0.05·<·1`
intervalRef.current = setInterval(() => {
handleZoomOut();
}, 1);
};

const handleHoldZoomInOutStop = () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
intervalRef.current = null;
}
};

const handleZoomIn = () => {
if (scale + 0.05 > 1) {
setScale((scale) => scale + 0.05);

Check failure on line 39 in src/Components/ImageZoomInOut/ImageZoomInOut.tsx

View workflow job for this annotation

GitHub Actions / lint-test / lint-test

Delete `··`
}else{

Check failure on line 40 in src/Components/ImageZoomInOut/ImageZoomInOut.tsx

View workflow job for this annotation

GitHub Actions / lint-test / lint-test

Replace `else` with `·else·`
setScale(1);

Check failure on line 41 in src/Components/ImageZoomInOut/ImageZoomInOut.tsx

View workflow job for this annotation

GitHub Actions / lint-test / lint-test

Delete `··`
handleHoldZoomInOutStop();

Check failure on line 42 in src/Components/ImageZoomInOut/ImageZoomInOut.tsx

View workflow job for this annotation

GitHub Actions / lint-test / lint-test

Delete `··`
}
};

const handleZoomOut = () => {
if (scale - 0.05 > 1) {
setScale((scale) => scale - 0.05);
}else{
setScale(1);
handleHoldZoomInOutStop();
}
};

useEffect(() => {
const image = imageRef.current as unknown as HTMLImageElement;
let isDragging = false;
let prevPosition = { x: 0, y: 0 };

const handleMouseDown = (e: MouseEvent) => {
isDragging = true;
prevPosition = { x: e.clientX, y: e.clientY };
};

const handleMouseMove = (e: MouseEvent) => {
if (!isDragging) return;
const deltaX = e.clientX - prevPosition.x;
const deltaY = e.clientY - prevPosition.y;
prevPosition = { x: e.clientX, y: e.clientY };
setPosition((position) => ({
x: position.x + deltaX,
y: position.y + deltaY,
}));
};

const handleMouseUp = () => {
isDragging = false;
};

image?.addEventListener("mousedown", handleMouseDown);
image?.addEventListener("mousemove", handleMouseMove);
image?.addEventListener("mouseup", handleMouseUp);

return () => {
image?.removeEventListener("mousedown", handleMouseDown);
image?.removeEventListener("mousemove", handleMouseMove);
image?.removeEventListener("mouseup", handleMouseUp);
};
}, [imageRef, scale]);

return (
<div
className={`imageZoomInOut ${className || ""}`}
style={{
backgroundColor: "#ffffff",
borderRadius: "10px",
position: "relative",
overflow: "hidden",
}}
onClick={onClick}
>
<div className={`btn-container ${imageRef.current ? "hidden" : ""}`}>
<button onClick={handleZoomIn} onMouseDown={handleHoldZoomIn} onMouseUp={handleHoldZoomInOutStop} onMouseLeave={handleHoldZoomInOutStop}>
<span className="material-symbols-outlined">+</span>
</button>
<button onClick={handleZoomOut} onMouseDown={handleHoldZoomOut} onMouseUp={handleHoldZoomInOutStop} onMouseLeave={handleHoldZoomInOutStop}>
<span className="material-symbols-outlined">-</span>
</button>
</div>

<img
ref={imageRef}
src={imageUrl}
alt="No Picture"
className="imageZoomInOut"
style={{
width: "50vw",
transform: `scale(${scale}) translate(${position.x}px, ${position.y}px)`,
cursor: "move",
}}
draggable={false}
/>
</div>
);
}

export default ImageZoomInOut;
8 changes: 5 additions & 3 deletions src/Components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import Carousel from "../Carousel/Carousel";
interface ModalProps {
text: string;
imgs: Image[]; // Array of Image objects
handleTextChange: (event: { target: { value: React.SetStateAction<string> }; }) => void;
handleTextChange: (event: {
target: { value: React.SetStateAction<string> };
}) => void;
close: () => void;
toRef: React.MutableRefObject<HTMLDivElement | null>;
}
Expand Down Expand Up @@ -48,8 +50,8 @@ const Modal: React.FC<ModalProps> = ({
return (
<div className="overlay" onClick={handleOverlayClick} ref={toRef}>
<div className="pic-container">
<Carousel imgs={imgs}></Carousel>
</div>
<Carousel imgs={imgs}></Carousel>
</div>
<div className="card">
<img
src={closeIcon}
Expand Down
33 changes: 17 additions & 16 deletions src/Pages/FormPage/FormPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ class input {

const MAX_CHAR_IN_ROW = 37;


const FormPage = () => {
// @ts-expect-error : setForm is going to be used when linked to db
// eslint-disable-next-line
Expand Down Expand Up @@ -109,10 +108,6 @@ const FormPage = () => {
}[]
>([]);

// Load data from environment variable or local JSON file
const [useLocalData, setUseLocalData] = useState(process.env.REACT_APP_ACTIVATE_USING_JSON);


const [data, setData] = useState<dataObject>(
new dataObject([
new section("Company information", "company", [
Expand Down Expand Up @@ -215,15 +210,15 @@ const FormPage = () => {
return (
<div className="input-container">
<label htmlFor={parent.label + "-" + inputInfo.label}>
{parent.label.charAt(0).toUpperCase() + parent.label.slice(1)} {" "}
{parent.label.charAt(0).toUpperCase() + parent.label.slice(1)}{" "}
{inputInfo.label.replace(/_/gi, " ")} :
</label>
<div className="textbox-container">
<textarea
id={parent.label + "-" + inputInfo.label}
ref={
textareas.find(
(obj) => obj.label === parent.label + inputInfo.label
(obj) => obj.label === parent.label + inputInfo.label,
)?.ref
}
value={inputInfo.value}
Expand All @@ -250,18 +245,23 @@ const FormPage = () => {
.reduce((sum, current) => sum + current) >
3 && (
<div className="show-more-container">
<label className="open-icon" onClick={() => {
const modal = modals.find(
(modalObj) => modalObj.label === parent.label + inputInfo.label
);
modal?.ref.current?.classList.add("active");
}}>
<label
className="open-icon"
onClick={() => {
const modal = modals.find(
(modalObj) =>
modalObj.label === parent.label + inputInfo.label,
);
modal?.ref.current?.classList.add("active");
}}
>
Show more
</label>
<Modal
toRef={
modals.find(
(modalObj) => modalObj.label === parent.label + inputInfo.label
(modalObj) =>
modalObj.label === parent.label + inputInfo.label,
)!.ref
}
text={inputInfo.value}
Expand All @@ -271,10 +271,11 @@ const FormPage = () => {
inputInfo.value = event.target.value.toString();
setData(data.copy());
}}
imgs= {urls}
imgs={urls}
close={() => {
const modal = modals.find(
(modalObj) => modalObj.label === parent.label + inputInfo.label
(modalObj) =>
modalObj.label === parent.label + inputInfo.label,
);
modal?.ref.current?.classList.remove("active");
}}
Expand Down

0 comments on commit 64e1192

Please sign in to comment.