我们可以使用requestAnimationFrame
在浏览器中绘制框架。但是,如果我们在同一页面上有多个动画会发生什么?
例如,如果我们有3个自定义标记和2个淡化效果,因为每个效果都有它自己requestAnimationFrame
并不意味着我们实际上每帧画5次浏览器请求?
此外,如果我将文本滚动条FPS限制在30FPS但我的渐弱效果以45FPS运行并不意味着在1秒的时间内我们总共运行3 * 30 + 2 * 45 = 180幅画作?
是否会更好(考虑到我将页面上的所有动画限制为相同的FPS速率)让1 requestAnimationFrame
绘制我的所有动画?因此,我最终每秒只能进行30-60帧绘画(取决于FPS限制)?
我只想尝试尽可能减少CPU使用率的方法。
答案 0 :(得分:1)
将多个效果合并为一个requestAnimationFrame
您使用一组javascript对象来定义每个效果的时间:
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;
}
}
}
这里的示例代码和演示:
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);
}
&#13;
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
&#13;
<canvas id="canvas" width=300 height=300></canvas>
&#13;
答案 1 :(得分:0)
requestAnimationFrame
引用内部浏览器机制来呈现整个网页的框架。当你说requestAnimationFrame
你没有告诉它为你创造一些东西时,你要求它告诉你何时渲染下一帧,这样你就可以把你的动作连接到它。
因此,您可以根据需要多次使用requestAnimationFrame
,并且只要您(您请求的)框架可用,浏览器就会自动同步您的操作。
当然,performancevise最好避免每帧多个函数调用(因为它们需要在每个帧内一个接一个地堆栈和执行),但从同步的角度来看它是完全无关紧要的。此外,你无法将任何帧或颜料加倍。