我在“mousemove”事件上使用 offsetX 和 offsetY 属性时遇到问题

问题描述 投票:0回答:1

我正在尝试通过制作一个国际象棋游戏进一步加深 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

尝试过使用或不使用偏移,尝试使用 event.OffsetX、event.LayerX 和 event.Left,但所有这些都最终扰乱了运动。我期望的是即使我调整窗口大小,图像仍保留在光标上

javascript events canvas mouseevent offset
1个回答
0
投票

我检查了你的代码,找到了对我有用的最简单的解决方案。 移动时图片位于光标中心

body, html {
  padding: 0;
  margin: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

你应该隐藏页面上的滚动条,这样你就不必考虑scrollLeft和scrollTop,它也可以称为offsetLeft和offsetTop。 css 属性

overflow: hidden;
负责此操作。如果您确实想保留滚动条,则需要考虑画布元素本身的偏移量,它还可能具有其他可以影响光标位置的属性

© www.soinside.com 2019 - 2024. All rights reserved.