I created a canvas with a circle inside it and I'm trying to detect the mouse click.
I am calculating the distance between the mouse click and the radius of the circle. The output should be 0
when the click is next to the center of the circle however I'm getting more than 400
!
Here is the code that I have tried. I couldn't understand what I'm doing wrong!?
let canvas = document.querySelector('canvas');
let ctx = canvas.getContext('2d');
let mousePos = {
x: undefined,
y: undefined
};
function Circle(x, y, r) {
this.x = x;
this.y = y;
this.r = r;
this.draw = function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
ctx.stroke();
ctx.fill();
ctx.closePath();
};
this.clickCircle = function(xmouse, ymouse) {
let distance = Math.sqrt(
(xmouse - this.x) * (xmouse - this.x) +
(ymouse - this.y) * (ymouse - this.y)
);
console.log(distance);
};
}
let myCircle = new Circle(100, 100, 20);
myCircle.draw();
canvas.addEventListener('click', e => {
const rect = canvas.getBoundingClientRect();
mousePos.x = e.clientX - rect.left;
mousePos.y = e.clientY - rect.top;
myCircle.clickCircle(mousePos.x, mousePos.y);
});
canvas {
border: 1px solid black;
background-color: wheat;
width: 100%;
}
<div class="container">
<canvas id="app"></canvas>
</div>
In general, your code is correct except one detail. Unfortunately, canvas doesn't work with relative sizes (such as %). Actually he does, but that is a style which is applied to the result picture not the canvas itself.
So the only thing you need to change is to remove width: 100%;
from the CSS code for canvas element and at the same time set the concrete values for canvas width and height via html attributes or by javascript code.
For example:
let canvas = document.querySelector('canvas');
canvas.width = 500;
canvas.height = 300;
...
let canvas = document.querySelector('canvas');
// add size. btw, you may calculate those based on the parent element or window
// or just use the values you like
canvas.width = 500;
canvas.height = 300;
let ctx = canvas.getContext('2d');
let mousePos = {
x: undefined,
y: undefined
};
function Circle(x, y, r) {
this.x = x;
this.y = y;
this.r = r;
this.draw = function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
ctx.stroke();
ctx.fill();
ctx.closePath();
};
this.clickCircle = function(xmouse, ymouse) {
let distance = Math.sqrt(
(xmouse - this.x) * (xmouse - this.x) +
(ymouse - this.y) * (ymouse - this.y)
);
console.log(distance);
};
}
let myCircle = new Circle(100, 100, 20);
myCircle.draw();
canvas.addEventListener('click', e => {
const rect = canvas.getBoundingClientRect();
mousePos.x = e.clientX - rect.left;
mousePos.y = e.clientY - rect.top;
myCircle.clickCircle(mousePos.x, mousePos.y);
});
canvas {
border: 1px solid black;
background-color: wheat;
/* width: 100%; REMOVED THIS */
}
<div class="container">
<canvas id="app"></canvas>
</div>