Just redefine your path (without drawing it), then use (instead of isPointInPath()):
ctx.isPointInStroke(x, y)
It will even consider the line thickness of the stroke.
The problem with this solution is that these path checks are not supported in IE (
). For that you need a manual solution. But for browsers which do (you can feature check this), simple use it like this:
Example
var ctx = document.querySelector("canvas").getContext("2d");
function getEllipse(ctx, cx, cy, rx, ry) { // render an ellipse
var angleStep = 0.05, angle = angleStep;
ctx.moveTo(cx + rx, cy); // start at angle 0
while(angle < Math.PI*2) {
ctx.lineTo(
cx + rx * Math.cos(angle), // store these to an array as wanted
cy + ry * Math.sin(angle)
);
angle += angleStep
}
ctx.closePath();
}
// draw an ellipse:
getEllipse(ctx, 150, 75, 100, 60);
ctx.lineWidth = 10;
ctx.stroke();
// reuse ellipse path when checking for mouse position
ctx.canvas.onmousemove = function(e) {
ctx.clearRect(0,0,300,150);
var rect = this.getBoundingClientRect(), // get adjusted mouse position
x = e.clientX - rect.left,
y = e.clientY - rect.top;
ctx.strokeStyle = ctx.isPointInStroke(x, y) ? "red" : "black";
ctx.stroke();
};
<canvas></canvas>
Note that context already has an ellipse method, it doesn't have the greatest support yet, but when it does you could instead of storing each point along the ellipse, store the center and radius (it do support rotation as well as start and end angles too). Something to have in mind for later.
Support as of 2018/9
api.CanvasRenderingContext2D.isPointInStroke
On Standard Track
https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/isPointInStroke
DESKTOP > |Chrome |Edge |Firefox |IE |Opera |Safari
:----------------|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:
isPointInStroke | Y | - | Y | - | Y | Y
MOBILE > |Chrome/A |Edge/mob |Firefox/A |Opera/A |Safari/iOS|Webview/A
:----------------|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:
isPointInStroke | Y | Y | Y | Y | Y | Y
Data from MDN - "npm i -g mdncomp" (c) epistemex
For these browsers you can use this polyfill.
Other alternatives is to use line-intersection. Iterate your array and check each line segment against a line going from center to mouse. You will get a x/y coordinate if it does, then apply a radius check for thickness (you can optimize by only selecting the closest lines to an angle etc.)
How to do line intersection can be found in this answer (getIntersection).