美文网首页菜鸟前端工程师
JavaScript学习笔记019-原生js运动框架0时间运动框

JavaScript学习笔记019-原生js运动框架0时间运动框

作者: Mr柳上原 | 来源:发表于2018-08-25 23:10 被阅读0次

    Author:Mr.柳上原

    • 付出不亚于任何的努力
    • 愿我们所有的努力,都不会被生活辜负
    • 不忘初心,方得始终

    吾日三省吾身

    学习

    学习

    学习

    Nodejs又来了

    下个月笔记更新

    前端果然是一项需要活到老学到老的语言

    当你登上这座船

    几乎永远不可能再停下来

    <!DOCTYPE html> <!-- 文档类型:标准html文档 -->
    
    <html lang='en'> <!-- html根标签 翻译文字:英文 -->
    
    <head> <!-- 网页头部 -->
    
    <meat charset='UTF-8'/> <!-- 网页字符编码 -->
    
    <meat name='Keywords' content='关键词1,关键词2'/>
    
    <meat name='Description' content='网站说明'/>
    
    <meat name='Author' content='作者'/>
    
    <title>前端59期学员作业</title> <!-- 网页标题 -->
    
    <link rel='stylesheet' type='text/css' href='css/css1.css'/> <!-- 外链样式表 -->
    
    <style type='text/css'> /*内部样式表*/
     * {
    margin: 0;
    padding: 0;
        }
        #box {
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
    height: 100px;
    background: pink;
        }
    
    </style>
    
    </head>
    
    <body> <!-- 网页主干:可视化区域 -->
    <div id="box"></div>
    
    // 时间运动框架实例
    <script>
                var box = document.getElementById("box");
    
        animation(box, {
          width: 300,
          height: "500px",
          top: 50,
          left: 120
        }, 1000, function(){
          console.log('动画执行结束')
        });
        // 起始值   终点值  =  运动的目标值   
        function animation(ele, data = {}, time = 500, cb = () => {}) {
          var startValue = {} // 存放起始值
          var changeValue = {}  // 终点 - 起始
          var startTime = new Date();  // 起始时间
    
          var eleStart = getStyle(ele); // 取到ele对象的所有样式
    
          for (var key in data) {
            var val = parseFloat(eleStart[key]);
            startValue[key] = isNaN(val) ? 0 : val;
            changeValue[key] = parseFloat(data[key]) - startValue[key]; // 目标值 - 起始值  =  变化量
          }
    
          run();
          function run() { // 计算每个调用时刻的  属性值
            var nowTime = new Date() - startTime;
            var t1 = nowTime / time; // 拿到已花费时间在总时间的比例
    
            if (t1 >= 1) {// 时间用完了,应该到终点了
              t1 = 1;
            } else {
              requestAnimationFrame(run);
            }
    
            for (var key in changeValue) {
              var val = t1 * changeValue[key] + startValue[key]; // 每个时刻点的目标值
              ele.style[key] = val + "px";
            }
    
            // 这才是真正的结束了
            if(t1 === 1){
              cb();
            }
          }
        }
    
        //let styleObj = getComputedStyle(box);
    
        //let widthNum = styleObj.width;
    
        //box.currentStyle.width;
    
        function getStyle(ele) {
          return ele.currentStyle || getComputedStyle(ele);
        }
    
    <script>
    
    // 运动框架 animation.js
    <script>
    /*
        参数: * 必填   []选填
    
            *obj        需要运动的对象(原生DOM节点)
            *json       变化的属性(必须是json对象,)  低版本IE要在css给初始值,不然时是auto
            *time       动画持续时间
    
            [easing]    运动函数(默认匀速运动)
                        1.Linear 匀速,  此时speed可以不填。
                        2.Quad 二次方缓动效果
                        3.Cubic 三次方缓动效果
                        4.Quart 四次方缓动效果
                        5.Quint 五次方缓动效果
    
                        6.Sine  正弦缓动效果
                        7.Expo  指数缓动效果
                        8.Circ  圆形缓动函数
    
                        9.Elastic 指数衰减正弦曲线缓动函数
                        10.Back  超过范围的三次方的缓动函数
                        11.Bounce 指数衰减的反弹曲线缓动函数
            
            [speed]     运动方式(值为Number)
                        0   代表加速运动
                        1   代表减速运动
                        2   先加速后减速
    
            [callback]  回调函数,this指向obj。
    */
    /*
        * t: current time(当前时间);
        * b: beginning value(初始值);
        * c: change in value(变化量);
        * d: duration(持续时间)。    
    */
    
    function animation(ele, data, time, cb) {
      // requestAnimationFrame 的兼容
      window.requestAnimationFrame = window.requestAnimationFrame || function (cb) { return setTimeout(cb, 1000 / 60) }
      // 获取对象的样式
      function getStyle(ele) {return ele.currentStyle || getComputedStyle(ele)}
      // tween.js 运动库
      var Tween = {
        Linear: {
          easeIn: function (t, b, c, d) {
            return c * t / d + b;
          }
        },
        Quad: {
          easeIn: function (t, b, c, d) {
            return c * (t /= d) * t + b;
          },
          easeOut: function (t, b, c, d) {
            return -c * (t /= d) * (t - 2) + b;
          },
          easeInOut: function (t, b, c, d) {
            if ((t /= d / 2) < 1) return c / 2 * t * t + b;
            return -c / 2 * ((--t) * (t - 2) - 1) + b;
          }
        },
        Cubic: {
          easeIn: function (t, b, c, d) {
            return c * (t /= d) * t * t + b;
          },
          easeOut: function (t, b, c, d) {
            return c * ((t = t / d - 1) * t * t + 1) + b;
          },
          easeInOut: function (t, b, c, d) {
            if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
            return c / 2 * ((t -= 2) * t * t + 2) + b;
          }
        },
        Quart: {
          easeIn: function (t, b, c, d) {
            return c * (t /= d) * t * t * t + b;
          },
          easeOut: function (t, b, c, d) {
            return -c * ((t = t / d - 1) * t * t * t - 1) + b;
          },
          easeInOut: function (t, b, c, d) {
            if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
            return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
          }
        },
        Quint: {
          easeIn: function (t, b, c, d) {
            return c * (t /= d) * t * t * t * t + b;
          },
          easeOut: function (t, b, c, d) {
            return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
          },
          easeInOut: function (t, b, c, d) {
            if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
            return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
          }
        },
        Sine: {
          easeIn: function (t, b, c, d) {
            return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
          },
          easeOut: function (t, b, c, d) {
            return c * Math.sin(t / d * (Math.PI / 2)) + b;
          },
          easeInOut: function (t, b, c, d) {
            return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
          }
        },
        Expo: {
          easeIn: function (t, b, c, d) {
            return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
          },
          easeOut: function (t, b, c, d) {
            return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
          },
          easeInOut: function (t, b, c, d) {
            if (t == 0) return b;
            if (t == d) return b + c;
            if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
            return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
          }
        },
        Circ: {
          easeIn: function (t, b, c, d) {
            return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
          },
          easeOut: function (t, b, c, d) {
            return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
          },
          easeInOut: function (t, b, c, d) {
            if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
            return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
          }
        },
        Elastic: {
          easeIn: function (t, b, c, d, a, p) {
            var s;
            if (t == 0) return b;
            if ((t /= d) == 1) return b + c;
            if (typeof p == "undefined") p = d * .3;
            if (!a || a < Math.abs(c)) {
              s = p / 4;
              a = c;
            } else {
              s = p / (2 * Math.PI) * Math.asin(c / a);
            }
            return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
          },
          easeOut: function (t, b, c, d, a, p) {
            var s;
            if (t == 0) return b;
            if ((t /= d) == 1) return b + c;
            if (typeof p == "undefined") p = d * .3;
            if (!a || a < Math.abs(c)) {
              a = c;
              s = p / 4;
            } else {
              s = p / (2 * Math.PI) * Math.asin(c / a);
            }
            return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b);
          },
          easeInOut: function (t, b, c, d, a, p) {
            var s;
            if (t == 0) return b;
            if ((t /= d / 2) == 2) return b + c;
            if (typeof p == "undefined") p = d * (.3 * 1.5);
            if (!a || a < Math.abs(c)) {
              a = c;
              s = p / 4;
            } else {
              s = p / (2 * Math.PI) * Math.asin(c / a);
            }
            if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
            return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
          }
        },
        Back: {
          easeIn: function (t, b, c, d, s) {
            if (typeof s == "undefined") s = 1.70158;
            return c * (t /= d) * t * ((s + 1) * t - s) + b;
          },
          easeOut: function (t, b, c, d, s) {
            if (typeof s == "undefined") s = 1.70158;
            return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
          },
          easeInOut: function (t, b, c, d, s) {
            if (typeof s == "undefined") s = 1.70158;
            if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
            return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
          }
        },
        Bounce: {
          easeIn: function (t, b, c, d) {
            return c - Tween.Bounce.easeOut(d - t, 0, c, d) + b;
          },
          easeOut: function (t, b, c, d) {
            if ((t /= d) < (1 / 2.75)) {
              return c * (7.5625 * t * t) + b;
            } else if (t < (2 / 2.75)) {
              return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
            } else if (t < (2.5 / 2.75)) {
              return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
            } else {
              return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
            }
          },
          easeInOut: function (t, b, c, d) {
            if (t < d / 2) {
              return Tween.Bounce.easeIn(t * 2, 0, c, d) * .5 + b;
            } else {
              return Tween.Bounce.easeOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
            }
          }
        }
      }
    
      // 运动函数的选择配置项
      var option = data.options // options 存起来 
      // 对象要改变的属性
      var valueDate = data.data  
    
      // speed的数组【easeIn。。】
      var speedArr = ["easeIn", "easeOut", "easeInOut"]
    
      // 存放起始值
      var startValue = {} 
      // 终点 - 起始 = 变化量
      var changeValue = {}
      // 起始时间  
      var startTime = new Date()  // 起始时间
      
      var eleStart = getStyle(ele) // 取到ele对象的所有样式
    
      for (var key in valueDate) {
        var val = parseFloat(eleStart[key])
        startValue[key] = isNaN(val) ? 0 : val
        changeValue[key] = parseFloat(valueDate[key]) - startValue[key] // 目标值 - 起始值  =  变化量
      }
    
      // options 的默认情况
      var speed = option && option.speed
      var easing = option && option.easing
    
      if (typeof option === "object") {
        if("easing" in option){ // options 存在运动函数
          speed = speed || 0
          // 确定easing 是不是Linear
          
          if(easing.toLowerCase() === 'linear'){
            speed = 0
            easing = "Linear"
          }
        }else{
          speed = 0
          easing = "Linear"
        }
      }else{ // 没有options 参数 默认 匀速运动
        speed = 0
        easing = "Linear"
      }
      run()
      function run() { // 计算每个调用时刻的  属性值
        var t = new Date() - startTime
        var t_ = time - t
        for (var key in changeValue) {
          var val = Tween[easing][speedArr[speed]](t, startValue[key], changeValue[key], time)
          
          var currentValue = parseFloat(valueDate[key])
          // 限制最大值
          if(t_ <= 0){
            val = Math.min(val, currentValue)
            val = Math.max(val, currentValue)
          }
    
          if(key.toLowerCase() === "opacity"){
            ele.style[key] = val
            ele.style.filter = "alpha(opacity=" + val * 100 + ")" // IE透明度
          }else{
            ele.style[key] = val + "px"
          }
        }
        if(t_ <= 0){
          cb && cb()
        }else{
          requestAnimationFrame(run)
        }
      }
    }
    </script>
    
    </body>
    
    </html>
    

    相关文章

      网友评论

        本文标题:JavaScript学习笔记019-原生js运动框架0时间运动框

        本文链接:https://www.haomeiwen.com/subject/rcrniftx.html