附加到画布内对象的事件

时间:2015-06-23 21:44:41

标签: javascript canvas javascript-events html5-canvas

我只有在画布上绘制rect的画布代码

var x=document.getElementById("canvas");
var ctx=x.getContext("2d");
ctx.rect(20,20,150,100);
ctx.stroke();

可以在所说的rect上添加eventListener吗?例如,如果我点击rect,它将变为红色。

3 个答案:

答案 0 :(得分:8)

地区

根据您希望支持各种旧版浏览器的效果,addHitRegion()可以通过Firefox和Chrome中的标记启用它(在编写本文时):

  

Firefox:about:config - >搜索" hitregions"并设为真实   Chrome:chrome:// flags / - >启用实验性画布功能

这是将直接与事件系统集成的唯一技术。我不会推荐它用于生产,AFAIK也没有它的填充 - 但是为了表明它是多么容易使用:



var x=document.getElementById("canvas");
var ctx=x.getContext("2d");
ctx.rect(20,20,150,100);
ctx.addHitRegion({id: "demo"});   // enable in flags in Chrome/Firefox
ctx.stroke();

x.addEventListener("click", function(e) {
  if (e.region && e.region === "demo") alert("Hit!");
})

<canvas id="canvas"></canvas>
&#13;
&#13;
&#13;

路径:isPointInPath

其他技术需要人工手动实现命中检测机制。一个是使用isPointInPath()。您只需逐个重建要测试的路径,然后针对它运行(调整的)x / y鼠标坐标:

&#13;
&#13;
var x=document.getElementById("canvas");
var ctx=x.getContext("2d");
generatePath();
ctx.stroke();

x.addEventListener("click", function(e) {
  var r = this.getBoundingClientRect(),
      x = e.clientX - r.left,
      y = e.clientY - r.top;
  
  // normally you would loop through your paths:
  generatePath();
  if (ctx.isPointInPath(x, y)) alert("Hit!");
})

function generatePath() {
  ctx.beginPath();          // reset path
  ctx.rect(20,20,150,100);  // add region to draw/test
}
&#13;
<canvas id="canvas"></canvas>
&#13;
&#13;
&#13;

路径:Path2D对象

对于后一个示例,还有新的Path2D对象可以自己保存路径 - 这里的优点是您不需要重建路径,只需传入路径对象使用x / y到isPointInPath()方法。

问题是Path2D是not supported in all browsers yet,但是有polyfill可以解决这个问题,

&#13;
&#13;
var x=document.getElementById("canvas");
var ctx=x.getContext("2d");

var path1 = new Path2D();
path1.rect(20,20,150,100);  // add rect to path object

ctx.stroke(path1);

x.addEventListener("click", function(e) {
  var r = this.getBoundingClientRect(),
      x = e.clientX - r.left,
      y = e.clientY - r.top;
  
  // normally you would loop through your paths objects:
  if (ctx.isPointInPath(path1, x, y)) alert("Hit!");
})
&#13;
<canvas id="canvas"></canvas>
&#13;
&#13;
&#13;

手动检查边界

当然,还有使用手动边界检查的旧技术。这适用于所有浏览器。这里可取的做法是创建包含边界的对象,也可以用来渲染它。这通常会限制您使用矩形区域 - 更复杂的形状将需要更复杂的算法(例如isPointInPath()嵌入)。

&#13;
&#13;
var x=document.getElementById("canvas");
var ctx=x.getContext("2d");
ctx.rect(20,20,150,100);
ctx.stroke();

x.addEventListener("click", function(e) {
  var r = this.getBoundingClientRect(),
      x = e.clientX - r.left,
      y = e.clientY - r.top;
  
  // normally you would loop through your region objects:
  if (x >= 20 && x < 20+150 && y >= 20 && y < 20+100) alert("Hit!");
})
&#13;
<canvas id="canvas"></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

形状和路径作为副作用绘制到画布,因此没有要添加事件侦听器的元素;但是,您可以向整个画布或与画布共享位置的元素添加事件侦听器,并在单击它时使用矩形重绘画布,但是红色(或其他任何更改)。 (确保在使用.clearRect()方法重绘之前清除画布)。

答案 2 :(得分:0)

如果您在画布上绘制某些内容,则绘制的形状不是javascript对象,而是更改画布所在的特定状态。因此,您无法将事件侦听器附加到它,而应该附加事件到画布本身。

然后你的javascript可以检查点击的坐标,并找出它是否在矩形内。请记住,如果您在矩形或形状的顶部绘制某些内容,则必须调整代码以检查所形成的新区域。如果它不是一个矩形,你可能也会发现很难检查该区域,但它仍然是可能的。

如果要将矩形重绘为红色,则应重新绘制画布,更改重绘的新矩形的颜色(矩形不是对象,因此无法直接更改颜色)。这还需要重新绘制画布上的所有其他形状。