Hello
I have spent hours trying to understand why my mousedown event is not working inside the useEffect.
When I console log ‘hello’ within the useEffect nothing happens. But when I do it outside it logs to the console. It is a drag app that allows you to zoom into an image and pan over it.
This is my code. If any React expert or otherwise has any ideas at all I want to hear them!
Thank you.
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import { useState, useEffect } from "react";
import { useRef } from "react";
import img1 from "./img1.jpg";
import img2 from "./img2.jpg";
function App() {
const images = {
1: img1,
2: img2
};
return (
<div>
<ImageZoomInOut img1={img1} images={images} />
</div>
);
}
////////////////////////////////////////////
function ImageZoomInOut({ images }) {
//state for img scale
const [scale, setScale] = useState(1);
//state for img position
const [position, setPosition] = useState({ x: 0, y: 0 });
//reference to the img element
const imageRef = useRef(null);
//zoom in function
function handleZoomIn() {
return setScale((scale) => scale + 0.05);
}
//zoom out function
function handleZoomOut() {
return setScale((scale) => scale - 0.05);
}
//image drag and zoom/////////////////////////////
useEffect(() => {
const image = imageRef.current;
let isDragging = false;
let prevPosition = { x: 0, y: 0 };
//mouse down event handler for starting img drag
const handleMouseDown = (e) => {
isDragging = true;
prevPosition = { x: e.ClientX, y: e.clientY };
};
//mouse move event handler for dragging img
const handleMouseMove = (e) => {
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,
}));
};
//mouse up event handler for ending img drag
const handleMouseUp = () => {
isDragging = false;
};
const image1 = document.getElementById("2");
//add event listeners
if (image) {
image.addEventListener("mousedown", handleMouseDown);
image.addEventListener("mousemove", handleMouseMove);
image.addEventListener("mouseup", handleMouseUp);
return;
}
//remove event listners on component unmount
return () => {
if (image) {
image.removeEventListener("mousedown", handleMouseDown);
image.removeEventListener("mousemove", handleMouseMove);
image.removeEventListener("mouseup", handleMouseUp);
}
};
}, [imageRef, scale]);
//////////
return (
<div style={{ position: "relative", overflow: "hidden" }}>
<div className="btns">
<button className="btn1" onClick={handleZoomIn}>
+
</button>
<button className="btn2" onClick={handleZoomOut}>
-
</button>
</div>
{/* image element */}
<img
ref={imageRef}
id="2"
src={images[2]}
alt=""
style={{
width: "900px",
height: "auto",
cursor: "move",
transform: `scale(${scale}) translate(${position.x}px, ${position.y}px)`,
}}
draggable={false}
onClick={() => console.log("hi")}
/>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);