我有一个非常简单的循环,它以平铺方式在画布上多次绘制8px×8px图像。目前它每个循环绘制7500个图像。
var img = new Image();
img.src = 'http://i.imgur.com/3dzaMlv.png';
var W = 8;
var H = 8;
var R = 800/W;
var C = 600/H
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var fps = document.getElementById('fps');
var timePrev = new Date().getTime();
var fpsInterval = 30;
var i = 0;
window.setInterval(function() {
ctx.clearRect(0, 0, 800, 600);
for (var r=0 ; r<R ; r++) {
for (var c=0 ; c<C ; c++) {
ctx.drawImage(img, r*W, c*H);
}
}
// fps
if (i % fpsInterval == 0) {
var timeNow = new Date().getTime();
var spf = (timeNow - timePrev) / fpsInterval / 1000;
fps.innerHTML = (1/spf).toFixed(2);
timePrev = timeNow;
}
i++;
}, 1000/60);
在我的I7-2700K(3.5GHz)处理器和ATI Radeon HD7970上,我得到以下帧速率:
有没有办法在这里提高FPS性能,假设我确实需要在每次更新时绘制这么多的瓷砖?
编辑:为了澄清,我要求在每次更新时将它们绘制为单独的图块。因此,将它们全部渲染到屏幕外的画布是行不通的。我基本上对看似表现良好的drawImage()调用的数量感到失望。
答案 0 :(得分:0)
使用requestAnimationFrame
代替setInterval
,请参阅http://www.w3.org/TR/animation-timing/。您的代码可能会被重写为:http://jsfiddle.net/fv99o6jc/
答案 1 :(得分:0)
这是使用更少的drawImage的一种方法:
// make a template column
for(var y=0;y<ch;y+=ih){
ctx.drawImage(img,0,y);
}
// flood-fill with the template column
for(var x=iw;x<cw;x+=iw){
ctx.drawImage(canvas,0,0,iw,ch,x,0,iw,ch);
}
演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var img=new Image();
img.onload=start;
img.src="http://i.imgur.com/3dzaMlv.png";
function start(){
var iw=img.width;
var ih=img.height;
// make a template column
for(var y=0;y<ch;y+=ih){
ctx.drawImage(img,0,y);
}
// flood-fill with the template column
for(var x=iw;x<cw;x+=iw){
ctx.drawImage(canvas,0,0,iw,ch,x,0,iw,ch);
}
}
&#13;
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
&#13;
<canvas id="canvas" width=300 height=300></canvas>
&#13;