我有简单的 Canvas 代码,可以在 Canvas 上绘制矩形
var x=document.getElementById("canvas");
var ctx=x.getContext("2d");
ctx.rect(20,20,150,100);
ctx.stroke();
是否可以在所述矩形上添加 eventListener?例如,如果我点击矩形,它会变成红色。
最佳答案
地区
根据您希望支持各种旧浏览器的程度,您可以通过 Firefox 和 Chrome 中的标志启用它来使用 addHitRegion()
(在撰写本文时) :
Firefox: about:config -> search "hitregions" and set to true
Chrome: chrome://flags/ -> Enable experimental canvas features
这是唯一直接与事件系统集成的技术。不过,我还不建议将它用于生产环境,而且 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 是 not supported in all browsers yet , 但有这个 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>
关于javascript - 附加到 Canvas 内对象的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31014083/