You can use the isPointInPath method on the canvas context to check if a particular x and y coordinate is within the bounds of a Path2D object.
This means that you can maintain a list of Path2D objects that respond to a mousemove event. I've put up a fiddle here demonstrating how you can make a path respond to this event. The following snippet of code simply stores the canvas, its 2D context and the list of Path2D parallelograms you are concerned with. Following this, the parallelogram is created using a simple drawParallelogram
function which creates the Path2D object, forms the shape of the parallelogram using the moveTo
and lineTo
methods and then returns it at the end. This object is then filled by the context and stored in the paths array so it can later be used by the canvas mousemove
event.
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var paths = [];
function drawParallelogram(x, y, width, height, offset) {
var path = new Path2D();
path.moveTo(x, y + offset);
path.lineTo(x, y + height);
path.lineTo(x + width, y + height - offset);
path.lineTo(x + width, y);
return path;
}
var parallelogram = drawParallelogram(50, 50, 150, 100, 30);
ctx.fill(parallelogram);
paths.push(parallelogram);
Following, this you want to add the mousemove
event listener to the canvas so you can start detecting when a parallelogram has been hovered on.
canvas.addEventListener('mousemove', function (event) {
var canvas = event.target;
var ctx = canvas.getContext('2d');
var rect = canvas.getBoundingClientRect();
var x = event.clientX - rect.left;
var y = event.clientY - rect.top;
ctx.clearRect(0, 0, canvas.width, canvas.height);
paths.forEach(function (path) {
if (ctx.isPointInPath(path, x, y)) {
// Hovered.
ctx.fillStyle = '#f00';
ctx.fill(path);
} else {
// Go back to default state.
ctx.fillStyle = '#000';
ctx.fill(path);
}
});
});
During the mousemove
event listener, we retrieve the current x
and y
coordinate of the mouse pointer and then clear the current canvas so that any anti-aliasing artifacts are removed when drawing on top of the object again. Following this, you can iterate through each path
in the paths
array and check whether the current x and y coordinate is within the path
. When that's the case, you know you've hovered on the item and can change its fill colour, otherwise revert it back to default settings.
One way you could improve what happens here is to create JavaScript classes for each type of hoverable item and fire some custom hover
and leave
event instead of manually adjusting the fill colour. This implementation would enable you to handle additional types of objects more easily.