是什么导致了我的 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
呐喊
我目前正在创建一个最终项目,该项目应该类似于经典的恐怖迷宫游戏。我正在使用 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>
向