首页 > 解决方案 > 在重新绘制画布时单击事件侦听器

问题描述

我正在构建一个使用画布(大约 6FPS)动态呈现的 javascript 游戏,我希望在其中支持单击画布中的各种对象以选择它们。

作为一个最小的例子,我有一个圆圈在屏幕上移动的代码示例,同时为圆圈绑定了一个单击事件侦听器并取消绑定以前的单击事件侦听器(对于清除画布后不再存在的路径)。

https://jsfiddle.net/gbvj67ro/7/

HTML

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

JS

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

function drawCircle(path2d, x, y, radius, fill) {
        ctx.beginPath();
        path2d.arc(x, y, radius, 0, 2*Math.PI);
        fill?ctx.fill(path2d):ctx.stroke(path2d);
        ctx.closePath();
    }

let eventListener = null
let i = 0

setInterval(function(){ 
  ctx.clearRect(0, 0, 1000, 200)
  
  // remove the existing event listener
  if (eventListener !== null) {
    canvas.removeEventListener("click", eventListener)
  }
  
  // new path
  let p1 = new Path2D();
    ctx.fillStyle = 'blue';
    drawCircle(p1, 20 + i, 20, 10, true)
    
  // new event listener function for current path
  eventListener = function(e) {
    if (ctx.isPointInPath(p1, e.offsetX, e.offsetY)) {
      console.log("clicked p1 i=" + i);
    }
  }
  
  // bind new event listener
  canvas.addEventListener("click", eventListener)    

  i += 5
  ctx.restore()
}, 1000);

这是实现这一点的最佳方法吗?作为替代方案,我可以绑定一个事件侦听器来查询对象的当前位置以及它们是否与单击位置相交。但这需要我重新复制场景绘制逻辑。

标签: javascripthtml5-canvasaddeventlistener

解决方案


推荐阅读