1

So I've gotten pretty excited about the introduction of Canvas Paths as standard objects in contemporary browsers, and have been trying to see how much mileage I can get out of this new-ish feature. However, my understanding of how these objects interact with the isPointInPath() method (and possibly other path-based methods) is apparently somewhat flawed.

As demonstrated in the first two test functions below, I can get the drawn paths to be recognized by the isPointInPath() method. However, when I define the paths as an object, the method ceases to work (even though the path objects can be recognized for other purposes such as filling).

function startGame(){ //Initiating Environment Variables
 gamemap = document.getElementById("GameMap")
 ctx = gamemap.getContext("2d")
 testCircleBounds()
 testVarCircleBounds()
 testObjCircleBounds()
 testMultiObjCircleBounds()
}

function testCircleBounds() { //Minimalist Test of Path Methods
 ctx.beginPath()
 ctx.arc(250,250,25,0,2*Math.PI)
 console.log(ctx.isPointInPath(250,250)) //point in path detected
 ctx.closePath()
 console.log(ctx.isPointInPath(250,250)) //point in path still detected
 ctx.stroke()
 ctx.fillStyle = "yellow"
 ctx.fill() //fills great
}

function testVarCircleBounds() { //Test of Path Methods with Variables
 x_cen = 250; y_cen = 250; rad = 15
 ctx.beginPath()
 ctx.arc(x_cen,y_cen,rad,0,2*Math.PI)
 ctx.closePath()
 console.log(ctx.isPointInPath(x_cen,y_cen)) //true yet again
 ctx.stroke()
 ctx.fillStyle = "orange"
 ctx.fill() //also fills great
}

function testObjCircleBounds() { //Test of Path Methods with Single Stored Path Object
 x_cen = 250; y_cen = 250; rad = 10
 ctx.beginPath()
 lonely_node = new Path2D()
 lonely_node.arc(x_cen,y_cen,10,0,2*Math.PI)
 ctx.closePath()
 console.log(ctx.isPointInPath(x_cen,y_cen)) //point in path not found!
 ctx.stroke(lonely_node)
 ctx.fillStyle = "red"
 ctx.fill(lonely_node) //but ctx.fill notices the path just fine
}


function testMultiObjCircleBounds(){ //Test of Paths Methods with Multi-Object Referencing
 nodes = [] //initializes set of nodes as array
 for (i=0; i<25; i++) { //generates 25 nodes
  nodes[i] = new Path2D() //defines each node as Path object in the array
  node = nodes[i]
  //Places Nodes along the 'horizon' of the map
  x_cen = 20*i + 10
  y_cen = 100
  ctx.beginPath(node) //"node" argument probably not helping?
  node.arc(x_cen,y_cen,8,0,2*Math.PI)
  console.log(ctx.isPointInPath(x_cen,y_cen)) //still returns false!
  ctx.closePath(node)
  ctx.stroke(node)
  console.log(ctx.isPointInPath(x_cen,y_cen)) //arrgh!!
 }
 // Fill can also be selectively applied to referenced path objects
 for (i=0; i<25; i=i+2) {
  ctx.fill(nodes[i])
 }
  
}
<!DOCTYPE html>
<html>
<head>
<title>Wrap Around Beta</title>
<script src="Circuity_PathObjectTest.js"></script>
</head>

<body onload='startGame()'>
 
<canvas id="GameMap" width="500" height="500" style="border:1px solid #000000"></canvas>

</body>

</html>

Is this fundamentally the wrong way to think about Path2D objects and to record 'hit' areas on a canvas? If so, is there another technique (saving the canvas context for each path drawn or something along that vein) that would produce the desired effect?

Jonathan Straus
  • 317
  • 1
  • 3
  • 12

1 Answers1

2

You must send a reference to the Path2D being tested into isPointInPath:

ctx.isPointInPath( lonely_node, x_cen, y_cen ) 
markE
  • 102,905
  • 11
  • 164
  • 176
  • Oh wow, that was simple. I didn't realize that the object was an argument the method accepted. In the W3C documentation, it only mentions the x and y coordinates as valid arguments: http://www.w3schools.com/tags/canvas_ispointinpath.asp... is there a better resource I should be referring to for this type of thing? – Jonathan Straus Jul 05 '16 at 22:00
  • 1
    w3schools is verrrry hit-and-miss. I often use [MDN](https://developer.mozilla.org/en-US/) for generally complete and accurate information. Cheers! :-) – markE Jul 05 '16 at 22:11