Reputation: 29
I am using React with typescript. In my app, I converted the logic for drawing SVG using javascript on the existing question on StackOverflow
The problem is my shapes are not drawing. Please help me with what I missed in the code my addRectangle
method is not triggering.
Here is my code:
let last_mousex: number = 0;
let last_mousey: number = 0;
let mousex: number = 0;
let mousey: number = 0;
let mousedown:boolean = false;
const mouseDown = () => {
last_mousex = xCord;
last_mousey = yCord;
mousedown = true;
}
const mouseUp = () => {
mousedown = false;
}
const mouseMove = () => {
mousex = xCord;
mousey = yCord;
}
const addRectangle = () => {
if (mousedown) {
const width = Math.abs(mousex - last_mousex);
const height = Math.abs(mousey - last_mousey);
return <rect
className={"rectangle"}
x={last_mousex}
y={last_mousey}
height={height}
width={width}
/>
}
}
return (
<div className="App" ref={divRef}>
<svg
id="svg"
ref={svgRef}
onMouseDown={mouseDown}
onMouseUp={mouseUp}
onMouseMove={mouseMove}
>
{addRectangle}
</svg>
</div>
);
Upvotes: 1
Views: 1763
Reputation: 2806
You were close, but have not used a component state at all, throwing away and overwriting the coordinates. You can do it like that:
const {useRef, useEffect, useState} = React;
const App = () => {
const svgRef = useRef(null);
const divRef = useRef(null);
const { xCord, yCord } = useMousePosition({ divRef });
const [mousedown, setMouseDown] = useState(false);
const [last_mousex, set_last_mousex] = useState(0);
const [last_mousey, set_last_mousey] = useState(0);
const [mousex, set_mousex] = useState(0);
const [mousey, set_mousey] = useState(0);
const [rectx, setrectx] = useState(0);
const [recty, setrecty] = useState(0);
const [rectwidth, setrectwidth] = useState(0);
const [rectheight, setrectheight] = useState(0);
const mouseDown = () => {
set_last_mousex(xCord);
set_last_mousey(yCord);
setMouseDown(true);
};
const mouseUp = () => {
setMouseDown(false);
};
const mouseMove = () => {
set_mousex(xCord);
set_mousey(yCord);
};
const addRectangle = () => {
if (mousedown) {
const width = Math.abs(mousex - last_mousex);
const height = Math.abs(mousey - last_mousey);
const rx = mousex < last_mousex ? mousex : last_mousex;
const ry = mousey < last_mousey ? mousey : last_mousey;
if(rectx !== rx) setrectx(rx);
if(recty !== ry )setrecty(ry);
if(rectheight !== height) setrectheight(height);
if(rectwidth !== width) setrectwidth(width);
return (
<rect
className={"rectangle"}
x={rx}
y={ry}
height={height}
width={width}
/>
);
}
};
return (
<div className="App" ref={divRef}>
<svg
id="svg"
ref={svgRef}
onMouseDown={mouseDown}
onMouseUp={mouseUp}
onMouseMove={mouseMove}
>
{addRectangle() ? (
addRectangle()
) : (
<rect
className={"rectangle"}
x={rectx}
y={recty}
height={rectheight}
width={rectwidth}
/>
)}
</svg>
</div>
);
}
function useMousePosition({divRef}){
const [position, setPosition] = useState({ xCord: 0, yCord: 0 });
useEffect(() => {
function setFromEvent(e) {
return setPosition({ xCord: e.clientX, yCord: e.clientY });
}
if(divRef.current){
divRef.current.addEventListener("mousemove", setFromEvent);
}
return () => {
if(divRef.current){
divRef.current.removeEventListener("mousemove", setFromEvent);
}
};
});
return position;
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
.App { height: 500px; width: 800px; background-color: rgb(126, 119, 119); } #svg { position: absolute; top: 0; left: 0; height: 100%; width: 100%; border: 1px solid #000000; cursor: crosshair; } .rectangle { fill: rgba(255, 255, 255, 0); stroke-width: 3; stroke: rgb(250, 0, 0); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js" integrity="sha512-qlzIeUtTg7eBpmEaS12NZgxz52YYZVF5myj89mjJEesBd/oE9UPsYOX2QAXzvOAZYEvQohKdcY8zKE02ifXDmA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js" integrity="sha512-9jGNr5Piwe8nzLLYTk8QrEMPfjGU0px80GYzKZUxi7lmCfrBjtyCc1V5kkS5vxVwwIB7Qpzc7UxLiQxfAN30dw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="root"></div>
Upvotes: 1