Ser*_*nos 10 javascript algorithm performance canvas
我正在渲染一个单元格网格,非常类似于填字游戏中的网格,但使用四种不同的颜色来填充每个单元格(不仅是黑色或白色).
网格大小约为160x120,我需要尽可能快地渲染它,因为它将用于显示细胞自动机动画.
我尝试了两种不同的方法来渲染网格:
使用以下内容渲染每个单元格:
var w = x + step;
var h = y + step;
canvasContext.fillStyle=cell.color;
canvasContext.fillRect(x+1,y+1,w-1,h-1);
canvasContext.strokeRect(x,y,w,h);
Run Code Online (Sandbox Code Playgroud)渲染没有边框的所有单元格,然后使用以下方法渲染网格线:
var XSteps = Math.floor(width/step);
canvasContext.fillStyle = gridColor;
for (var i = 0, len=XSteps; i<len; i++) {
canvasContext.fillRect(i*step, 0, 1, height);
}
//Similar thing for Y coord
Run Code Online (Sandbox Code Playgroud)两种算法都表现不佳:在两种情况下绘制网格都比单元格慢.我错过了什么吗?我该如何优化这些算法?还有其他方法我应该尝试吗?
注意:网格会移动,因为用户可以移动它或缩放视图.
一般的问题是:在元素上绘制单元格网格的最快算法是什么?
做某事的最快方法是根本不做.
在一个画布上绘制一次不变的网格,并在另一个分层上方(或下方)的画布上绘制(并清除和重绘)细胞自动机.让浏览器(在其所有本机编译优化的荣耀中)为您处理弄脏,重绘和合成.
或者(更好)如果你不打算改变你的网格大小,只需创建一个小图像,让CSS填充它作为背景.
基于这个优秀的演示,这里是一个完全通过CSS创建的背景图像网格; 使用此功能,您可以根据需要更改大小(以整像素为增量).
如果必须绘制网格,最快的方法是绘制线条:
function drawGrid(ctx,size){
var w = ctx.canvas.width,
h = ctx.canvas.height;
ctx.beginPath();
for (var x=0;x<=w;x+=size){
ctx.moveTo(x-0.5,0); // 0.5 offset so that 1px lines are crisp
ctx.lineTo(x-0.5,h);
}
for (var y=0;y<=h;y+=size){
ctx.moveTo(0,y-0.5);
ctx.lineTo(w,y-0.5);
}
ctx.stroke(); // Only do this once, not inside the loops
}
Run Code Online (Sandbox Code Playgroud)
对于m行和n列,这需要在单个通道中进行m + n个线条绘制.与此相比,绘制m × n个别行为,您可以看到性能差异非常显着.
例如,fillRect()在天真的情况下,512×512网格的8×8小区将需要4,096个呼叫,但是使用上面的代码在单个 stroke()呼叫中只需要抚摸128个线路.