Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Click on an object using canvas and javascript [duplicate]

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>
like image 403
walid naceri Avatar asked Jun 07 '26 11:06

walid naceri


1 Answers

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>
like image 93
Artem Arkhipov Avatar answered Jun 10 '26 06:06

Artem Arkhipov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!