2014-12-17 1 views
0

Мы можем использовать requestAnimationFrame, чтобы нарисовать рамку в нашем браузере. Однако, что произойдет, если у нас есть несколько анимаций на одной странице?Скорость печати веб-браузера с несколькими анимациями на странице

Если, например, у нас есть 3 пользовательских шатра и несколько эффектов затухания, так как каждый эффект имеет свой собственный requestAnimationFrame, разве это не означает, что мы на самом деле рисуем браузер 5 раз каждый запрос кадра?

Кроме того, если я ограничу свои текстовые скроллеры FPS на 30FPS, но мои эффекты затухания работают с 45FPS, разве это не означает, что в промежутке в 1 секунду мы работаем в общей сложности 3 * 30 + 2 * 45 = 180 кадров картины?

Было бы лучше (учитывая, что я ограничиваю всю свою анимацию на странице той же скоростью FPS), чтобы 1 requestAnimationFrame рисовать все мои анимации? В результате я получаю всего 30-60 кадров в секунду (зависит от предела FPS)?

Я просто пытаюсь найти способы, которые помогут максимально уменьшить использование ЦП.

ответ

1

Это довольно легко объединить несколько эффектов в одном requestAnimationFrame

Вы используете массив яваскрипта объектов, которые определяют сроки каждого из эффектов:

var timers=[]; 
timers.push({delay:50,nextFireTime:0,doFunction:doEffect1,counter:0}); 
timers.push({delay:500,nextFireTime:0,doFunction:doEffect2,counter:0}); 
timers.push({delay:5000,nextFireTime:0,doFunction:doEffect3,counter:0}); 

Вы можете использовать одну петлю requestAnimationFrame, что итерация через петлю и запускает каждый эффект, основанный на nextFireTime

function timerLoop(currentTime){ 
    // request another loop 
    requestAnimationFrame(timerLoop); 
    // iterate through each timer 
    for(var i=0;i<timers.length;i++){ 
     // if this timer has reached its 
     //  next scheduled trigger time... 
     if(currentTime>timers[i].nextFireTime){ 
      var t=timers[i]; 
      // ...then do this effect 
      t.doFunction(t,i); 
      // and reset the timer to fire again in the future 
      t.nextFireTime=currentTime+t.delay; 
     } 
    } 
} 

H ERE пример кода демо:

var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 
var cw=canvas.width; 
 
var ch=canvas.height; 
 

 

 
var timers=[]; 
 
timers.push({delay:50,nextFireTime:0,doFunction:doTimers,counter:0}); 
 
timers.push({delay:500,nextFireTime:0,doFunction:doTimers,counter:0}); 
 
timers.push({delay:5000,nextFireTime:0,doFunction:doTimers,counter:0}); 
 
// 
 
requestAnimationFrame(timerLoop); 
 
// 
 
function timerLoop(currentTime){ 
 
    // request another loop 
 
    requestAnimationFrame(timerLoop); 
 
    // iterate through each timer 
 
    for(var i=0;i<timers.length;i++){ 
 
    // if this timer has reached its 
 
    //  next scheduled trigger time... 
 
    if(currentTime>timers[i].nextFireTime){ 
 
     var t=timers[i]; 
 
     // ...then do this effect 
 
     t.doFunction(t,i); 
 
     // and reset the timer to fire again in the future 
 
     t.nextFireTime=currentTime+t.delay; 
 
    } 
 
    } 
 
} 
 
// 
 
function doTimers(t,i){ 
 
    // this demo just calls this one effect function 
 
    // but you would call separate effect functions 
 
    // for your marquis & fades. 
 
    ctx.clearRect(0,100+i*20-20,cw,20); 
 
    ctx.fillText('Timer#'+i+' with '+t.delay+'ms delay has fired '+(++t.counter)+' times.',20,100+20*i);  
 
}
body{ background-color: ivory; padding:10px; } 
 
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>

+0

Большое спасибо! очень признателен. Я прочитал несколько статей о 'requestAnimationFrame', и кажется, что' requestAnimationFrame' соберет все анимации для 1 картины за раз. Как вы думаете, я неправильно понял, что я читал? В вашей функции 'timeLoop' у вас есть аргумент' currentTime', но вы никогда не передавали его в качестве аргумента при вызове 'requestAnimationFrame', как переменная' currentTime' получает инициализацию и обновление тогда? Последний вопрос, следует ли использовать 'canvas' для выполнения моей анимации вместо' div '? это больше ЦП? – kfirba

0

requestAnimationFrame reffers к внутреннему механизму браузера рендеринга кадра всей веб-страницы. Когда вы говорите requestAnimationFrame, вы не говорите ему, чтобы что-то создавали для вас, вы просите его рассказать вам, когда отображается следующий кадр, чтобы вы могли подключить свое действие к нему.

Таким образом, вы можете использовать requestAnimationFrame столько раз, сколько хотите, и браузер автоматически синхронизирует ваши действия, запуская их каждый раз, когда будет запрограммирован кадр (который вы запросили).

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

 Смежные вопросы

  • Нет связанных вопросов^_^