使用 lineTo 和 arc 绘制线段和圆 - 填充问题

Draw segments and circles with lineTo and arc - fill issue

我尝试用 HTML5 Canvas 制作一个动画,我在其中绘制了 3 个片段的位置,每个片段用一个圆连接。

每个圆的位置由(x1,y1)、(x2,y2)和(x3,y3)决定。

这是我的代码片段:

      context.fillStyle = 'white';
      context.fillRect(0, 0, 400, 320);

      context.beginPath();
      context.moveTo(x0, y0);
      context.lineTo(x1, y1);
      context.lineTo(x2, y2);
      context.lineTo(x3, y3);
      context.strokeStyle = 'black';
      context.stroke();

      context.beginPath();
      context.arc(x1, y1, radius, 0, 2*Math.PI, true);
      context.arc(x2, y2, radius, 0, 2*Math.PI, true);
      context.arc(x3, y3, radius, 0, 2*Math.PI, true);
      context.fillStyle = 'blue';
      context.fill();

以下是这些片段的起始位置:

(x0,y0) 是顶点坐标,在动画过程中永远不会改变。

现在,经过一些迭代,我得到下图:

如您所见,我的代码填充了 3 个点 (x1,y1)、(x2,y2) 和 (x3,y3) 之间的三角形。

我不想填充这个,我只想绘制 3 个线段,每次迭代只填充 3 个圆圈。

上面的代码片段有什么问题?

感谢您的帮助

问题

arc() 只是一条路径,显然是圆形的,但有两个开放的端点。这导致它附加到先前的路径点。当发出 fill() 时,主路径关闭,导致第一个圆弧终点连接到第一个圆弧起点。

解决方案

您可以通过为圆弧创建子路径来解决它。为从角度 0 开始的每个圆弧插入一个 moveTo()(同时删除 CCW 的最后一个布尔值,以便它按顺时针方向绘制)。在我们处理子路径时调用 closePath() 将导致 sub-path 关闭末端,这对我们的情况很好,因为我们可以关闭使用 moveTo 设置的起点()恰好对应弧的起点,然后连接到弧的终点

示例

 context.beginPath();

 context.moveTo(x1 + radius, y1);  // create a new sub-path
 context.arc(x1, y1, radius, 0, 2*Math.PI);
 context.closePath();              // closes the current sub-path

 context.moveTo(x2 + radius, y2);  // create a new sub-path
 context.arc(x2, y2, radius, 0, 2*Math.PI);
 context.closePath();              // closes the current sub-path

 context.moveTo(x3 + radius, y3);  // create a new sub-path
 context.arc(x3, y3, radius, 0, 2*Math.PI);
 context.closePath();              // closes the current sub-path

 // fill all sub-paths
 context.fillStyle = 'blue';
 context.fill();  // would normally close the main path, but now we only have sub-paths