Ускорение вызова, чтобы нарисовать один пиксель (тысячи раз) на холсте - PullRequest
2 голосов
/ 01 июля 2011

Я создаю «генератор пузырей» в качестве фонового эффекта, который будет работать на странице. Генератор работает нормально, но он замедляется, через некоторое время лот .

демо: http://jsfiddle.net/Dud2q/

Я настроил демонстрацию на запуск с интервалом в 1 мс, чтобы было легко увидеть замедление при повторном запуске скрипта (особенно, если вы сделаете окно результатов большим).

Проблема в том, что у меня есть тысячи звонков на этот код (по одному на каждый пузырь):

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

Кто-нибудь знает о более быстром способе рисования одного пикселя на холсте?

Кроме того, если кто-то захочет сделать пузырьки более реалистичными, я бы не стал жаловаться:)

Ответы [ 2 ]

3 голосов
/ 01 июля 2011

Вместо того, чтобы рисовать пузыри один за другим, как насчет рисования сразу?т.е. вывести 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 голос
/ 01 июля 2011

Полагаю, вам нужно будет изучить методы getImageData и setImageData.Возвращаемые данные изображения доступны для записи вплоть до уровня пикселей.Я хотел бы представить, что вы могли бы заполнить холст черным, вызвать на нем getImageData, обновить данные пикселей, возвращаемые со следующим «кадром» пузырьков, и записать его обратно на холст с помощью setImageData.Повторите последние два шага до бесконечности, до тошноты.

Подробнее см. Здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...