加快调用以在画布中绘制一个像素(数千次)

时间:2011-07-01 02:06:32

标签: javascript canvas

我正在创建一个“气泡生成器”作为将在页面上运行的背景效果。生成器工作正常,但在一段时间后它会变慢, 很多

演示:http://jsfiddle.net/Dud2q/

我将演示设置为以1毫秒的间隔运行,因此当您重新启动小提琴时很容易看到减速(特别是如果您使结果窗口变大)。

问题是我有几千次调用此代码(每个泡泡一次):

ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x+1, y+1);
ctx.stroke();

有没有人知道在画布上绘制一个像素的更快方法?

另外,如果有人想要让气泡更加真实,我不会抱怨:)

2 个答案:

答案 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)

我猜您需要调查getImageDatasetImageData方法。返回的图像数据可写入像素级别。我想你可以用黑色填充画布,在其上调用getImageData,更新用下一个“帧”气泡返回的像素数据,然后用setImageData将其写回画布。无限制地重复最后两个步骤,令人作呕。

See here了解更多详情。