Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

drawing circle starts at wrong position

I wrote a function which allows me to draw circles on a canvas. Everything works fine, but the start position of my canvas is not the same position as my mouse position.

const stopDrawingCircle = () => {
    setIsDrawing(false);
    console.log(currentImage);
}
//Setting start position
const startDrawingCircle = (event:any) => {
    currentImage.circle.x = event.clientX;
    currentImage.circle.y = event.clientY;
    currentImage.circle.radius = 0;
    setIsDrawing(true);
};
const drawCircle = function(event:any){
    if(!isDrawing)
      return;
    let canvas = canvasRef.current as HTMLCanvasElement | null; 
    let ctx = canvas?.getContext('2d')
    //seems to be the problem console log at start says the result of this is zero
    var currentX = currentImage.circle.x - event.clientX;
    var currentY = currentImage.circle.y - event.clientY;
    currentImage.circle.radius = Math.sqrt(currentX * currentX + currentY * currentY)
    if(canvas != null && ctx != null){
        ctx.beginPath();
        ctx.arc(currentImage.circle.x, currentImage.circle.y, currentImage.circle.radius, 0, Math.PI*2);
        ctx.fill();
    }
}
return(
  <div className="main">
    <div id="imageSection">
      <canvas id="canvas" 
        onMouseDown={startDrawingCircle}
        onMouseUp={stopDrawingCircle}
        onMouseMove={drawCircle}
        ref={canvasRef}> </canvas>       
    </div>
  </div>
)

The result of drawing a circle is like this:

example of fail

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I started with my mouse in the center of the image and he draws it in the "lower right corner"

>Solution :

event.clientX and event.clientY are relative to the current screen, not element being clicked.

MDN MouseEvent.clientX docs:

clientX
A number, defaulting to 0, that is the horizontal position of the mouse event on the client window of user’s screen;

Use event.offsetX and event.offsetY to get the mouse position relative to the event target.

However, since you’re using React, you need to use event.nativeEvent.offsetX and event.nativeEvent.offsetY because react doesn’t copy the offset properties onto their event proxy object.


Full code example:

import {useState, useRef} from "react";

const currentImage = {
  circle: {
    x: 0,
    y: 0,
    radius: 10,
  }
};

export default function App() {
  const [isDrawing, setIsDrawing] = useState(false);
  const canvasRef = useRef<HTMLCanvasElement>(null);

  const stopDrawingCircle = () => {
      setIsDrawing(false);
      // console.log(currentImage);
  }
  //Setting start position
  const startDrawingCircle = (event:any) => {
      currentImage.circle.x = event.nativeEvent.offsetX;
      currentImage.circle.y = event.nativeEvent.offsetY;
      currentImage.circle.radius = 0;
      setIsDrawing(true);
  };
  const drawCircle = function(event:any){
      if(!isDrawing)
        return;
      let canvas = canvasRef.current as HTMLCanvasElement | null; 
      let ctx = canvas?.getContext('2d')
      //seems to be the problem console log at start says the result of this is zero
      var currentX = currentImage.circle.x - event.nativeEvent.offsetX;
      var currentY = currentImage.circle.y - event.nativeEvent.offsetY;

      currentImage.circle.radius = Math.sqrt(currentX * currentX + currentY * currentY)
      if(canvas != null && ctx != null){
          ctx.beginPath();
          ctx.arc(currentImage.circle.x, currentImage.circle.y, currentImage.circle.radius, 0, Math.PI*2);
          ctx.fill();
      }
  }
  return(
    <div className="main">
      <div id="imageSection">
        <canvas id="canvas" 
          onMouseDown={startDrawingCircle}
          onMouseUp={stopDrawingCircle}
          onMouseMove={drawCircle}
          ref={canvasRef}> </canvas>       
      </div>
    </div>
  )
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading