问题描述
我们可以使用 requestAnimationFrame
在我们的浏览器中绘制框架。但是,如果我们在同一页面上有多个动画会发生什么呢?
We can use requestAnimationFrame
in order to paint a frame in our browser. However, what happens if we have multiple animations on the same page?
例如,如果我们有3个自定义字幕和2种淡入淡出效果,因为每种效果都有自己的 requestAnimationFrame
并不意味着我们实际上是在为每个框架请求绘制5次浏览器吗?
If for example we have 3 custom marquees and some 2 fading effects, since each effect has it's own requestAnimationFrame
doesn't it mean that we are actually painting the browser 5 times each frame request?
此外,如果我限制我的文字卷轴的FPS为30FPS,但我的褪色效果以45FPS运行,这并不意味着在一秒钟的时间里我们总共运行了3 * 30 + 2 * 45 = 180帧画作吗?
Moreover, if I limit my text-scrollers FPS to be at 30FPS but my fading effects are running with 45FPS doesn't it mean that in a span of 1 second we are running in total 3*30 + 2*45 = 180 frame paintings?
会更好(考虑到我将页面上的所有动画限制为相同的FPS的事实)让1 requestAnimationFrame
绘制所有动画吗?结果,我最终只能每秒获得30-60帧绘画(取决于FPS限制)?
Would it be better (considering the fact that I limit all of my animation on the page to the same FPS rate) to let 1 requestAnimationFrame
draw all of my animations? As a result I would end up with merely 30-60 frame painting per second (depends on the FPS limit)?
我只是想着想办法尽可能减少CPU使用率。
I'm simply trying to think of ways that help reduce the CPU usage as much as possible.
推荐答案
将多个效果组合成一个相当容易requestAnimationFrame
It's fairly easy to combine multiple effects into a single requestAnimationFrame
您使用了一系列javascript对象,它们定义了每种效果的时间:
You use an array of javascript objects which define the timing of each of your effects:
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循环来循环遍历并基于<$ c触发每种效果$ c> nextFireTime
You can use one requestAnimationFrame loop that iterates through the loop and triggers each effect based on a 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;
}
}
}
下面是示例代码:
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>
这篇关于Web浏览器在页面上具有多个动画的绘制速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!