简体   繁体   English

通过click事件识别画布上的对象

[英]identify an object on canvas by a click event

Into this simple code I use an eventListener which doesn't look to work at all. 在这个简单的代码中,我使用了一个eventListener,它看起来根本不起作用。 The canvas display an image and the given hitpaint() function is supposed determines whether a click occurs. 画布显示图像,并且假定给定的hitpaint()函数确定是否发生单击。 I cant understand why the eventListener behaves like that. 我不明白为什么eventListener会那样表现。 Any insight would be helpful. 任何见解都会有所帮助。

mycanv.addEventListener("click", function(e) {
    var output = document.getElementByID("output");
    ctx.fillStyle = 'blue';
    //ctx.clearRect(0,0,100,20);

    if (hitpaint) {
        //ctx.fillText("hit",100,20);                                                                                                                                                                                                           
        output.innerHTML = "hit";
    } else {
        //ctx.fillText("miss",100,20);                                                                                                                                                                                                          
        output.innerHTML = "miss";
    }
}, false);

The hitpaint() function is defined as: hitpaint()函数定义为:

function hitpaint(mouse_event) {
    var bounding_box = mycanv.getBoundingClientRect();
    var mousex = (mouse_event.clientX - bounding_box.left) *
        (mycanv.width / bounding_box.width);
    var mousey = (mouse_event.clientY - bounding_box.top) *
        (mycanv.height / bounding_box.height);
    var pixels = ctx.getImageData(mousex, mousey, 1, 1);

    for (var i = 3; i < pixels.data.length; i += 4) {
        // If we find a non-zero alpha we can just stop and return                                                                                                                                                                            
        // "true" - the click was on a part of the canvas that's                                                                                                                                                                              
        // got colour on it.                                                                                                                                                                                                                  
        if (pixels.data[i] !== 0) return true;
    }

    // The function will only get here if none of the pixels matched in                                                                                                                                                                   
    return false;
}

Finally, the main loop which display the picture in random location into the canvas: 最后,主循环将图片随机显示在画布中:

function start() {
    // main game function, called on page load                                                                                                                                                                                            
    setInterval(function() {
        ctx.clearRect(cat_x, cat_y, 100, 100);
        cat_x = Math.random() * mycanv.width - 20;
        cat_y = Math.random() * mycanv.height - 20;
        draw_katy(cat_x, cat_y);
    }, 1000);
}

There are a some issues here: 这里有一些问题:

  • As Grundy points out in the comment, the hitpaint is never called; 正如格伦迪(Grundy)在评论中指出的那样,从来没有调用hitpaint。 right now it checks for it's existence and will always return true 现在它会检查它的存在,并将始终返回true
  • The mouse coordinates risk ending up as fractional values which is no-go with getImageData 鼠标将风险协调为最终的分数值,这对于getImageData是不可行的
  • Scaling the mouse coordinates is usually not necessary. 通常不需要缩放鼠标坐标。 Canvas should preferably have a fixed size without an additional CSS size 画布最好具有固定的大小,而无需额外的CSS大小
  • Add boundary check for x/y to make sure they are inside canvas bitmap 添加x / y的边界检查以确保它们在画布位图中

I would suggest this rewrite: 我建议重写一下:

mycanv.addEventListener("click", function(e) {
    var output = document.getElementByID("output");
    ctx.fillStyle = 'blue';
    //ctx.clearRect(0,0,100,20);

    if (hitpaint(e)) {  // here, call hitpaint()
         //ctx.fillText("hit",100,20);                                                                                                                                                                                                           
        output.innerHTML = "hit";
    } else {
        //ctx.fillText("miss",100,20);                                                                                                                                                                                                          
        output.innerHTML = "miss";
    }
}, false);

Then in hitpaint: 然后在hitpaint中:

function hitpaint(mouse_event) {

  var bounding_box = mycanv.getBoundingClientRect();

  var x = ((mouse_event.clientX - bounding_box.left) *
    (mycanv.width / bounding_box.width))|0;  // |0 cuts off any fraction
  var y = ((mouse_event.clientY - bounding_box.top) *
    (mycanv.height / bounding_box.height))|0;

  if (x >= 0 && x < mycanv.width && y >= 0 && y < mycanv.height) {
      // as we only have one pixel, we can address alpha channel directly
      return ctx.getImageData(x, y, 1, 1).data[3] !== 0;
  }
  else return false;  // x/y out of range
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM