javascript - 当 Canvas 滚动到屏幕外时无法拖动 Canvas 中的对象

标签 javascript canvas scroll mouseevent mousemove

我用 draggable battleships on a canvas 做了一个可以工作的 jsFiddle |和 have just added some HTML paragraphs在它的上面。顿时拖不住战列舰了。

我尝试添加 e.pageXe.pageY在鼠标处理程序中,但这没有帮助。

在这种情况下如何处理滚动内容?

请在下面查看屏幕截图和有问题的 JavaScript 代码的副本 -

screenshot

jQuery(document).ready(function($) {

        var board = document.getElementById("board");
        var ctx = board.getContext("2d");
        ctx.strokeStyle = "lightgray";

        var canvasOffset = $("#board").offset();
        var offsetX = canvasOffset.left;
        var offsetY = canvasOffset.top;

        console.log('ready: offsetX=' + offsetX + ", " + "offsetY=" + offsetY);

        var mouseIsDown = false;
        var lastX = 0;
        var lastY = 0;

        var ships = [];

        makeShip(20, 30, 50, 25, "skyblue");
        makeShip(20, 100, 30, 25, "skyblue");
        makeShip(20, 170, 50, 25, "salmon");
        makeShip(20, 240, 30, 25, "salmon");

        function makeShip(x, y, width, height, fill) {
            var ship = {
                x: x,
                y: y,
                width: width,
                height: height,
                right: x + width,
                bottom: y + height,
                fill: fill
            }
            ships.push(ship);
        }

        drawAllShips();

        function drawAllShips() {
            ctx.clearRect(0, 0, board.width, board.height);
            for (var i = 0; i < ships.length; i++) {
                var ship = ships[i]
                drawShip(ship);
                ctx.fillStyle = ship.fill;
                ctx.fill();
                ctx.stroke();
            }
        }

        function drawShip(ship) {
            ctx.beginPath();
            ctx.moveTo(ship.x, ship.y);
            ctx.lineTo(ship.right, ship.y);
            ctx.lineTo(ship.right + 10, ship.y + ship.height / 2);
            ctx.lineTo(ship.right, ship.bottom);
            ctx.lineTo(ship.x, ship.bottom);
            ctx.closePath();
        }

        function handleMouseDown(e) {

            mouseX = parseInt(e.clientX - offsetX);
            mouseY = parseInt(e.clientY - offsetY);

            console.log('handleMouseDown: mouseX=' + mouseX + ", " + "mouseY=" + mouseY);

            lastX = mouseX;
            lastY = mouseY;
            mouseIsDown = true;
        }

        function handleMouseUp(e) {
            mouseX = parseInt(e.clientX - offsetX);
            mouseY = parseInt(e.clientY - offsetY);

            console.log('handleMouseUp: mouseX=' + mouseX + ", " + "mouseY=" + mouseY);

            mouseIsDown = false;
        }

        function handleMouseMove(e) {
            if (!mouseIsDown) {
                return;
            }

            mouseX = parseInt(e.clientX - offsetX);
            mouseY = parseInt(e.clientY - offsetY);

            console.log('handleMouseMove: mouseX=' + mouseX + ", " + "mouseY=" + mouseY);

            for (var i = 0; i < ships.length; i++) {
                var ship = ships[i];
                drawShip(ship);
                if (ctx.isPointInPath(lastX, lastY)) {
                    ship.x += (mouseX - lastX);
                    ship.y += (mouseY - lastY);
                    ship.right = ship.x + ship.width;
                    ship.bottom = ship.y + ship.height;
                }
            }
            lastX = mouseX;
            lastY = mouseY;
            drawAllShips();
        }

        $("#board").mousedown(function(e) {
            handleMouseDown(e);
        });

        $("#board").mousemove(function(e) {
            handleMouseMove(e);
        });

        $("#board").mouseup(function(e) {
            handleMouseUp(e);
        });
});

最佳答案

您还需要考虑文档滚动值

这是我创建的示例

