Skip to content
Advertisement

(JS/CANVAS/HTML) – isPoinToPath inaccurate?

Below here, the provided snippet for testing purpose.

The yellow(y) represent the canvas area, return “n” on click

The red(r) represent the click area, return “y” on click

The trouble(x) represent the error, return “y” when clicked

How to make it right?

yyyyyyyyyyyyyyy
yyrrrrrrrrrrryy
yyrrrrrrrrrrryy
yyxxxxxxxxxxxyy
yyyyyyyyyyyyyyy

const canvas = document.getElementById('test');
const context = canvas.getContext('2d');

testClicker();

function testClicker() {
  const buttonz = new Path2D();
  buttonz.rect(canvas.width / 2 - 125, canvas.height / 2 - 70, 250, 80);
  context.fillStyle = 'red';
  context.fill(buttonz);

  var mouseEvent = (event) => {
    // Check whether point is inside rect
    const isPointInPath = context.isPointInPath(buttonz, event.offsetX, event.offsetY);
    let a = isPointInPath ? 'y' : 'n';
    alert(a);
  }

  canvas.addEventListener("click", mouseEvent, false);
}
* {
  margin: 0px;
  padding: 0px;
}

#test {
  position: fixed;
  top: 1%;
  left: calc(50% - 150px);
  width: 300px;
  height: 100px;
  background: yellow;
}
<!DOCTYPE html>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="style.css">
<html>

<body>
  <canvas id="test"></canvas>
</body>
<script src="main.js"></script>

</html>

Advertisement

Answer

You have a mismatch between the CSS setting of height of canvas (100px) and the canvas’s attribute height (set to 150px by default).

You are using canvas.height as the basis for setting the path drawing on the canvas.

This snippet makes things match up by setting the height attribute of the canvas to 100.

const canvas = document.getElementById('test');
const context = canvas.getContext('2d');

testClicker();

function testClicker() {
  const buttonz = new Path2D();
  alert(canvas.height);
  buttonz.rect(canvas.width / 2 - 125, canvas.height / 2 - 70, 250, 80);
  context.fillStyle = 'red';
  context.fill(buttonz);

  var mouseEvent = (event) => {
    // Check whether point is inside rect
    alert(event.offsetY);
    const isPointInPath = context.isPointInPath(buttonz, event.offsetX, event.offsetY);
    let a = isPointInPath ? 'y' : 'n';
    alert(a);
  }

  canvas.addEventListener("click", mouseEvent, false);
}
* {
  margin: 0px;
  padding: 0px;
}

#test {
  position: fixed;
  top: 1%;
  left: calc(50% - 150px);
  width: 300px;
  height: 100px;
  background: yellow;
}
<!DOCTYPE html>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="style.css">
<html>

<body>
  <canvas id="test" width="300" height="100"></canvas>
</body>
<script src="main.js"></script>

</html>

See MDN for further explanation of the difference between setting dimensions of the canvas using the width/height attributes and using CSS. If they differ you get scaling/distortion.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement