尝试保持 60 fps 动画。目前,我收到了很多以 30~ fps 的速度出现的慢帧峰值,并且我的眼睛可以明显感觉到这种波动。
重大编辑:扔掉旧的过时代码,添加新代码和解释
fadeIn: function(ele){
raf = window.requestAnimationFrame(function() {
console.log(ele);
var opacity = 0;
function increase () {
opacity += 0.05;
if (opacity >= 1){
// complete
ele.style.opacity = 1;
return true;
}
ele.style.opacity = opacity;
requestAnimationFrame(increase);
}
increase();
});
},
fadeInElements: function(elements, properties, speed, delay){
var raf;
var ele;
for (i = 0; i < properties.length; i++){
ele = elements[properties[i]];
console.log('outside loop ' + ele);
instance.fadeIn(ele);
}
},
我的新代码在上面。成功了:
- 迭代多个元素(每个元素为
ele
),然后调用fadeIn(ele)
- 因此,所有元素都会淡入。
- 但是,我希望每次“淡入”之间有
50ms
延迟(每次在新元素上触发fadeIn()
)
最佳答案
好消息是,这实际上并不是递归——它更像是超时。您提供一个绘制框架的函数,浏览器会为您调用它。
这里的答案显示了 complete JSFiddle 的摘录。它不会尝试复制您的确切代码,而是尝试解释您需要了解的内容,以便您可以相应地调整您的代码。代码编写得很容易理解,所以我确信还有其他方法可以更快地完成它!
这个答案是从顶层向下进行的,这意味着我描述了 JSFiddle 源代码的结尾并向后工作。我个人认为这比从细节开始更容易理解。
您需要在某处开始动画。所以 JSFiddle 中的最后一件事是
window.requestAnimationFrame(eachFrame); //start the animation
这将调用一个名为
eachFrame()
的函数当到了下一帧的时间时,例如。每秒 60 次的下一个倍数。但它只会执行一次。您需要
eachFrame()
跟踪我们在动画中的位置。var startTime = -1.0; // -1 = a flag for the first frame. function eachFrame() { // Render this frame ------------------------ if(startTime<0) { // very first frame (because of the -1.0): save the start time. startTime = (new Date()).getTime(); render(0.0); // the parameter to render() is the time within the // animation. } else { // every frame after the first: subtract the saved startTime // to determine the current time. render( (new Date()).getTime() - startTime ); } // Now we're done rendering one frame. ------ //Start the timer to call this function again //when it's time for the next frame. window.requestAnimationFrame(eachFrame); }; //eachFrame
eachFrame()
确定相对于动画开始的当前时间。getTime()
给出以毫秒为单位的时间。另一件事
eachFrame()
就是调用window.requestAnimationFrame(eachFrame);
再次。这不是递归。相反,eachFrame()
会完成运行,然后,下一次帧出现时,浏览器会调用eachFrame()
再次。您需要的最后一个函数是实际绘制框架的函数!即
render(current time)
。假设,例如head1
和head2
引用您想要设置动画的两个标题元素,例如<h1>
HTML 中声明的元素。clamp(x)
函数返回x
但低于 0 且高于 1。function render(currTime) { // *** Put your rendering code here *** // How opaque should head1 be? Its fade started at currTime=0. var opacity1 = clamp(currTime/FADE_DURATION); // over FADE_DURATION ms, opacity goes from 0 to 1 // How opaque should head2 be? var opacity2 = clamp( (currTime-FADE_SPACING)/FADE_DURATION ); // fades in, but doesn't start doing it until // FADE_SPACING ms have passed. // Apply the changes head1.style.opacity = opacity1; head2.style.opacity = opacity2; } //render
在
render()
,您可以根据当前时间算出不透明度。您不必担心帧之间的延迟,因为requestAnimationFrame
为我们处理这个问题。您可以通过偏移时间来错开过渡。在此示例中,opacity1
取决于currTime
和opacity2
取决于currTime
减去一个常数FADE_SPACING
,因此元素 2 的不透明度更改将比元素 1 的不透明度更改晚FADE_SPACING
开始。女士。
JSFiddle已填写所有详细信息。它对两个 <h1>
的不透明度进行动画处理元素,每个元素的动画开头之间有一个间距。我希望这有帮助!
关于javascript - 我应该使用 requestAnimationFrame 淡入多个元素吗?实现60fps的动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37910634/