为了账号安全,请及时绑定邮箱和手机立即绑定

如何计算点击可拖动画布元素的位置?

如何计算点击可拖动画布元素的位置?

慕仙森 2022-01-07 18:45:47
我需要帮助解决一个非常困难的问题。我目前正在使用 React 和 Redux 制作游戏。在这个游戏中,我使用画布从我的 redux 商店创建地图数据。目前,该地图只是一个黑白方块矩阵。假设我想在你点击一个正方形时改变它的颜色,但还要保持拖动元素的能力。问题是很难精确定位鼠标点击的位置,因为元素可以拖动到页面上的任何位置。据我所知,mouseclick 事件对象属性似乎都无法告诉我。我以为 offsetX 和 offsetY 会告诉我,但是当画布对象由于某种原因移动时,它们似乎并没有保持不变。我在这个项目中使用 React 和 Redux,并且 CanvasMap 元素被包装在来自这个库的 Draggable 中:https ://www.npmjs.com/package/react-draggable#draggablecoreimport React from 'react'import { connect } from 'react-redux'import './CanvasMap.css'class CanvasMap extends React.Component{  componentDidMount() {    const map = this.props.map //Data representing the map    const canvas = this.refs.canvas    const context = canvas.getContext('2d')    //Building the map on the canvas    for(let i = 0; i < map.length; i++){      for(let j = 0; j < map[i].length; j++){        const x=i*100        const y=j*100        const isBlackSquare= map[i][j] === 'black' ? true : false        if(isBlackSquare) context.fillRect(x, y, 100, 100)        else context.strokeRect(x, y, 100, 100)      }    }    function handleClick(e){      //None of the event properties seem to stay the same when the canvas is moved      console.log(e)    }    canvas.addEventListener('click', handleClick)  }  render(){    return (      <div className='Map'>        <canvas ref='canvas' width={8000} height={8000} />      </div>    )  }}function mapStateToProps(state){  return {    map: [...state.map]  }}const connectedComponent = connect(mapStateToProps)(CanvasMap)export { connectedComponent as CanvasMap }
查看完整描述

2 回答

?
UYOU

TA贡献1878条经验 获得超4个赞

解决了!


我迷失在围绕元素和点击事件的大量数据中,我试图找出 pageX、clientX、offsetLeft、screenX 等的正确组合。但是,一旦你确切知道该怎么做,最终的解决方案就会非常简单。这里是:


function handleClick(e){

  const rect = e.target.getBoundingClientRect()

  const x = e.pageX - rect.left

  const y = e.pageY - rect.top

}

无论您拖动和重新定位元素的位置,这都应该为您提供鼠标相对于元素的确切 x 和 y 坐标。


查看完整回答
反对 回复 2022-01-07
?
神不在的星期二

TA贡献1963条经验 获得超6个赞

在大多数情况下,当您单击 HTML 元素时,您可以使用 rectangleBounding Box 并从中获取协调器,例如


domRect = element.getBoundingClientRect();

在画布点击位置有点困难


这是我前一段时间在画布上拖动鼠标时绘制的脚本。也许您可以应用此方法


<html>

    <head>

    <style>


    * { margin:0; padding:0; } /* to remove the top and left whitespace */


    html, body { width:100%; height:100%; } /* just to be sure these are full screen*/


    canvas { display:block; } /* To remove the scrollbars */




    </style>

    </head>


    <body>

    <canvas id="canvas" ></canvas>

    <script>




    ////////////////////////////////////////



    (function() {

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

        var ctx = canvas.getContext('2d');


        var elemLeft = canvas.offsetLeft;

        var elemTop = canvas.offsetTop;

        var BB=canvas.getBoundingClientRect();

        var offsetX=BB.left;

        var offsetY=BB.top;


        // resize the canvas to fill browser window dynamically

        window.addEventListener('resize', resizeCanvas, false);


        function resizeCanvas() {

            canvas.width = window.innerWidth;

            canvas.height = window.innerHeight;


            /**

                * Your drawings need to be inside this function otherwise they will be reset when 

                * you resize the browser window and the canvas goes will be cleared.

            */

            drawStuff(); 

        }

        resizeCanvas();


        function drawStuff() {

            // do your drawing stuff here

            var img = new Image();              


            img.src = 'images/3PkBe.gif';

            img.onload = function()

            {

                //var canvas = document.getElementById('canvas');

                // create pattern

                var ptrn = ctx.createPattern(img, 'repeat'); // Create a pattern with this image, and set it to "repeat".

                ctx.fillStyle = ptrn;

                ctx.fillRect(0, 0, canvas.width, canvas.height); // context.fillRect(x, y, width, height);

                ctx.shadowBlur=20;

                //ctx.shadowColor="black";

                //ctx.fillStyle="green";

                //ctx.fillRect(20,160,100,80);



                ctx.strokeStyle = "lightgray";


                //var canvasOffset = canvas.offset();

                //var offsetX = canvasOffset.left;

                //var offsetY = canvasOffset.top;


                var mouseIsDown = false;

                var lastX = 0;

                var lastY = 0;

                var elements = [];


                makeShip( 30 , 30,120, 120,  '#119' , "romea");

                makeShip( 30, 160,120, 120,  '#393', "fomar");

                makeShip( 30, 290,120, 120,  '#955', "ojab");

                makeShip( 30, 420,120, 120,  '#6ff', "eliot");

                // Add event listener for `click` events.


                canvas.addEventListener('click', function(event) {


                    var x = event.pageX - elemLeft,

                    y = event.pageY - elemTop;

                    console.info(x, y);

                    elements.forEach(function(element) {


                        if (y > element.y && y < element.y + element.height && x > element.x && x < element.x + element.width) {

                            console.log(element.name);

                        }

                    });






                }, false);


                canvas.addEventListener('mousedown', function(event) {


                        var x = event.pageX - elemLeft,

                    y = event.pageY - elemTop;

                    console.info(x, y);

                    elements.forEach(function(element) {


                        if (y > element.y && y < element.y + element.height && x > element.x && x < element.x + element.width) {

                            console.info(element.name);

                            handleMouseDown(element);

                        }

                    });




                }, false);


                canvas.addEventListener('mousemove', function(event) {



                    var x = event.pageX - elemLeft,

                    y = event.pageY - elemTop;

                    console.info(x, y);

                    elements.forEach(function(element) {


                        if (y > element.y && y < element.y + element.height && x > element.x && x < element.x + element.width) {

                            console.info(element.name);

                            handleMouseMove(element,x,y);

                        }

                    });


                }, false);


                canvas.addEventListener('mouseup', function(event) {



                    var x = event.pageX - elemLeft,

                    y = event.pageY - elemTop;

                    //console.info(x, y);


                    elements.forEach(function(element) {


                        //if (y > element.y && y < element.y + element.height && x > element.x && x < element.x + element.width) {

                            console.info(element.name + "mouse up evenr=========");

                            handleMouseUp(element);

                    //}

                    });


                }, false);





                function makeShip(x, y, width, height, colour,ShipName) {

                    var ship = {

                        name: ShipName,

                        colour: colour,

                        width: width,

                        height: height,

                        x: x,

                        y: y

                    }

                    elements.push(ship);

                    return (ship);

                }

                function drawShip(ship) {


                    //ctx.fillStyle = ship.colour;

                    //ctx.fillRect(ship.x, ship.y, ship.width, ship.height);

                    //ctx.fillRect(element.x, element.y, element.width, element.height);

                }


                function drawAllShips() {

                    //  ctx.clearRect(0, 0, canvas.width, canvas.height);

                    for (var i = 0; i < elements.length; i++) {

                        var ship = elements[i]

                        //drawShip(ship);

                    ctx.fillStyle = ship.colour;

                    ctx.fillRect(ship.x , ship.y, ship.width, ship.height);

                        //   ctx.fillStyle = ship.fill;

                        //   ctx.fill();

                        //    ctx.stroke();

                    }

                }





                // Add element.

                //elements.push({

                //colour: '#05EFFF',

                //width: 150,

                //height: 100,

                //x: 20,

                //y: 15

            //});


            // Render elements.

            //  elements.forEach(function(element) {

            //      ctx.fillStyle = element.colour;

            //      ctx.fillRect(element.x, element.y, element.width, element.height);

            //  });


            drawAllShips();



            function handleMouseDown(e) {

              mouseX = e.x ;

              mouseY = e.y ;


                //mouseX = parseInt(e.x - offsetX);

                //mouseY = parseInt(e.y - offsetY);

                console.log("===========Problem "+mouseX);

                // mousedown stuff here

                lastX = mouseX;

                lastY = mouseY;

                mouseIsDown = true;

                //alert("mouse Handle");


            }


            function handleMouseUp(e) {

                //mouseX = parseInt(e.clientX - offsetX);

                //mouseY = parseInt(e.clientY - offsetY);


     ctx.onmousemove = null;

                // mouseup stuff here

                mouseIsDown = false;

                return

            }


            function handleMouseMove(e,x,y) {

                if (mouseIsDown) {




                //console.log(' no fuck');

                mouseX = e.x ;

                mouseY = e.y ;

                console.log(e.name+"is truing to drag");


                // mousemove stuff here

                //for (var i = 0; i < elements.length; i++) {


                        //if (ctx.isPointInPath(mouseX, mouseY)) {

                    //console.log('============== no fuck');

                    var ship =e;// elements[i];

                    ship.x = x-15;//(mouseX - lastX);

                    ship.y = y-20;//(mouseY -lastY);

                //  ship.right = ship.x + ship.width;

                //  ship.bottom = ship.y + ship.height;


                    //drawShip(ship);

            //}


            //}

                lastX = mouseX;

                lastY = mouseY;

                drawAllShips(); 

                }

            }


            <!-- ctx.mousedown(function (e) { -->

                <!-- handleMouseDown(e); -->

            <!-- }); -->

            <!-- ctx.mousemove(function (e) { -->

                <!-- handleMouseMove(e); -->

            <!-- }); -->

            <!-- ctx.mouseup(function (e) { -->

                <!-- handleMouseUp(e); -->

            <!-- }); -->


        }




    }

    })();

    </script>

    </body>

    </html>         



查看完整回答
反对 回复 2022-01-07
  • 2 回答
  • 0 关注
  • 175 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信