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 });
 
 
原文地址:https://www.cnblogs.com/KingCong/p/9508217.html