在HTML5 Canvas上绘制多个圆圈的问题

时间:2014-05-15 02:55:18

标签: javascript jquery html5 html5-canvas

您能否请一个look at this演示,让我知道如何在不同坐标的画布中绘制多个圆圈而不重复一串代码?

正如你在Demo和代码中看到的那样

var ctx = $('#canvas')[0].getContext("2d");
ctx.fillStyle = "#00A308";
ctx.beginPath();
ctx.arc(150, 50, 5, 0, Math.PI * 2, true);
ctx.arc(20, 85, 5, 0, Math.PI * 2, true);
ctx.arc(160, 95, 5, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();

我试图将它们放在ctx下,但它不正确,所以我尝试使用for循环来创建50个点,但我有重复和添加代码的问题,如ctx.fill();对于他们所有人。 能告诉我如何解决这个问题吗?

由于

5 个答案:

答案 0 :(得分:8)

这是因为您没有关闭路径,使用fill()closePath()将关闭路径,因此它不会尝试连接所有项目。 fill()填写圈子并关闭路径,以便我们可以使用它。您还需要使用beginPath(),以便它们彼此分开。这是你的三个圈子:

var coords = [ [150,50], [20,85], [160,95] ];

for(var i = 0; i < coords.length; i++){
    ctx.beginPath();
    ctx.arc(coords[i][0], coords[i][1], 5, 0, Math.PI * 2, true);
    ctx.fill();
}

要不重复大量代码并使用唯一坐标将XY位置存储在数组中,并使用for循环来完成它。

<强>更新

一种更有效的方法,可以实现相同的效果,即只使用单个路径并使用moveTo()而不是在绘制每个圆时创建新路径:

ctx.beginPath();
for(var i = 0; i < coords.length; i++){
    ctx.moveTo(coords[i][0], coords[i][1]);
    ctx.arc(coords[i][0], coords[i][1], 5, 0, Math.PI * 2, true);
}
ctx.fill();

答案 1 :(得分:8)

不断创建和关闭新路径并不是一个好建议。

您应该将所有相同样式的填充/描边一起批处理,并在一次绘制调用中执行它们。随着多边形数量的增加,这些方法之间的性能差异变得非常明显。

解决这个问题的方法是移动笔并为每个圆圈进行路径构建调用;中风/一次填写最后一次。但是,这里有一个怪癖。当您将点移动到中心并绘制圆时,您仍然会看到从圆心到圆周绘制的水平半径线

为了避免这种假象,我们移动到圆周,而不是移动到中心。这会跳过半径绘图。基本上所有这些命令都用于跟踪路径,没有调用closePath就无法描述不连续性;通常moveTo可以做到但HTML5 canvas API却没有。这是一个简单的解决方法来解决这个问题。

const pi2 = Math.PI * 2;
const radius = 5;
ctx.fillStyle = '#00a308';
ctx.beginPath();

for( let i=0, l=coords.length; i < l; i++ )
{
    const p = coords[i],
    x = p.x,
    y = p.y;

    ctx.moveTo( x + radius, y ); // This was the line you were looking for
    ctx.arc( x, y, radius, 0, pi2 );
}

// Finally, draw outside loop
ctx.stroke();
ctx.fill();

另外值得考虑的是,使用转换,并绘制相对于本地参照系的所有内容。

ctx.fillStyle = '#00a308';
ctx.beginPath();

for( let i=0, l=coords.length; i < l; i++ )
{
    const p = coords[i];

    ctx.save();
        ctx.translate( p.x + radius, p.y );
        ctx.moveTo( 0, 0 );
        ctx.arc( 0, 0, radius, 0, pi2 );
    ctx.restore();
}

ctx.stroke();
ctx.fill();

答案 2 :(得分:1)

  ctx.beginPath();
  points.forEach(point => {
    ctx.moveTo( point.x, point.y );
    ctx.arc(point.x,point.y,1,0,Math.PI*2,false);
  });
  ctx.fill();

答案 3 :(得分:0)

您可以使用for循环轻松创建多个圆圈。你真的只需要绘制一个圆弧并每次填充它。使用你的例子,你可以做这样的事情。

var ctx = $('#canvas')[0].getContext("2d");
ctx.fillStyle = "#00A308";
for (var i = 0; i < 3; i++) {
  ctx.arc(50 * (i+1), 50 + 15 * i, 5, 0, Math.PI * 2, true);
  ctx.fill();
}

答案 4 :(得分:0)

Example Fiddle在循环中绘制的不同位置的许多圆圈。

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext( '2d' );
var cx = canvas.width/2;
var cy = canvas.height/2;
ctx.fillStyle = "#00A308";

var total_circles = 50;
var radius = 100;
for(i = 0; i < total_circles; i++){
    var angle = i * 2 * Math.PI/total_circles;
    var x = cx + Math.cos(angle) * radius;
    var y = cy + Math.sin(angle) * radius;   
    ctx.beginPath();
    ctx.arc(x, y, 2, 0, Math.PI * 2, true);
    ctx.closePath();
    ctx.fill();
}