javascript - 我应该使用 requestAnimationFrame 淡入多个元素吗?实现60fps的动画?

标签 javascript css animation

尝试保持 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 源代码的结尾并向后工作。我个人认为这比从细节开始更容易理解。

  1. 您需要在某处开始动画。所以 JSFiddle 中的最后一件事是

    window.requestAnimationFrame(eachFrame);    //start the animation
    

    这将调用一个名为 eachFrame() 的函数当到了下一帧的时间时,例如。每秒 60 次的下一个倍数。但它只会执行一次。

  2. 您需要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()再次。

  3. 您需要的最后一个函数是实际绘制框架的函数!即render(current time) 。假设,例如 head1head2引用您想要设置动画的两个标题元素,例如 <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取决于currTimeopacity2取决于currTime减去一个常数FADE_SPACING ,因此元素 2 的不透明度更改将比元素 1 的不透明度更改晚 FADE_SPACING 开始。女士。

JSFiddle已填写所有详细信息。它对两个 <h1> 的不透明度进行动画处理元素,每个元素的动画开头之间有一个间距。我希望这有帮助!

关于javascript - 我应该使用 requestAnimationFrame 淡入多个元素吗?实现60fps的动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37910634/

相关文章:

html - CSS3 滚动动画不起作用

python - 如何在 matplotlib 中绘制动画矩阵

javascript - jQuery UI slider : Allow handles to cross over

javascript - 解构es6中的对象数组

javascript - React Native 如何使用 FlatList inside nativebase Tabs onEndReach keep fire non-stop

html 5 解析媒体查询 vs html 4.0 过渡

windows-phone-7 - 自定义 Storyboard中的 "Cannot resolve TargetName"错误

javascript - webpack 不允许 d3.csv() 加载数据?

html - 本地页面上的 "Source map error: TypeError: NetworkError when attempting to fetch resource."

jquery - 如何使用 jQuery 实现悬停效果