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.