Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JavaScript画布API中设置允许的绘图区域_Javascript_Vue.js_Canvas - Fatal编程技术网

在JavaScript画布API中设置允许的绘图区域

在JavaScript画布API中设置允许的绘图区域,javascript,vue.js,canvas,Javascript,Vue.js,Canvas,我正在使用JavaScript画布API进行免费绘图。我一直在掩盖允许绘制的区域——在我的示例中,它应该只是speechbubble区域。 我正在使用此Vue组件: 在计算机科学中,确定一个给定的点是否属于多边形区域是一个相当棘手的问题 在这个具体场景中,您可以将上面图像设置为背景的画布和500x300维的画布,您实际上不需要使用光线投射算法。 例如,您可以将语音气泡区域划分为矩形和三角形,然后使用event.offsetX,event.offsetY检查是否有任何给定点位于这两个图形中的任何一

我正在使用JavaScript画布API进行免费绘图。我一直在掩盖允许绘制的区域——在我的示例中,它应该只是speechbubble区域。 我正在使用此Vue组件:


在计算机科学中,确定一个给定的点是否属于多边形区域是一个相当棘手的问题

在这个具体场景中,您可以将上面图像设置为背景的画布和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;
     ...