Home > Software engineering >  Drawing SVG shape with mouse using React
Drawing SVG shape with mouse using React

Time:01-30

I am using React with typescript. In my app, I converted the logic for drawing SVG using javascript on the existing question on StackOverflow Drawing SVG using Javascript

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}
        onm ouseDown={mouseDown}
        onm ouseUp={mouseUp}
        onm ouseMove={mouseMove}
      >
        {addRectangle}
      </svg>
    </div>
  );

This my sandbox link

CodePudding user response:

You were close, but have not used a component state at all, throwing away and overwriting the coordinates. You can do it like that:

import { useRef, useState } from "react";
import "./styles.css";
import useMousePosition from "./useMousePosition";
export default function App() {
  const svgRef = useRef<SVGSVGElement>(null);
  const divRef = useRef<HTMLDivElement>(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;
      rectx!==rx && setrectx(rx);
      recty!==ry && setrecty(ry);
      rectheight!==height && setrectheight(height);
      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}
        onm ouseDown={mouseDown}
        onm ouseUp={mouseUp}
        onm ouseMove={mouseMove}
      >
        {addRectangle() ? (
          addRectangle()
        ) : (
          <rect
            className={"rectangle"}
            x={rectx}
            y={recty}
            height={rectheight}
            width={rectwidth}
          />
        )}
      </svg>
    </div>
  );
}
  •  Tags:  
  • Related