繁体   English   中英

附加到画布内对象的事件

[英]Events attached to object inside canvas

我只有画布代码,可以在画布上绘制矩形

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

是否可以在上述矩形上添加eventListener? 例如,如果我单击rect,它将变成红色。

地区

根据您对各种和较旧的浏览器的支持addHitRegion() ,可以通过在Firefox和Chrome中通过标志启用它来使用addHitRegion() (在撰写本文时):

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

这是唯一与事件系统直接集成的技术。 我现在还不建议将其用于生产,并且AFAIK也没有它的polyfill-而是要展示它的易用性:

 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

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

 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对象

对于后一个示例,还有新的Path2D对象可以单独保存路径-这样做的好处是您无需重建路径,只需将带有x / y的路径对象传递给isPointInPath()方法。

问题在于, 尚不是所有浏览器都支持 Path2D,但是此polyfill可以为您解决该问题,

 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()嵌入)。

 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> 

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

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

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

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

暂无
暂无

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

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