Detect if user clicks inside a circle

How can I detect when the user clicks inside the red bubble?

It should not be like a square field. The mouse must be really inside the circle:

img

Here's the code:

<canvas id="canvas" width="1000" height="500"></canvas>
<script>
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d")

var w = canvas.width
var h = canvas.height

var bubble = {
  x: w / 2,
  y: h / 2,
  r: 30,
}

window.onmousedown = function(e) {
    x = e.pageX - canvas.getBoundingClientRect().left
    y = e.pageY - canvas.getBoundingClientRect().top

    if (MOUSE IS INSIDE BUBBLE) {
        alert("HELLO!")
    }
}

ctx.beginPath()
ctx.fillStyle = "red"
ctx.arc(bubble.x, bubble.y, bubble.r, 0, Math.PI*2, false)
ctx.fill()
ctx.closePath()
</script>

A circle, is the geometric position of all the points whose distance from a central point is equal to some number "R".

You want to find the points whose distance is less than or equal to that "R", our radius.

The distance equation in 2d euclidean space is d(p1,p2) = root((p1.x-p2.x)^2 + (p1.y-p2.y)^2).

Check if the distance between your p and the center of the circle is less than the radius.

Let's say I have a circle with radius r and center at position (x0,y0) and a point (x1,y1) and I want to check if that point is in the circle or not.

I'd need to check if d((x0,y0),(x1,y1)) < r which translates to:

Math.sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0)) < r

In JavaScript.

Now you know all these values (x0,y0) being bubble.x and bubble.y and (x1,y1) being x and y.


To test if a point is within a circle, you want to determine if the distance between the given point and the center of the circle is smaller than the radius of the circle.

Instead of using the point-distance formula, which involves the use of a (slow) square root, you can compare the non-square-rooted (or still-squared) distance between the points. If that distance is less than the radius squared, then you're in!

// x,y is the point to test
// cx, cy is circle center, and radius is circle radius
function pointInCircle(x, y, cx, cy, radius) {
  var distancesquared = (x - cx) * (x - cx) + (y - cy) * (y - cy);
  return distancesquared <= radius * radius;
}

(Not using your code because I want to keep the function general for onlookers who come to this question later)

This is slightly more complicated to comprehend, but its also faster, and if you intend on ever checking point-in-circle in a drawing/animation/object moving loop, then you'll want to do it the fastest way possible.

Related JS perf test:

http://jsperf.com/no-square-root


Just calculate the distance between the mouse pointer and the center of your circle, then decide whether it's inside:

var dx = x - bubble.x,
dy = y - bubble.y,
dist = Math.sqrt(dx * dx + dy * dy);

if (dist < bubble.r) {
  alert('hello');
}

Demo

As mentioned in the comments, to eliminate Math.sqrt() you can use:

var distsq = dx * dx + dy * dy,
rsq = bubble.r * bubble.r;

if (distsq < rsq) {
   alert('HELLO');
}

An alternative (not always useful meaning it will only work for the last path (re)defined, but I bring it up as an option):

x = e.pageX - canvas.getBoundingClientRect().left
y = e.pageY - canvas.getBoundingClientRect().top

if (ctx.isPointInPath(x, y)) {
    alert("HELLO!")
}

Path can btw. be any shape.

For more details:
http://www.w3.org/TR/2dcontext/#dom-context-2d-ispointinpath