Холст анимация не работает бегло. Что я могу сделать?

0

Поскольку я добавил o: Math.random()*(1 - 0.1) + 0.1//opacity для значений случайной непрозрачности заряда, анимация не работает плавно. Что я могу сделать, чтобы предотвратить это? Как сделать мой скрипт более эффективным в отношении производительности?

window.onload = function () {
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var W = canvas.width = window.innerWidth;
    var H = 550;
    var mp = 45; //max particles
    var particles = [];
    //var rotate = 180;

    reqAnimFrame = window.requestAnimationFrame ||
                   window.mozRequestAnimationFrame    ||
                   window.webkitRequestAnimationFrame ||
                   window.msRequestAnimationFrame     ||
                   window.oRequestAnimationFrame;

    for ( var i = 0; i < mp; i++ )
        {
            particles.push({
                x: Math.floor(Math.random()*W), //x-coordinate
                y: Math.floor(Math.random()*H), //y-coordinate
                d: Math.floor(Math.random()*(12 - 1) + 1), //density
                r: Math.floor(Math.random()*(70 - 10) + 10), //radius
                o: Math.random()*(1 - 0.1) + 0.1 //opacity
            })
        }



    function animate() {
        reqAnimFrame(animate);
        for ( var i = 0; i < mp; i++ )
            {
                var p = particles[i];
                p.x += p.d;


                if(p.x >= W + p.r){
                    p.x = -300;
                    p.y = Math.floor(Math.random()*H);
                }
                draw();
            }
    }

    function draw() {
        ctx.clearRect(0, 0, W, H);
        for ( var i = 0; i < mp; i++ )
            {
                var p = particles[i];
                ctx.fillStyle = "rgba(51,51,51," + p.o + ")";
                ctx.beginPath();
                ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2, false);
                ctx.fill();
                //ctx.moveTo(p.x,p.y);
                //ctx.lineTo(p.x + 150, p.y + (-180));
                //ctx.lineTo(p.x + 300, p.y);
            }    
    }
    animate();
    };//onload function
Теги:
canvas
animation

2 ответа

1
Лучший ответ

вы вызываете draw внутри цикла обновления один раз для каждой частицы, что приводит к стоимости mp * mp вместо стоимости mp.
Первое, что нужно сделать, - это нарисовать только один раз на частицу, поэтому не вызывайте его в цикле обновления, а только один раз в конце обновления.

Обратите внимание, что вы можете получить некоторые результаты, изменив контекст globalAlpha вместо создания нового цвета.

2

Я делаю jsfiddles one и two.

В первой closePath нет функции функции closePath, во второй скрипке она вызывает.

В первой скрипте график времени devtools показывает дополнительное использование памяти 7 МБ в секунду (после того, как 1-й вызов CG в вашем случае, IMHO): от 10 МБ до 17 МБ

Во второй временной шкале beginPath показано дополнительное использование памяти 2 МБ от beginPath to closePath (около 130 мс): от 10 МБ до 12 МБ. Но в этом случае CG не звонит.

Я думаю, будет лучше добавить функцию closePath, чтобы предотвратить вызов GC. И используйте меньшее количество частиц для старых браузеров, потому что для меня (MacBook Pro, Chrome) все работает отлично, а fps - 60 (максимум).

  • 0
    Интересно. Я действительно удивлен. Я думал, что beginPath означает, что вы закрываете предыдущий путь ... кажется, я был неправ!
  • 1
    О beginPath : он запускает только подпуть. Каждый новый beginPath будет создавать только еще один подпуть. Но closePath добавляет текущий подпуть к основному пути и закрывает подпуть, то есть освобождает часть памяти.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню