• window.requestAnimationFrame()的使用,处理更流畅的动画效果


    https://blog.csdn.net/w2765006513/article/details/53843169

    window.requestAnimationFrame()的使用

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/w2765006513/article/details/53843169

    1.前言

    在说明这个js的api用法之前,我先给个效果以及源码: 
    1. 页面效果 
    2. 页面源码

    2.说明

    window.requestAnimationFrame()这个API是浏览器提供的js全局方法,针对动画效果。

    1)使用

    1. 用法1:
    function animate() { 
      //done();
      requestAnimationFrame(animate); 
    } 
    requestAnimationFrame(animate);
    

    注意函数里的requestAnimationFrame(animate) 
      有了这句话,就形成了递归调用,设置应为这个函数多用在持续的动画中,可以自由处理要不要这句话。 
    2. 用法2:

    var globalID; 
    function animate() { 
      // done(); 一直运行
      globalID=requestAnimationFrame(animate); 
      // Do something animate 
    } 
    globalID=requestAnimationFrame(animate);//开始
    cancelAnimationFrame(globalID);//结束
    

    2)优点:

    浏览器可以优化并行的动画动作,更合理的重新排列动作序列,并把能够合并的动作放在一个渲染周期内完成,从而呈现出更流畅的动画效果。

    • 经过浏览器优化,动画更流畅;
    • 窗口没激活时,动画将停止,省计算资源;

    3) 使用场景:

    可以调节重新渲染,大幅提高网页性能。其中最重要的,它可以将某些代码放到下一次重新渲染时执行。避免短时间内触发大量reflow。

    function doubleHeight(element) {
      var currentHeight = element.clientHeight;
      window.requestAnimationFrame(function () {
        element.style.height = (currentHeight * 2) + 'px';
      });
    }
    elements.forEach(doubleHeight);
    

    页面滚动事件(scroll)的监听函数,就很适合用这个api,推迟到下一次重新渲染。

    $(window).on('scroll', function() {
       window.requestAnimationFrame(scrollHandler);
    });
    

    最佳的应用场景还是在帧动画里,可以大幅优化性能;

    4)兼容性支持

    为了避免老浏览器没有提供这个api,可以先检测,后处理,没有提供api时,写对应的函数挂在window下,以后的调用与正常情况一致。 
    网上大神的杰作

    (function() {
        var lastTime = 0;
        var vendors = ['webkit', 'moz'];
        for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
            window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
            window.cancelAnimationFrame =
              window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
        }
    
        if (!window.requestAnimationFrame)
            window.requestAnimationFrame = function(callback) {
                var currTime = new Date().getTime();
                var timeToCall = Math.max(0, 16 - (currTime - lastTime));
                var id = window.setTimeout(function() { callback(currTime + timeToCall); },
                  timeToCall);
                lastTime = currTime + timeToCall;
                return id;
            };
    
        if (!window.cancelAnimationFrame)
            window.cancelAnimationFrame = function(id) {
                clearTimeout(id);
            };
    }());
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    简单说明:

    1. 定义了一个立即执行函数,形成具备作用域,避免污染全局空间。
    2. 将功能函数挂在了window.
    3. 利用setTimeout和clearTimeout的异步实现相应的功能,不是为一种很好的结局方案。
    4. 如果对异步有疑问,可以查看我的另一篇博客js的执行机制
  • 相关阅读:
    能够分页显示的Label控件
    C# winform 捕获全局异常
    纯C#钩子实现及应用
    C#对App.config文件或者web.config文件中节点的操作类
    C#中强制关闭某个进程
    VS2005中服务的启动,安装与卸载
    获取数据库表结构和表数据的小程序(VB.NET版本)
    使用ImessageFilter接口实现截获键盘或者鼠标的消息
    Windows_API_函数 参考大全
    系统升级程序的介绍
  • 原文地址:https://www.cnblogs.com/chaoyuehedy/p/9768080.html
Copyright © 2020-2023  润新知