Suf*_*fii 13 javascript jquery html5 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();
Run Code Online (Sandbox Code Playgroud)
我尝试将它们放在下面,ctx但它不正确,所以我尝试使用for循环创建50个点,但我有重复和添加代码的问题,如ctx.fill(); 对于他们所有人.你能告诉我怎么解决这个问题吗?
谢谢
Spe*_*rek 10
这是因为您没有关闭路径,使用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();
}
Run Code Online (Sandbox Code Playgroud)
为了不重复一串代码,并具有独特的坐标存储您X和Y位置在数组中,并使用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();
Run Code Online (Sandbox Code Playgroud)
不断创建和关闭新路径并不是一个好建议.
您应该将所有相同样式的填充/笔划一起批处理,并在一次绘制调用中执行它们.随着多边形数量的增加,这些方法之间的性能差异变得非常明显.
解决这个问题的方法是移动笔并为每个圆圈进行路径构建调用; 中风/一次性填充.但是,这里有一个怪癖.当您将点移动到中心并绘制圆时,您仍然会看到从圆的中心绘制到圆周的水平半径线.
为了避免这种假象,我们移动到圆周,而不是移动到中心.这会跳过半径绘图.基本上所有这些命令都用于跟踪路径,没有办法在没有调用的情况下描述不连续性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();
Run Code Online (Sandbox Code Playgroud)
另外值得考虑的是,使用转换,并绘制相对于本地参照系的所有内容.
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();
Run Code Online (Sandbox Code Playgroud)