如何确定我点击了哪个方框?

时间:2018-05-04 11:14:08

标签: javascript html canvas

首先,我是javascript的新手并且仍然在学习它的基础知识,我正在尝试确定我点击了哪个框(画布)。 我的框是一个字典列表,如果我们使用console.log来显示它们,让我们调用该列表labels

[
    {"id":"1","image":"1-0.png","name":"","xMax":"4802","xMin":"4770","yMax":"156","yMin":"141"},
    {"id":"2","image":"1-0.png","name":"","xMax":"4895","xMin":"4810","yMax":"157","yMin":"141"},
    {"id":"3","image":"1-0.png","name":"","xMax":"4923","xMin":"4903","yMax":"156","yMin":"145"},
    {"id":"4","image":"1-0.png","name":"","xMax":"4956","xMin":"4931","yMax":"156","yMin":"145"}
]

在这里我们可以看到我们有4个矩形及其坐标。 我用来点击鼠标的功能是:

canvas.addEventListener("contextmenu", getPosition, false);
function getPosition(event) {
  event.preventDefault();
  var x = event.x;
  var y = event.y;

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

  x -= canvas.offsetLeft;
  y -= canvas.offsetTop;

  console.log("x:" + x + " y:" + y);
}

我正在努力的部分是找出我点击的位置是否在任何一个方框内,如果点击位于一个内部我想要id。

我尝试了什么:

我尝试在上一个代码段中的console.log之后添加此内容:

for (i = 0,i < labels.length; i++) {
                if (x>labels[i].xMin) and (x<labels[i].xMax) and (y>labels[i].yMin) and (y<labels[i].yMax) {
                    log.console(labels[i].id)
                }
            }

但它无效

3 个答案:

答案 0 :(得分:2)

标签中的rects都在右边,因此您可能需要将滚动位置添加到鼠标位置。

制作了一个工作示例(打开控制台查看结果): https://jsfiddle.net/dgw0sxu5/

<html>
    <head>
        <style>
            body{
                background: #000;
                margin: 0
            }
        </style>

        <script>
            //Some object which is used to return an id from a click
            //Added a fillStyle property for testing purposes
            var Labels = [
                {"id":"0","image":"1-0.png","name":"","xMax":"4956","xMin":"0","yMax":"50","yMin":"0","fillStyle":"pink"},
                {"id":"1","image":"1-0.png","name":"","xMax":"4802","xMin":"4770","yMax":"156","yMin":"141","fillStyle":"red"},
                {"id":"2","image":"1-0.png","name":"","xMax":"4895","xMin":"4810","yMax":"157","yMin":"141","fillStyle":"blue"},
                {"id":"3","image":"1-0.png","name":"","xMax":"4923","xMin":"4903","yMax":"156","yMin":"145","fillStyle":"limegreen"},
                {"id":"4","image":"1-0.png","name":"","xMax":"4956","xMin":"4931","yMax":"156","yMin":"145","fillStyle":"aqua"}
            ];

            //Initialisiing for the testcase
            window.onload = function(){
                //The canvas used for click events
                var tCanvas = document.body.appendChild(document.createElement('canvas'));
                tCanvas.width = 4956; //Highest xMax value from labels
                tCanvas.height = 157; //Highest yMax value from labels

                //The graphical object
                var tCTX = tCanvas.getContext('2d');

                //Drawing the background
                tCTX.fillStyle = '#fff';
                tCTX.fillRect(0, 0, tCanvas.width, tCanvas.height);

                //Drawing the rects for testing purposes
                //The rectangles are kinda far on the right side
                for(var i=0, j=Labels.length; i<j; i++){
                    tCTX.fillStyle = Labels[i].fillStyle;
                    tCTX.fillRect(+(Labels[i].xMin), +(Labels[i].yMin), +(Labels[i].xMax)-+(Labels[i].xMin), +(Labels[i].yMax)-+(Labels[i].yMin));
                };

                tCanvas.onclick = function(event){
                    var tX = event.clientX - this.offsetLeft + (document.body.scrollLeft || document.documentElement.scrollLeft), //X-Position of click in canvas
                        tY = event.clientY - this.offsetTop + (document.body.scrollTop || document.documentElement.scrollTop), //Y-Position of click in canvas
                        tR = []; //All found id at that position (can be more in theory)

                    //Finding the Labels fitting the click to their bounds
                    for(var i=0, j=Labels.length; i<j; i++){
                        if(tX >= +(Labels[i].xMin) && tX <= +(Labels[i].xMax) && tY >= +(Labels[i].yMin) && +(tY) <= +(Labels[i].yMax)){
                            tR.push(Labels[i].id)
                        }
                    };

                    console.log(
                        'Following ids found at the position @x. @y.: '
                            .replace('@x.', tX)
                            .replace('@y.', tY),
                        tR.join(', ')
                    )
                }
            }
        </script>
    </head>

    <body></body>
</html>

答案 1 :(得分:0)

首先:究竟什么不起作用?

var canvas = document.getElementById("canvas");应该在您的函数之外,以便在第二次调用时保存性能。

获取坐标并不复杂,但很复杂。

如何获得正确的资源有很好的资源:http://javascript.info/coordinates

确保相对于父元素(offsetParentoffsetLeft),左上角文档(pageX)或左上角视图(clientX )。

答案 2 :(得分:0)

您的逻辑似乎是正确的,您只需要修复语法。

for (i = 0; i < labels.length; i++) {
    if ((x>labels[i].xMin) && (x<labels[i].xMax) && (y>labels[i].yMin) && (y<labels[i].yMax)) {
        console.log(labels[i].id)
    }
}

这是一个完整的例子:

labels = [
          {"id":"1","image":"1-0.png","name":"","xMax":"4802","xMin":"4770","yMax":"156","yMin":"141"},
          {"id":"2","image":"1-0.png","name":"","xMax":"4895","xMin":"4810","yMax":"157","yMin":"141"},
          {"id":"3","image":"1-0.png","name":"","xMax":"4923","xMin":"4903","yMax":"156","yMin":"145"},
          {"id":"4","image":"1-0.png","name":"","xMax":"4956","xMin":"4931","yMax":"156","yMin":"145"}
]

var canvas = document.getElementById("canvas");
canvas.addEventListener("contextmenu", getPosition, false);
function getPosition(event) {
  event.preventDefault();

  var x = event.clientX;
  var y = event.clientY;

  var label = labels.find(function(label){
     return (x>label.xMin) && (x<label.xMax) && (y>label.yMin) && (y<label.yMax)
  });

  if(label){
     console.log("clicked label", label.id);
  }else{
     console.log("no label was clicked");
  }
}