在JavaScript画布API中设置允许的绘图区域
我正在使用JavaScript画布API进行免费绘图。我一直在掩盖允许绘制的区域——在我的示例中,它应该只是speechbubble区域。 我正在使用此Vue组件:在JavaScript画布API中设置允许的绘图区域,javascript,vue.js,canvas,Javascript,Vue.js,Canvas,我正在使用JavaScript画布API进行免费绘图。我一直在掩盖允许绘制的区域——在我的示例中,它应该只是speechbubble区域。 我正在使用此Vue组件: 在计算机科学中,确定一个给定的点是否属于多边形区域是一个相当棘手的问题 在这个具体场景中,您可以将上面图像设置为背景的画布和500x300维的画布,您实际上不需要使用光线投射算法。 例如,您可以将语音气泡区域划分为矩形和三角形,然后使用event.offsetX,event.offsetY检查是否有任何给定点位于这两个图形中的任何一
在计算机科学中,确定一个给定的点是否属于多边形区域是一个相当棘手的问题 在这个具体场景中,您可以将上面图像设置为背景的画布和500x300维的画布,您实际上不需要使用光线投射算法。
例如,您可以将语音气泡区域划分为矩形和三角形,然后使用
event.offsetX,event.offsetY
检查是否有任何给定点位于这两个图形中的任何一个图形内
代码示例:
isPointInArea(event) {
const x = event.offsetX;
const y = event.offsetY;
// For rectangle it is straightforward
if (x >= 60 && x <= 325 && y >= 60 && y <= 215) {
return true;
}
/* Since two sides of this triangle are parallel to canvas
It is enough to check y coordinate with one linear function of a third one
in form of y = ax + b */
if(x >= 60 && x <= 120 && y >= 215) {
const boundaryY = -0.81818181818 * x + 313.181818182;
if (y <= boundaryY) {
return true;
}
}
return false;
}
结果:
编辑:
正如您所指出的,您还可以简单地使用Canvas API的clip()
方法。如果没有其他要渲染的内容(因为它不是游戏,所以可能是这样),则只需执行一次clip(),即可完成所有设置。否则请记住使用方法(当然还有,这样您也可以在语音气泡剪辑区域之外渲染内容)。有一种内置方法,将路径设置为剪辑区域
var ctx=document.getElementById(“cnv”).getContext(“2d”);
ctx.线宽=2;
ctx.strokeStyle=“红色”;
ctx.moveTo(0,0);
ctx.lineTo(100100);
stroke();//1。
ctx.strokeStyle=“黑色”;
ctx.beginPath();
ctx.moveTo(10,10);
ctx.lineTo(100,10);
ctx.lineTo(100,60);
ctx.lineTo(30,60);
ctx.lineTo(10,80);
ctx.closePath();
stroke();//2。
ctx.clip();//3。
ctx.strokeStyle=“绿色”;
ctx.beginPath();
ctx.moveTo(0100);
ctx.lineTo(100,0);
ctx.stroke();//4.
你不能对照气泡的边界检查event.offsetX,event.offsetY
吗?不管怎样,如果你提供了一个可运行的代码段,你就更有可能得到一个好的答案。@avejidah如前所述,我正在使用这个Vue组件:如果你能用预期的结果和可复制的代码更好地描述你的问题,我们可能会有帮助您在画布中只渲染一个图像吗?(粉色背景和语音气泡)或者它们是单独的对象吗?谢谢您的回答。您认为哪一个可以提供更好的性能-clip()或您的“isPointInArea”?不客气:)在您的例子中,只要我测量了这两种解决方案的性能,就可以调用clip,clip()的性能稍好一些。(我使用了浏览器的performance.measure())
isPointInArea(event) {
const x = event.offsetX;
const y = event.offsetY;
// For rectangle it is straightforward
if (x >= 60 && x <= 325 && y >= 60 && y <= 215) {
return true;
}
/* Since two sides of this triangle are parallel to canvas
It is enough to check y coordinate with one linear function of a third one
in form of y = ax + b */
if(x >= 60 && x <= 120 && y >= 215) {
const boundaryY = -0.81818181818 * x + 313.181818182;
if (y <= boundaryY) {
return true;
}
}
return false;
}
draw(event) {
if(!this.isPointInArea(event)) {
return;
}
this.drawCursor(event);
if (!this.isDrawing) return;
...