繁体   English   中英

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

[英]Issue on Drawing Multiple Circles on HTML5 Canvas

你能不能看一下这个演示,让我知道如何在不同坐标的画布上绘制多个圆圈,而不重复一堆代码?

正如你在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(); 对于他们所有人。 你能告诉我怎么解决这个问题吗?

谢谢

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

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

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

为了避免这种假象,我们移动到圆周,而不是移动到中心。 这会跳过半径绘图。 基本上所有这些命令都用于跟踪路径,没有调用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();

这是因为您没有关闭路径,使用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();
  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();

您可以使用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();
}

示例在循环中绘制的不同位置中的许多圆圈的小提琴

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();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM