• requestAnimationFrame


    介绍:
    requestAnimationFrame 是 js 中除了 setTimeout 和 setInterval 之外另外一个可以实现动画的API。
      语法:
      long window.requestAnimationFrame(callback);
      void window.cancelAnimationFrame(long); //取消动画

        参数: callback 动画回调函数

        返回值:long 指的是 callback 在浏览器回调列表中的一个标识,可以用来取消回调函数。

    
    
    requestAnimationFrame 方法在浏览器下一次重绘之前告诉浏览器调用指定的函数(callback)来更新动画。
    如果想要有一个持续的动画,需要在callback 里再次调用requestAnimationFrame。
    在调用callback 时会传入一个参数 DOMHighResTimeStamp 指的是回调函数被执行的时间,也就是 performance.now() 返回的时间,该时间戳的最小精度是1 ms。

    优点(TODO):

      1. 无需计算回调时间,动画的流畅性更有保障。
         -- 无论是setTimeout或者是setInterval都需要指明浏览器回调函数的时间。尽管设置了1000/60的回调时间,也就是每秒60帧的动画,但是并不能保证浏览器的真实回调时间,可能会造成动画卡顿。
            requestAnimationFrame 不需要设置回调时间,跟着浏览器的重绘的钩子走。这种做法更加高效,不会失帧或者卡顿,更大程度的保证了动画的流畅性。
      2. 性能优秀,占用更少内存。
         -- 对隐藏或者不可见元素的动画,requestAnimationFrame 不会进行重绘或者是回流,意味着占用的内存更少,性能更好。


    例子:
    1. scroll 动画
     1 /**
     2  *  scrollHeight: 目标高度
     3  *  duration:      持续时间 ms
     4  **/
     5 
     6 function scrollTo(scrollHeight, duration) {
     7     let from = window.scrollY;
     8     let to = scrollHeight - window.scrollY;
     9     lastTimestamp = performance.now(); //上一次动画的时间
    10     let fps = 0; //总帧数
    11     let currentFPS = 0; //当前帧数
    12 
    13     const step = function (newTimestamp) {
    14         //计算出总帧数,由于每次调用的时间不确定,也就是每次调用时距离上一次用用的时间差不确定,
    15         //为了确保动画执行的时间和连续性,所以总帧数每次都需要重新计算
    16         fps = Math.round(duration/Math.abs(newTimestamp - lastTimestamp ));
    17         
    18         //如果当前帧数等于总帧数,则直接滚动到目标高度,跳出函数,动画结束
    19         if(currentFPS >= fps){
    20             window.scrollTo(0, scrollHeight);
    21             return;
    22         }
    23         // 计算出当前这一帧动画的位移(或者是角度等等..)
    24         // 执行动画
    25         let displacement = Tween.Quad.easeInOut(currentFPS, from, to, fps);
    26         window.scroll(0, displacement);
    27         // 当前帧数自加,更新本次动画的时间,用作下一次计算
    28         currentFPS++;
    29         lastTimestamp = newTimestamp;
    30         //进行下一帧动画
    31         window.requestAnimationFrame(step);
    32     }
    33     window.requestAnimationFrame(step);
    34 }

    2. 取消动画操作:

    html

    1 <button id="stopBtn">stop<button>
    2 <button id="startBtn">start<button>

    css

    1 div {
    2   width:  10px;
    3   height: 10px;
    4   background: #ffd213;
    5 }

    js

     1 var animationId;
     2 var stop = document.getElementById('stopBtn');
     3 var start = document.getElementById('startBtn');
     4 
     5 function createBar() {
     6     document.body.append(document.createElement('div'));
     7     animationId = requestAnimationFrame(createBar);
     8 }
     9 animationId = requestAnimationFrame(createBar);
    10 
    11 stop.addEventListener('click', function() {
    12     cancelAnimationFrame(animationId);
    13 });
    14 
    15 start.addEventListener('click', function() {
    16     animationId = requestAnimationFrame(createBar);
    17 });
     
     
  • 相关阅读:
    CF1592F2 Alice and Recoloring 2
    CF1601E Phys Ed Online
    AGC050B Three Coins
    [学习笔记]珂朵莉树(Old Drive Tree)
    CF30E. Tricky and Clever Password
    [学习笔记]替罪羊树
    开源项目MiniOA队员招募通知
    MiniOA开发过程记录(33)自动登录模式
    MiniOA开发过程记录(29)安装Maven
    简易工作流设计思考(欢迎补充和批评)
  • 原文地址:https://www.cnblogs.com/KingCong/p/9508217.html
Copyright © 2020-2023  润新知