The isPointInPath(x, y) function might not be one that you immediately come across when you first start using canvas to draw things. When you start adding interactivity and events though it's usefulness does start to shine through. The isPointInPath() function does exactly as the name suggests - it determines whether the coordinates that you give it are in the current path. With simple shapes like squares, rectangles and even circles it's easy to test whether a point is within the boundaries of the shape but with more complex shapes that involve curves or things like parallelograms the function can save you a lot of time and simplify your code significantly.
The isPointInPath() function only works on the current path - so to test multiple paths you must replay each path (they don't need to be stroked or filled) and test them in turn. This is the method used by the Funnel chart to greatly simplify the testing of the cursor position (the getShape() function). Previously trigonometry functions were used to work out whether the mouse coordinates were within the boundaries of the shape but the isPointInPath() function massively simplified the process allowing significant amounts of code to be eliminated.
The isPointInPath() function is supported by all browsers that support canvas. Obviously this means that IE7 and IE8 don't support it.
When the new path object is available it will mean that testing multiple paths gets really easy. To allow the isPointInPath() function to work with path objects you can specify the path to be tested as one of the arguments to the function like this:
context.isPointInPath(x, y); // Original context.isPointInPath(path, x, y); // New
Either variant will be usable. Currently - since Path objects aren't implemented - only the first variant is supported.
This is a simplified example of the function being used in order to change the mouse cursor when a shape is hovered over. The code for the example is shown below. In the example the mouse position is gained using the RGraph.getMouseXY(e) function. This function is in the RGraph.common.core.js library.
<script>
window.onload = function (e)
{
var canvas = document.getElementById('cvs');
var context = canvas.getContext('2d');
// Draw the rectangle
context.beginPath();
context.rect(50,50,100,100);
context.fill();
context.fillStyle = 'red';
// Draw the circle
context.beginPath();
context.arc(450,175, 50, 0,2 * Math.PI, false);
context.fill();
context.fillStyle = 'green';
// Draw the shape
context.beginPath();
context.moveTo(250,100);
context.lineTo(350,175);
context.lineTo(325,215);
context.lineTo(185,195);
context.fill();
canvas.onmousemove = function (e)
{
var canvas = e.target;
var context = canvas.getContext('2d');
// This gets the mouse coordinates (relative to the canvas)
var mouseXY = RGraph.getMouseXY(e);
var mouseX = mouseXY[0];
var mouseY = mouseXY[1];
// Replay the rectangle path (no need to fill() it) and test it
context.beginPath();
context.rect(50,50,100,100);
if (context.isPointInPath(mouseX, mouseY)) {
canvas.style.cursor = 'pointer';
return;
}
///////////////////////////////////////////////////////////////
// Replay the circle path (no need to fill() it) and test it
context.beginPath();
context.arc(450,175, 50, 0,2 * Math.PI, false);
if (context.isPointInPath(mouseX, mouseY)) {
canvas.style.cursor = 'pointer';
return;
}
///////////////////////////////////////////////////////////////
// Replay the irregular shape path (no need to fill() it) and test it
context.beginPath();
context.moveTo(250,100);
context.lineTo(350,175);
context.lineTo(325,215);
context.lineTo(185,195);
if (context.isPointInPath(mouseX, mouseY)) {
canvas.style.cursor = 'pointer';
return;
}
///////////////////////////////////////////////////////////////
// Return the cursor to the default style
canvas.style.cursor = 'default';
}
}
</script>
© Copyright RGraph licensing 2008-2013 All rights reserved. Privacy policy, Terms and conditions