移动端动画——requestAnimationFrame

window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行

注意:若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用window.requestAnimationFrame()

 

当你准备更新动画时你应该调用此方法。这将使浏览器在下一次重绘之前调用你传入给该方法的动画函数(即你的回调函数)。回调函数执行次数通常是每秒60次,但在大多数遵循W3C建议的浏览器中,回调函数执行次数通常与浏览器屏幕刷新次数相匹配。为了提高性能和电池寿命,因此在大多数浏览器里,当requestAnimationFrame() 运行在后台标签页或者隐藏的<iframe> 里时,requestAnimationFrame() 会被暂停调用以提升性能和电池寿命。

回调函数会被传入DOMHighResTimeStamp参数,DOMHighResTimeStamp指示当前被 requestAnimationFrame() 排序的回调函数被触发的时间。在同一个帧中的多个回调函数,它们每一个都会接受到一个相同的时间戳,即使在计算上一个回调函数的工作负载期间已经消耗了一些时间。该时间戳是一个十进制数,单位毫秒,最小精度为1ms(1000μs)。

 

语法:window.requestAnimationFrame(callback);

参数:callback下一次重绘之前更新动画帧所调用的函数(即上面所说的回调函数)。该回调函数会被传入DOMHighResTimeStamp参数,该参数与performance.now()的返回值相同,它表示requestAnimationFrame() 开始去执行回调函数的时刻。

返回值:一个 long 整数,请求 ID ,是回调列表中唯一的标识。是个非零值,没别的意义。你可以传这个值给 window.cancelAnimationFrame() 以取消回调函数。

 

示例一:

var start = null;
var element = document.getElementById('SomeElementYouWantToAnimate');
element.style.position = 'absolute';

function step(timestamp) {
  if (!start) start = timestamp;
  var progress = timestamp - start;
  element.style.left = Math.min(progress / 10, 200) + 'px';
  if (progress < 2000) {
    window.requestAnimationFrame(step);
  }
}

window.requestAnimationFrame(step);

示例二:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
    <title>2.2 移动端动画</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }
        .box {
            width: 100px;
            height: 100px;
            background-color: red;
            /*position: absolute;
            transition: left margin-left 1s;*/
            /*transition: transform 1s;*/
        }
    </style>
</head>
<body>
    <button id="btn">start</button>
    <div id="box" class="box"></div>

    <script>
        // var boxEl = document.getElementById('box'),
        //     btnEl = document.getElementById('btn');
        // var dest = window.innerWidth - 100;

        // btnEl.addEventListener('click', function () {
        //     move(boxEl, dest);
        // }, false);

        // function move(el, position) {
        //     el.style.transform = 'translate3d(' + position +'px, 0, 0)';
        // }

        var requestAnimationFrame = window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            function (fn) {
                setTimeout(fn, 16);
            };
        var boxEl = document.getElementById('box'),
            btnEl = document.getElementById('btn');
        var dest = window.innerWidth - 100,
            speed = 10,
            position = 0;

        btnEl.addEventListener('click', function () {
            requestAnimationFrame(step);
        }, false);

        function move(el, position) {
            el.style.transform = 'translate3d(' + position +'px, 0, 0)';
        }

        function step() {
            if (position < dest) {
                position += speed;
                move(boxEl, position);
                requestAnimationFrame(step);
            } else {
                position = dest;
                move(boxEl, position);
            }
        }

    </script>
</body>
</html>

 

实现js动画最好的是requestAnimationFrame:

requestAnimationFrame 比起 setTimeout、setInterval的优势主要有两点:
1、requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。
2、在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量。

示例三:

var dis =0;
function animation(){
  requestAnimationFrame(function(){
      div.style.left = ++dis;
      if(disx<50) animation();
  })  
}
animation();

 

posted @ 2019-09-30 16:30  是桂  阅读(713)  评论(0编辑  收藏  举报