附加到画布内对象的事件 [英] Events attached to object inside canvas

查看:112
本文介绍了附加到画布内对象的事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have simply canvas code which draw rect on the canvas

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

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

is it possible to add eventListener on said rect? For example , if i click on rect , it will turn red.

推荐答案

区域



根据您希望支持各种旧版浏览器的程度,可以通过Firefox和Chrome中的标记启用 addHitRegion()。在写这篇文章的那一刻):

Regions

Depending on how well you want to support various and older browsers, there is addHitRegion() that you can use by enabling it through flags in Firefox and Chrome (at the moment of this being written):


Firefox:about:config - >搜索hitregions并设置为true

Chrome:chrome:// flags / - >启用实验性画布功能

Firefox: about:config -> search "hitregions" and set to true
Chrome: chrome://flags/ -> Enable experimental canvas features

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

This is the only technique that integrates directly with the event system. I would not recommend it for production quite yet though, and AFAIK there is not a polyfill for it either - but to show how easy it is to use:

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>

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

The other techniques require one to manually implement a mechanism for hit-detection. One is by using isPointInPath(). You simply rebuild the paths you want to test, one by one, then run your (adjusted) x/y mouse coordinate against it:

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
}

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

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

For the latter example there is also the new Path2D objects which can hold a path on their own - the advantage here is that you don't need to rebuild the paths, just pass in the path object with x/y to the isPointInPath() method.

问题是Path2D是目前还不支持所有浏览器,但有 polyfill 将为您解决这个问题,

The problem is that Path2D is not supported in all browsers yet, but there is this polyfill that will fix that for you,

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!");
})

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

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

And of course, there is the old technique of using manual boundary checks. This will work in all browsers. Here the advisable thing to do is to create objects that holds the bounds and can also be used to render it. This typically limits you to rectangular areas - more complex shapes will require more complex algorithms (such as the isPointInPath() embeds).

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!");
})

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

这篇关于附加到画布内对象的事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