提问人:Courby 提问时间:11/6/2023 更新时间:11/6/2023 访问量:58
我在“mousemove”事件上使用 offsetX 和 offsetY 属性时遇到问题
I have trouble using the offsetX and offsetY properties on `mousemove` events
问:
我正在尝试通过制作国际象棋游戏来进一步学习 JS。
我制作了一个 800*800 的画布,其中放置了 16 个 SVG
然后,我为 mousedown、mousemove 和 mouseup 添加了事件侦听器,以使这些片段可拖动。
除了鼠标移动部分外,一切都很好。我已经在图像尺寸的一半处设置了偏移量,因此在移动图像时光标位于图像的中心,只要我全屏运行页面,它就可以正常工作。但是,如果我减小窗口大小并移动滚动条,则图像位置将关闭。
听说了 offsetX 和 offsetY 属性,我尝试使用它们。但我认为我做错了,因为我所能做的就是在移动鼠标时让图像到处传送。
这是我的代码的一个简短、快速测试的版本:
[HTML全文]
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
<title>Chess</title>
</head>
<body>
<div id ="container" style="position:relative;">
<div id="gameBox" class="game">
<canvas id="board" width="800px" height="800px" style = "position:absolute;z-index=-1"></canvas>
<img id ="brook1" src="assets/piecebrook.svg" style="position:absolute;left:0px;top:0px;" draggable="false"/>
</div>
</div>
<script type="text/javascript" src="js/utility.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>
JS系列
class ChessGame {
constructor () {
this.b = document.getElementById("board");
this.c = document.getElementById("gameBox");
this.bContext = this.b.getContext("2d");
this.bContext.fillStyle = "#825e2b";
this.bContext.lineWidth = "5";
this.pieces = [];
this.selectedPiece = null;
}
addListeners = function() {
this.c.addEventListener('mousedown', function(event) {
var x = event.clientX;
var y = event.clientY;
eventOnMouseDown(document.elementFromPoint(x,y));
}, false);
window.addEventListener('mouseup', eventOnMouseUp, false);
}
fillBoard = function() {
this.bContext.clearRect(0, 0, 800, 800);
var fill = true;
for (let i = 0; i < 8; i++) {
fill = (fill) ? false : true;
for (let j = 0; j < 8; j++) {
this.bContext.beginPath()
{
this.bContext.fillStyle = (fill) ? "#76521f" : "#ffffff";
this.bContext.fillRect(j * 100, i * 100, 100, 100);
}
fill = (fill) ? false : true;
}
}
}
startGame = function() {
this.fillBoard();
this.generatePieces();
this.addListeners();
var obj = document.getElementById("brook1");
this.pieces[id] = obj;
}
}
eventOnMouseDown = function(elem) {
if (elem.id != "board") {
var piece = game.pieces[elem.id];
game.selectedPiece = document.getElementById(elem.id);
game.selectedPiece.style.zIndex = "50";
window.addEventListener('mousemove', movePiece, true);
}
}
eventOnMouseUp = function(event) {
window.removeEventListener('mousemove', movePiece, true);
}
movePiece = function(event) {
let offsetX = game.selectedPiece.width / 2;
let offsetY = game.selectedPiece.height / 2;
game.selectedPiece.style.top = (event.clientY - offsetY) + 'px';
game.selectedPiece.style.left = (event.clientX - offsetX) + 'px';
}
var game = new ChessGame();
game.startGame();
我正在使用的 SVG:https://svgshare.com/s/zMV
尝试过有和没有偏移量,尝试使用事件。OffsetX,事件。LayerX 和事件。离开了,但他们都结束了这场运动。我所期望的是,即使我调整窗口大小,图像也会保留在光标上
答:
0赞
waffentrager
11/6/2023
#1
我检查了您的代码,找到了最适合我的解决方案。 图片在移动过程中位于光标的中心
body, html {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
您应该隐藏页面上的滚动条,这样您就不必考虑 scrollLeft 和 scrollTop,它也可以称为 offsetLeft 和 offsetTop。css 属性对此负责。如果您确实想保留滚动条,则需要考虑 canvas 元素本身的偏移量,它可能还具有其他可能影响光标位置的属性overflow: hidden;
movePiece = function(event) {
let offsetX = game.selectedPiece.width / 2;
let offsetY = game.selectedPiece.height / 2;
let winY = window.scrollY || window.pageYOffset;
let winX = window.scrollX || window.pageXOffset;
game.selectedPiece.style.top = (event.clientY - game.selectedPiece.offsetParent.offsetTop + winY - offsetY) + 'px';
game.selectedPiece.style.left = (event.clientX - game.selectedPiece.offsetParent.offsetLeft + winX - offsetX) + 'px';
}
评论
{ this.bContext.fillStyle ...