是什么导致了我的 canvas 游戏中鼠标位置的这种偏移?

What could be causing this offset in the mouse position on my canvas game?

我目前正在创建一个最终项目,该项目应该类似于经典的恐怖迷宫游戏。我正在使用 Vanilla JS 和 HTML5 Canvas 并且不希望使用外部库或框架。鼠标的位置和应该跟随它的矩形之间有很大的偏移。似乎当我离屏幕的左角越远时,偏移量就越大。看看:

https://github.uconn.edu/pages/ssw19002/dmd-3475/final-project/maze-page-1.html

如果有人有任何可能导致这种情况的原因,请告诉我!我是 <canvas>.

的新手

所以这里的问题实际上根本不在于 Javascript,而在于 CSS。

在 CSS 中,您将 canvas 的宽度设置为占据容器的 100%,并根据宽度自动缩放高度。

canvas {
    border: 1px solid black;
    background-color: black;
    width: 100%;
    height: auto;
    margin: 0;
    display: inline;
    /* cursor: none; */
}

但是在您的 JS 中,您告诉脚本 canvas 的宽度恰好为 1600 像素,高度恰好为 1400 像素。这混淆了事件侦听器,使其基于返回的 1600x1400 数字而不是 CSS.

中设置的实际大小
var canvas = document.querySelector('canvas');

// returning a drawing context to a variable 'c'
// allows you to draw 2d elements
var c = canvas.getContext('2d');

canvas.width = 1600;
canvas.height = 1400;
canvas.style.width = 1600;
canvas.style.height = 1400;

要解决此问题,您只需将 canvas 设置为固定大小,或者在页面加载时读取大小并在每次重新加载页面时更新数字。下面是第一个可能的解决方案的示例。请注意,该示例未考虑与滚动偏移相关的问题。

var canvas = document.querySelector('canvas');

  // returning a drawing context to a variable 'c'
  // allows you to draw 2d elements
  var c = canvas.getContext('2d');

    canvas.width = 1600;
    canvas.height = 1400;
    canvas.style.width = 1600;
    canvas.style.height = 1400;
    
///----------------------------------------------------

var canvasPos = getPosition(canvas);

var mouseX = 0;
var mouseY = 0;

var mouseWidth = 30;
var mouseHeight = 30;
 
canvas.addEventListener("mousemove", setMousePosition);
 
function setMousePosition(e) {  
  mouseX = e.clientX - canvasPos.x;
  mouseY = e.clientY - canvasPos.y;
}   

function update() {

  c.clearRect(0, 0, canvas.width, canvas.height);

  //1. create landscapes
    // a. Maze (blue region)
    c.beginPath();
    c.moveTo(150, 1300); //start
    c.lineTo(150, 400);
    c.lineTo(1350, 400);
    c.lineTo(1350, 450);
    c.lineTo(700, 450);
    c.lineTo(700, 1300);
    c.lineTo(150, 1300);
    c.fillStyle = "#C1EEFF";
    c.fill();

    //Red region
    c.beginPath();
    c.moveTo(1350, 400);
    c.lineTo(1350, 450);
    c.lineTo(1300, 450);
    c.lineTo(1300, 400);
    c.moveTo(1350, 400);
    c.fillStyle = "#FF4000";
    c.fill();

  //2. create cursor
  c.beginPath();
  c.rect(mouseX, mouseY, mouseWidth, mouseHeight);
  c.fillStyle = "#928C6F";
  c.fill();

  // console.log(mouseX, mouseY);
  requestAnimationFrame(update);
}

canvas.addEventListener("mousemove", update());

function getPosition(el) {
  var xPosition = 0;
  var yPosition = 0;
 
  while (el) {
    xPosition += (el.offsetLeft - el.scrollLeft + el.clientLeft);
    yPosition += (el.offsetTop - el.scrollTop + el.clientTop);
    el = el.offsetParent;
  }
  return {
    x: xPosition,
    y: yPosition
  };
}
h1 {
    text-align: center;
  }
  
  canvas {
    border: 1px solid black;
    background-color: black;
    
    
    /* HERE'S WHERE THE CHANGE IS BEING MADE */ 
    /* width: 100%; */
    /* height: auto; */
    
    
    margin: 0;
    display: inline;
    /* cursor: none; */
  }
  
  .container {
    text-align: center;
    margin: 0;
    /* display: flex;
    justify-content: center; */
  }
  
  body {
    margin: 0;
    max-width: 1000px;
    background-color: #6d72c3;
  }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="maze.css">
    <title>Maze Game</title>
    </head>


    <body>
      <div class="container">
        <canvas></canvas>
      </div>

      <script src = "maze.js"></script>
    </body>
</html>

for helping me find the solution. I essentially just removed the extra margin in all of the parent containers of the canvas, as well as the canvas itself. I then set a fixed width in the JS for the width and height of the canvas, as canvas.width/canvas.height. The mouse offset is essentially gone. Check it out – https://github.uconn.edu/pages/ssw19002/dmd-3475/final-project/maze-page-1.html

呐喊