用requestAnimationFrame做轮播

本文探讨了如何使用requestAnimationFrame而非setTimeout或setInterval来实现更优化的动画效果。requestAnimationFrame能够根据浏览器的实际情况自动调整帧率,并确保在浏览器重绘前执行,提供更好的性能和流畅体验。同时,介绍了requestAnimationFrame的回调参数和取消机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用setTimeout和setInterval来实现动画

  1. 没有对调用动画的循环机制进行优化
  2. 即使传递毫秒为单位的参数,也不能打到ms的准确性。因为JavaScript是单线程的,可能发生阻塞
  3. 没有考虑绘制动画的最佳时机

requestAniamationFrame

  • requestAnimationFrame不需要使用者指定循环间隔时间,浏览器会基于当前页面是否可见、CPU的负荷情况等来自行决定最佳的帧速率,从而更合理地使用CPU。
  • 如果想做逐帧动画,就应该用这个方法,这就要求动画函数执行会先于浏览器重绘动作。通常,被调用的频率是每秒60次。
  • 回调函数只会传入一个DOMHighResTimeStamp参数,表示函数队列被触发的时间。
  • requestAnimationFrame返回一个id,用于window.cancelAnimationFrame(id)来取消这个回调函数
  • 兼容代码:
window.requestAnimationFrame=window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||

            function (callback, element) {
                var start,
                        finish;

                window.setTimeout(function () {
                    start = +new Date();
                    callback(start);
                    finish = +new Date();

                    self.timeout = 1000 / 60 - (finish - start);

                }, self.timeout);
            };
window.cancelNextRequestAnimationFrame = window.cancelRequestAnimationFrame
        || window.webkitCancelAnimationFrame
        || window.webkitCancelRequestAnimationFrame
        || window.mozCancelRequestAnimationFrame
        || window.oCancelRequestAnimationFrame
        || window.msCancelRequestAnimationFrame
        || clearTimeout;

requestAnimationFrame做的简易动画

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <style>
        *{padding:0;margin: 0}
            .outer{width: 100px;height: 100px;overflow:hidden;position: relative;}
            .inner{
                height:100px;list-style-type:none;width: 400px;
            }
            .inner:after{height: 0;content: '';clear: both;visibility: hidden;}
            .inner li{float: left;width: 100px;height: 100px}
            li:nth-child(1){background: red}
            li:nth-child(2){background: black}
            li:nth-child(3){background: yellow}
            li:nth-child(4){background: green}
        </style>
    </head>
    <body>
    <div class="outer">
        <ul class="inner">
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </div>

    <button>下一步</button>
    <script type="text/javascript">
        var start = null;
        var element = document.querySelector('.inner')
        element.style.position = 'absolute';
        var cur=0,mm=100,timeid
        function step(timestamp) {
          if (!start) start = timestamp;
          var progress = timestamp - start;
          if(cur==3){
            element.style.left=0;
          }else{
            element.style.left = -Math.min(progress / 10+cur*100, (cur+1)*100) + 'px';
          }

          if (progress < 1000) {
            timeid=window.requestAnimationFrame(step);
          }else{
            cur=cur<3?cur+1:0
            window.cancelAnimationFrame(timeid)
            timeid=null
            start=null
            setTimeout(auto,1000)
          }
        }
        var btn=document.querySelector('button')
        btn.onclick=function(){
            auto()
        }
        function auto(){
            if(!timeid){
                console.log(cur)
                timeid=window.requestAnimationFrame(step);
            }
        }
    </script>
    </body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值