我正在创建一个“气泡生成器”作为将在页面上运行的背景效果。生成器工作正常,但在一段时间后它会变慢, 很多 。
我将演示设置为以1毫秒的间隔运行,因此当您重新启动小提琴时很容易看到减速(特别是如果您使结果窗口变大)。
问题是我有几千次调用此代码(每个泡泡一次):
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x+1, y+1);
ctx.stroke();
有没有人知道在画布上绘制一个像素的更快方法?
另外,如果有人想要让气泡更加真实,我不会抱怨:)
答案 0 :(得分:3)
不是一个一个地绘制气泡,而是一次性绘制?即将ctx.beginPath()
和ctx.stroke()
移出循环?它在Firefox上看起来要快得多。 :)
$.extend(Number.prototype, {
times : function(cb){ for(var i=0; i<this; i++){ cb(i); }},
interval : function(cb){ return setInterval(cb, this); },
timeout : function(cb){ return setTimeout(cb, this); }
});
$(function(){
var $canvas = $('<canvas></canvas>'),
ctx = $canvas[0].getContext('2d'),
$cont = $('#fish-bubbles'),
generators = [],
bubbles = [],
w, h;
$cont.append($canvas);
$(window).bind('resize', onResize);
onResize();
5..times(createBubbleGenerator);
1..interval(drawBubbles);
function drawBubbles(){
ctx.clearRect(0, 0, w, h);
var newBubbles = [],
x, y, i, j, m, imgData, offset;
for(var i=0, l=generators.length; i<l; i++){
for(var j=0, m=0|Math.random()*6; j<m; j++){
newBubbles.push( 0|generators[i] + j );
}
generators[i] = Math.max(0, Math.min(w, generators[i] + Math.random()*10 - 5));
}
bubbles.unshift(newBubbles);
for(i=0; i<bubbles.length; i++){
y = h - i*2;
if(y<0){
bubbles.splice(i);
break;
}
ctx.beginPath();
for(j=0, m=bubbles[i].length; j<m; j++){
x = 0|(bubbles[i][j] += Math.random() * 6 - 3);
ctx.moveTo(x, y);
ctx.lineTo(x+1, y+1);
}
ctx.stroke();
}
}
function createBubbleGenerator(){
generators.push(0|Math.random() * w);
}
function onResize(){
w = $cont.width();
h = $cont.height();
$canvas.attr('width', w).attr('height', h);
ctx.strokeStyle = '#AAA';
}
});
然而,当有更多气泡时确实会减速。
答案 1 :(得分:1)
我猜您需要调查getImageData
和setImageData
方法。返回的图像数据可写入像素级别。我想你可以用黑色填充画布,在其上调用getImageData,更新用下一个“帧”气泡返回的像素数据,然后用setImageData将其写回画布。无限制地重复最后两个步骤,令人作呕。
See here了解更多详情。