Matthias Southwick
Matthias Southwick

Reputation: 121

Is there a way to detect if a point is in a Path2D object after it has been rotated and translated?

I am trying to find a point in a Path2D object in an HTML5 canvas using JavaScript.

var path = new Path2D;
path.rect(0,0,100,100);
// declare the path

ctx.beginPath(); 
ctx.save()
ctx.translate(500,500);
ctx.rotate(Math.PI/2);
ctx.fill(path);
ctx.restore()
// draw the path after translation and rotation

ctx.isPointInPath(path,505,500) // return false because path is defined at 0, 0 not 500,500 where path is drawn
// Is there a way know if the points are in the path where it is drawn.
// I do not want to re - define the path, but if there is a way to move it that would work.

Please understand that this code is simplified, and the path I am using is not a generic shape, so this needs to work for any given 2d path. This is not a question about syntax so please excuse the undefined variables.

Upvotes: 0

Views: 1761

Answers (1)

Kaiido
Kaiido

Reputation: 136708

isPointInPath() takes its x and y coordinates as untransformed, i.e as absolute coordinates on the canvas, however it does apply the transformations on the given path.

So you need to call it with the applied transformation (i.e, get rid of this ctx.restore()).

However your numbers don't add up:

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d');
const path = new Path2D;
path.rect(0,0,100,100);
// declare the path

ctx.translate(500,500);
ctx.rotate(Math.PI / 2)
ctx.fillStyle = "green";
ctx.fill(path);

// using fixed values
const x = 505;
const y = 500;
console.log(ctx.isPointInPath(path,x,y));

// reset to identity matrix
ctx.setTransform(1,0,0,1,0,0);
ctx.fillStyle = "red";
ctx.fillRect(x-2,y-2,4,4);

document.scrollingElement.scrollBy(600, 650);
<canvas id="canvas" width="600" height="650"></canvas>

But if you use correct coordinates, it will work as expected:

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d');
const path = new Path2D;
path.rect(0,0,100,100);
// declare the path

ctx.translate(500,500);
ctx.rotate(Math.PI / 2)
ctx.fillStyle = "green";
ctx.fill(path);

// using fixed values
const x = 495;
const y = 505;
console.log(ctx.isPointInPath(path,x,y));

// reset to identity matrix
ctx.setTransform(1,0,0,1,0,0);
ctx.fillStyle = "red";
ctx.fillRect(x-2,y-2,4,4);

document.scrollingElement.scrollBy(600, 650);
<canvas id="canvas" width="600" height="650"></canvas>

And if one day you really need to transform a Path2D object, you can refer to this post which uses the second parameter matrix of Path2D.add(path, matrix) to return a transformed copy of the Path2D object.

Upvotes: 4

Related Questions