Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
鼠标单击javascript画布上的对象数组_Javascript_Jquery_Canvas_Mouseevent_Mouseover - Fatal编程技术网

鼠标单击javascript画布上的对象数组

鼠标单击javascript画布上的对象数组,javascript,jquery,canvas,mouseevent,mouseover,Javascript,Jquery,Canvas,Mouseevent,Mouseover,我有一个数组,其中充满了我游戏中许多不同对象的位置,我试图实现的是,当鼠标位于画布中的对象上时,用户可以单击,然后出现一个框(将是一个菜单) 以下是我已经掌握的代码: this.init_inv = function(value){ canvas.onmousemove = function (e) { var x, y; for(var i = 0;i < value.length; i++){ // Get the mo

我有一个数组,其中充满了我游戏中许多不同对象的位置,我试图实现的是,当鼠标位于画布中的对象上时,用户可以单击,然后出现一个框(将是一个菜单)

以下是我已经掌握的代码:

 this.init_inv = function(value){
    canvas.onmousemove = function (e) {
        var x, y;
        for(var i = 0;i < value.length; i++){
            // Get the mouse position relative to the canvas element.
            if (e.layerX || e.layerX) { //for firefox
                x = e.layerX;
                y = e.layerY;
            }
            x-=canvas.offsetLeft;
            y-=canvas.offsetTop;

            if(x>=value[i][0] && x <= (value[i][0] + value[i][2]) &&
               y<=value[i][1]&& y >= (value[i][1]-value[i][2])){
                document.body.style.cursor = "pointer";
                inObject=true;
            }
            else{
                document.body.style.cursor = "";
                inObject=false;
            }
        }
    };
    canvas.addEventListener("click", on_click, false);
};
我有一个单独的点击处理程序,因为我需要处理不同画布不同部分的点击

我相信问题在于如何读取数组中的值,但不确定如何读取。我知道这一点,因为如果我在
值[I][0]
etc值所在的位置输入一个int,我可以在指定的区域中单击,然后单击触发,我就会得到控制台日志

该数组如下所示:

function on_click(e) {
    if (inLink)  {
        var dataString = {"save": "true", "level":level, "location_X":pos_X, "location_Y":pos_Y};
        $.ajax({
            type:"POST",
            url:"PHP/class.ajax.php",
            data: dataString,
            dataType: "JSON",
            success: function(success){
                alert("Saved");
            },
            error:function(){
                alert("Not Saved");
            }
        });
    }
    if(inObject){
        console.log("hovering");
    }
}
var array = [
   [pos_x,pox_y, size]
   //etc...
];

因此,您可以先将其设置为false,然后再将其设置为
i
,这样就可以知道实际选择了哪个对象,而不是将
inoobject
设置为true或false

确保inObject是在函数外部定义的,以便以后可以访问它

我将稍微解释一下您的代码,简要概述一下我将如何构造此代码

//first of all, name your stuff what it is, rather than array, name it meaningfully
// and since we don't have a huge amount(1000+) of menu items, we can just use them as objects
// arrays are faster, but for clarity purposes, we don't need the speed and might as well have readable code
var menuboxes = [
  {x: 10, y: 10, size: 100},
  {x: 115, y: 10, size: 100}
];

//i suggest using underscore, but this could be converted to a regular each
_.each(menuboxes, function(box, n){
  context.fillRect(box.x, box.y, box.size, box.size);
});

var on_click = function(e){
  // this doesn't change for each item, so define x and y outside of the boxes loop
  x = e.layerX - canvas.offsetLeft;
  y = e.layerY - canvas.offsetTop;
  clickTarget = false
  _.each(menuboxes, function(box, n){
    if(box.x < x && x < box.x + box.size &&
      // no need to invert y, use it like you use x
      box.y < y && y < box.y + box.size) {
        clickTarget = n;
      }
  });
  if(clickTarget !== false){
    openMenu(clickTarget);
  }
};

var openMenu = function(n){
  console.log("You opened box", n, menuboxes[n]);
  // menu opening code here
}

canvas.addEventListener("click", on_click, false);
//首先,给你的东西命名,而不是数组,给它命名要有意义
//由于我们没有大量(1000+个)菜单项,我们可以将它们作为对象使用
//数组的速度更快,但为了清晰起见,我们不需要速度,最好有可读的代码
变量菜单框=[
{x:10,y:10,大小:100},
{x:115,y:10,大小:100}
];
//我建议使用下划线,但可以将其转换为常规的下划线
_.每个(菜单框,函数(框,n){
context.fillRect(box.x,box.y,box.size,box.size);
});
单击时的变量=函数(e){
//这对于每个项目都不会改变,所以在循环框外部定义x和y
x=e.layerX-canvas.offsetLeft;
y=e.layerY-canvas.offsetTop;
clickTarget=false
_.每个(菜单框,函数(框,n){
如果(box.x

这是未经测试,但应该给你一些提示。我建议现在使用jquery和下划线,最后在学习诀窍时使用coffeescript。由于浏览器的特殊性,Jquery非常重要,下划线非常有用且快速,在某些情况下,coffeescript是生成可读代码的唯一方法。将代码复制到中,看看它可以短多少。

通常,您可以通过在画布上移动元素并直接将单击处理程序附加到元素上来处理此问题,而不是通过在数组中查找来跟踪鼠标移动和推断单击的位置;您不只是利用此内置功能有什么原因吗?如果您想对画布中特定项目上的事件做出反应,您可能需要查看类似库的内容来帮助您@ChrisMoschini Canvas本机不允许您将事件处理程序附加到Canvas元素,因为所有内容都是光栅化的,并且向量不会保留。如何定义画布的不同部分?我能想到的唯一方法是1个鼠标侦听器,根据位置有2个不同的ifs。1D示例:如果(x