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:
I started with my mouse in the center of the image and he draws it in the "lower right corner"
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>
)
}