jQuery(document).ready(function($) {

        var board = document.getElementById("board");
        var ctx = board.getContext("2d");
        ctx.strokeStyle = "lightgray";

        var canvasOffset = $("#board").offset();
        var offsetX = canvasOffset.left;
        var offsetY = canvasOffset.top;

        var scrolltop = $(document).scrollTop();
        var scrollleft = $(document).scrollLeft();

        console.log('ready: offsetX=' + offsetX + ", " + "offsetY=" + offsetY, scrolltop, scrollleft);

        var mouseIsDown = false;
        var lastX = 0;
        var lastY = 0;

        var ships = [];

        makeShip(20, 30, 50, 25, "skyblue");
        makeShip(20, 100, 30, 25, "skyblue");
        makeShip(20, 170, 50, 25, "salmon");
        makeShip(20, 240, 30, 25, "salmon");

        function makeShip(x, y, width, height, fill) {
            var ship = {
                x: x,
                y: y,
                width: width,
                height: height,
                right: x + width,
                bottom: y + height,
                fill: fill
            }
            ships.push(ship);
            return (ship);
        }

        drawAllShips();

        function drawAllShips() {
            ctx.clearRect(0, 0, board.width, board.height);
            for (var i = 0; i < ships.length; i++) {
                var ship = ships[i]
                drawShip(ship);
                ctx.fillStyle = ship.fill;
                ctx.fill();
                ctx.stroke();
            }
        }

        function drawShip(ship) {
            ctx.beginPath();
            ctx.moveTo(ship.x, ship.y);
            ctx.lineTo(ship.right, ship.y);
            ctx.lineTo(ship.right + 10, ship.y + ship.height / 2);
            ctx.lineTo(ship.right, ship.bottom);
            ctx.lineTo(ship.x, ship.bottom);
            ctx.closePath();
        }

        function handleMouseDown(e) {

            scrolltop = $(document).scrollTop();
            scrollleft = $(document).scrollLeft();

            mouseX = parseInt(e.clientX - offsetX + scrollleft);
            mouseY = parseInt(e.clientY - offsetY + scrolltop);

            lastX = mouseX;
            lastY = mouseY;
            mouseIsDown = true;

            console.log('ready: offsetX=' + offsetX + ", " + "offsetY=" + offsetY, scrolltop, scrollleft);
        }

        function handleMouseUp(e) {
            mouseX = parseInt(e.clientX - offsetX + scrollleft);
            mouseY = parseInt(e.clientY - offsetY + scrolltop);

            console.log('handleMouseUp: mouseX=' + mouseX + ", " + "mouseY=" + mouseY);

            mouseIsDown = false;
        }

        function handleMouseMove(e) {
            if (!mouseIsDown) {
                return;
            }

            mouseX = parseInt(e.clientX - offsetX + scrollleft);
            mouseY = parseInt(e.clientY - offsetY + scrolltop);

            console.log('handleMouseMove: mouseX=' + mouseX + ", " + "mouseY=" + mouseY);

            for (var i = 0; i < ships.length; i++) {
                var ship = ships[i];
                drawShip(ship);
                if (ctx.isPointInPath(lastX, lastY)) {
                    ship.x += (mouseX - lastX);
                    ship.y += (mouseY - lastY);
                    ship.right = ship.x + ship.width;
                    ship.bottom = ship.y + ship.height;
                }
            }
            lastX = mouseX;
            lastY = mouseY;
            drawAllShips();
        }

        $("#board").mousedown(function (e) {
            handleMouseDown(e);
        });

        $("#board").mousemove(function (e) {
            handleMouseMove(e);
        });

        $("#board").mouseup(function (e) {
            handleMouseUp(e);
        });

});

DEMO HERE

关于javascript - 当 Canvas 滚动到屏幕外时无法拖动 Canvas 中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36591866/

相关文章:

javascript - Jquery滚动事件导致性能问题

javascript - 如何聚焦隐藏的输入字段

javascript - 使用 Javascript 收集鼠标在 Canvas 上的位置

javascript - 使用 paperjs 在图像上绘图

jquery - 固定 div 位置而不考虑滚动条

javascript - 为什么我的平滑滚动不流畅?

javascript - JavaScript 中的 session

javascript - 使用jquery突出显示特定位置的文本

javascript - 时区转换时刻js

javascript - JQuery 在调整图像 Canvas 大小后仅调整图像而不是 Canvas