• 浅谈原生JavaScript的动画和特效


    一、JavaScript中的动画原理

      动画效果的实现总的来说可分为两种,一种是利用纯css实现,该方法在css3成熟后广泛应用;另外一种是通过JavaScript(或者一些封装的库如jQuery的animate方法)间接的操作css样式,每隔几秒执行一次。这里主要讲的是原生js里面的动画:

    1、常用的动画方式

    1. JavaScript动画用的最多的3个方法是setInterval()、setTimeout()以及requestAnimationFrame():
    2. 延时器setTimeout()和定时器setInterval ()主要是自身会执行动画效果,它们里面有回调函数function和时间参数,然后通过设置事件就可以用了;
    3. requestAnimationFrame(回调函数):它是一个全局函数,接收一个回调函数作为参数,在调用该函数后,它会要求浏览器根据自己的频率进行一次重绘,在即将开始的浏览器重绘时,会调用这个函数,并会给这个函数传入调用回调函数时的时间作为参数。
      • 值得一提的是,该方法跟setTimeout()特别类似,它的功效也是一次性的,若想达到动画效果,则必须连续不断的调用该函数,所以它应是setTimeout的性能增强版。
      • requestAnimationFrame与 setTimeout的区别 是用户指定的,而 requestAnimationFrame 是浏览器刷新频率决定的,一般遵循 W3C 标准,它在浏览器每次刷新页面之前执行。

      4.清除动画效果:setTimeout()的清除是clearTimeout(),setInterval()的清除是clearInterval(),requestAnimationFrame()的清除则是使用cancelAnimationFrame()

         <button  id="btn">清除</button>
            var id;
        <script> var time = new Date(); requestAnimationFrame(function step(){ console.log(new Date() - time); time = new Date(); id = requestAnimationFrame(step); }); btn.onclick = function (){ cancelAnimationFrame(id ) }
        </script>

    2、简单动画的一些坑 

    1. setTimeout和setInterval即使是0毫秒执行也会有延迟效果,请看下面的代码
        console.log("1");
              setTimeout(function(){
                console.log("3")
               },0);
               console.log("2");    
          //结果是1 2 3
      

        为什么结果不是1 3 2呢,这其实主要是因为:JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序,所以由于受到JavaScript的单线程关系,像setTimeout、setInterva、来自浏览器内核的其他线程如鼠标点击、Ajax异步请求等都得排队等待JavaScript引擎的处理(当线程中没有执行任何同步代码的前提下才会执行异步代码),因此就算setTimeout和setInterva的时间为0,但它原理任然是不变的,也会将其加入到队列末尾,0秒后执行。

    2. 简单动画的变慢问题

            当setTimeout、setInterval甚至是requestAnimationFrame在循环里面要做很长的处理时,就会出现动画时间变慢的结果,使它本该在固定时间内结束而结果却是不尽人意的延迟

     function step() {
                var temp = div.offsetLeft + 2;
                div.style.left = temp + "px";
                window.requestAnimationFrame(step);
                for (var i = 0; i < 50000; i++) {
                console.log("等待我执行完才能执行")
                }
            }
            window.requestAnimationFrame(step);
    

     3、填坑

      1.动画变慢的结果其实是采用增量的方式来执行了动画,为了更精确的控制动画,更合适的方法是将动画与时间关联起来

      2.动画通常情况下有终止时间,如果是循环动画,我们也可以看做特殊的——当动画达到终止时间之后,重新开始动画。因此,我们可以将动画时间归一(Normalize)表示:

    //duration 是动画执行时间   isLoop是否为循环执行。
            function startAnimation(duration, isLoop){
              var startTime = Date.now();
              requestAnimationFrame(function change(){
                // 动画已经用去的时间占总时间的比值
                var p = (Date.now() - startTime) / duration;
                if(p >= 1.0){
                  if(isLoop){ // 如果是循环执行,则开启下一个循环周期。并且把开始时间改成上个周期的结束时间
                    startTime += duration;
                    p -= 1.0; //动画进度初始化
                  }else{
                    p = 1.0;    //如果不是循环,则把时间进度至为 1.0 表示动画执行结束
                  }
                }
                console.log("动画已执行进度", p);
                if(p < 1.0){ //如果小于1.0表示动画还诶有值完毕,继续执行动画。
                  requestAnimationFrame(change);
                }
              });
            }
    

      做个小栗子:用时间控制动画周期精确到2s中

    二、常见动画效果实现

    1、 匀速水平运动

      用时间来控制进度 s=S∗p

    2、匀加速(减速)运动

    • 加速度恒定,速度从0开始随时间增加而均匀增加。
    • 匀加速公式:大写S:要移动的总距离 p:归一化的时间进度 s=S∗p*p

        

    • 匀减速运动公式:s=S∗p∗(2−p)

     

     3、水平抛物运动

      匀速水平运动和自由落体运动的组合

    4、正弦曲线运动

      正弦运动:x方向匀速,垂直方向是时间t的正弦函数

     5、圆周运动

      圆周运动公式:x=R.sin(2∗π∗p),y=R.cos(2∗π∗p)

    总结:

    js原生的动画效果主要有setInterval()、setTimeout()以及requestAnimationFrame()这三种方法,通过设定时间可以对动画做一些简单的效果,但也会出现一些坑,比如它们在循环里面如果要做很长的处理时,就会出现动画时间变慢的结果,这时我们可以采用增量的方式来执行动画,将动画与时间关联起来;

    在运动效果方面,我们可以通过各种运动公式,采用归一化时间来控制进度,从而实现运动效果。

    写博客不是我的爱好,只是人脑毕竟空间只有那么大,有时候会忘了,好记性不如烂笔头,所以通过博客记录点点滴滴,以后可以翻出来看。
  • 相关阅读:
    Tensorflow2(预课程)---2.1、多层感知器-层方式
    pandas.Series转numpy的n维数组
    numpy将多维数组降维成一维
    《仙路争锋》读书感悟---200910(为逆所以顺,为玩所以勤,为生所以死)
    legend3---解决bootstrap栅格系统自动图片高度不齐问题
    python机器学习库numpy---15、模拟e^x的麦克劳林展开式
    400G 光模块的价格
    HTML编辑器 实现ctrl+v粘贴图片并上传、word粘贴带图片
    网页编辑器 实现ctrl+v粘贴图片并上传、word粘贴带图片
    富文本编辑器 实现ctrl+v粘贴图片并上传、word粘贴带图片
  • 原文地址:https://www.cnblogs.com/zhongxiaoyou/p/9045761.html
Copyright © 2020-2023  润新知