美文网首页
Dom_坐标属性及动画算子等(三)

Dom_坐标属性及动画算子等(三)

作者: mao77_ | 来源:发表于2019-02-09 19:38 被阅读3次

    Dom_坐标属性及动画算子等(三)

    1. 事件对象中的坐标的几个属性
    • offsetX, offsetY
    1. 事件触发点相对于target元素的左边和上边的偏移量
    2. 或者认为现在的坐标系原点:target元素的左上角
    • clientX, clientY
    1. 相对于游览器的左边和上边的偏倚量
    • screenX ,screenY
    1. 显示器的左上角作为坐标原点
    2. 别名: X, Y
    • pageX, pageY
    1. 把页面的左上角作为坐标原点

    2. 事件代理

    循环式的注册事件

    1. 当有新元素添加的时候,这些元素不会自动的有事件,必须要手动添加
    2. 当那些已经有事件的元素删除的时候,那些事件永远用不到了但是不会被内存回收,容易引起内存泄漏。

    事件委托, 事件代理

    把事件委托给它的上层元素来处理

        var btn = document.querySelector("button");
        btn.onclick = function (){
            var li = document.createElement("li");
            li.innerHTML = "python";
            ul.appendChild(li);
        }
        
        ul.onclick = function (e){
            var target = e.target;
            if(target.className == "item"){
                alert(target.innerHTML);
            }
            /*if (target.tagName.toLowerCase() == "li"){
                alert(target.innerHTML);
            }*/
        }
    
    1. open方法

       var btn = document.querySelector("#btn");
       var btn2 = document.querySelector("#btn2");
       btn.onclick = function (){
           // 参数1:url 参数2:给新打开的网页起个名字
           /*
           参数2: _black 如果传入一个空字符串,也是_blank
                 _self 表示在当前的tab页面中打开.
                 
                 "普通的名字" 表示给打开的页面起个名字, 将来再使用
                     open打开的时候, 会先查看有这个名字的页面是否已经打开
                     如果是, 就刷新已经打开的页面
                 
                 
               返回值:就是新打开的窗口(其实就是一个新的页面中的window对象)
            */
           win = open("abc.html", "b", "width=300,height=200,left=400,top=500");
       }
       var win;
       btn2.onclick = function (){
           win.close();
           // close();
       }
      
    2. 小广告

    • open: 打开新的窗口
    • close: win.close() 调用那个window的close,就可以关掉哪个window
    • moveBy(): 移动窗口
      • moveBy(-10, 10)
    • moveTo(): 移动到指定位置
      • moveTo(100, 100)

        setTimeout(function (){
            win = open("abc.html", "_blank", "width=400,height=400,left=200,top=200");
        }, 10);
        
        var lastI;
        setInterval(function (){
            /*if (win && win.innerWidth == 0){
                win = open("abc.html", "_blank", "width=400,height=400,left=200,top=200");
            }*/
            win.moveBy(10, 10);
        }, 200)
        
    1. location

       <button>assign:加载新的文档</button>
       <button>reload:重新加载当前文档</button>
       <button>replace:用新的页面当前页面</button>
       <script>
       var btns = document.querySelectorAll("button");
       btns[0].onclick = function (){
           // 会把访问记录添加到history中
           location.assign("https://www.baidu.com");
       }
       btns[1].onclick = function (){
           // 重新加载当前网页
           // true:表示总是从服务器加载  false: 表示允许从缓存加载
           location.reload(false);
       }
       btns[2].onclick = function (){
           // 不会把访问记录添加到history
           location.replace("https://www.baidu.com");
       }
       </script>
       <!--<script>
       document.write("协议:" + location.protocol + "<br>")
       document.write("host:" + location.host + "<br>")
       document.write("hostname:" + location.hostname + "<br>")
       document.write("href:" + location.href + "<br>")
       document.write("port:" + location.port + "<br>")
       document.write("pathname:" + location.pathname + "<br>")
       document.write("search:" + location.search + "<br>")
       </script>-->
      
    2. history

       <button>直接去第三个</button>
       <a href="second.html">去第二个页面</a>
       <script>
       // 记录你在当前这个页面中访问过的url的个数
       console.log(history.length);
       var btn = document.querySelector("button");
       btn.onclick = function (){
           history.go();
       }
      
    3. navigator

    4. screen

    5. 以前用到的动画的一些问题

    增量动画

    • setTimeout
    • setInterval

    时间的动画

    • var p = Math.min(1, (new Date() - starTime) / 2000);

    • p: 时间的归一化. p就是我们归一化的时间

        <button id="btn">开始运动</button>
        <script>
        
        // 1000ms 10s走完
        var btn = document.querySelector("button");
        var div = document.querySelector("div");
        var duration = 2000;
        btn.onclick = function (){
            var starTime = new Date();  // 动画的开始时间
            requestAnimationFrame(function step(){
                var p = Math.min(1, (new Date() - starTime) / duration);
        
                div.style.left = 1000 * p + "px";
        
                if (p < 1){
                    requestAnimationFrame(step);
                }
            });
        }
      

    匀加速运动

        <button id="btn">开始运动</button>
        <script>
        
        // 1000ms 10s走完
        var btn = document.querySelector("button");
        var div = document.querySelector("div");
        var duration = 1000;
        var dis = 500;
        btn.onclick = function (){
            var starTime = new Date();  // 动画的开始时间
            requestAnimationFrame(function step(){
                var p = Math.min(1, (new Date() - starTime) / duration);
        
                // div.style.left = dis * p * p + "px";  // 匀加速
                // div.style.left = dis * p * (2 - p) + "px";  //匀减速
                // div.style.left = 2 * dis * p + "px";  //
                // div.style.top = dis * p * p + "px";  //
                div.style.left =200 -  200 * Math.sin(Math.PI * 2 * p) + "px";
                div.style.top = 200 - 200 * Math.cos(Math.PI * 2 * p) + "px";
                
                if (p < 1){
                    requestAnimationFrame(step);
                }
            });
        }
    
    1. 使用动画算子
    • 写一个框架,可以完成大部分的动画动作
    • 给框架需要输入数据
      • 周期 —— 计算归一化的时间

      • 动画算子函数 —— 用来计算动画算子

      • 函数、动画具体的动作 —— 框架计算出来动画算子,帮助我们去执行这些动作

        动画算子:
            e = p
            e = p*p
            e =  p*(2-p)
            
            <button id="btn">开始运动</button>
        <script src="easing.js"></script>
        <script>
        
        var btn = document.querySelector("button");
        var div = document.querySelector("div");
        var duration = 2000;  // 动画周期, 表示动画应该多长时间执行完毕
        var dis = 500;
        btn.onclick = function (){
            // var initLeft = div.offsetLeft;
            var starTime = new Date();  // 动画的开始时间
            requestAnimationFrame(function step(){
                var p = Math.min(1, (new Date() - starTime) / duration);  // 归一化的时间
        
                // div.style.left = dis * p + "px";
                // div.style.left = dis * p * p + "px";
                div.style.top = dis * Easing.easeBoth(p) + "px";
        
                if (p < 1){
                    requestAnimationFrame(step);
                }
            });
        }
        
        
        
        <div></div>
        <p></p>
        <button id="btn">开始运动</button>
        <script src="easing.js"></script>
        <script src="animator.js"></script>
        <script>
        
        var btn = document.querySelector("button");
        var div = document.querySelector("div");
        var anim = new MyAnimator(2000, Easing.bounce, function (e){
            div.style.left = 1000 *(1 - e) + "px";
        })
        anim.start();
        
        //----
        var p = document.querySelector("p");
        var anim1 = new MyAnimator(5000, Easing.bounce, function (e){
            // p.style.left = 1000 * (1 - e) + "px";
            p.style.opacity = 1 - e;
        });
        anim1.start();
        </script>
        
        var pow = Math.pow,
            BACK_CONST = 1.70158;
        // t指的的是动画进度 归一化的时间  前面的p
        Easing = {
        // 匀速运动
            linear: function (t){
                return t;
            },
        // 匀加速运动
            easeIn: function (t){
                return t * t;
            },
        // 减速运动
            easeOut: function (t){
                return (2 - t) * t;
            },
        //先加速后减速
            easeBoth: function (t){
                return (t *= 2) < 1 ? .5 * t * t : .5 * (1 - (--t) * (t - 2));
            },
        // 4次方加速
            easeInStrong: function (t){
                return t * t * t * t;
            },
        // 4次方法的减速
            easeOutStrong: function (t){
                return 1 - (--t) * t * t * t;
            },
        // 先加速后减速,加速和减速的都比较剧烈
            easeBothStrong: function (t){
                return (t *= 2) < 1 ? .5 * t * t * t * t : .5 * (2 - (t -= 2) * t * t * t);
            },
        //
            easeOutQuart: function (t){
                return -(Math.pow((t - 1), 4) - 1)
            },
        // 指数变化 加减速
            easeInOutExpo: function (t){
                if (t === 0) return 0;
                if (t === 1) return 1;
                if ((t /= 0.5) < 1) return 0.5 * Math.pow(2, 10 * (t - 1));
                return 0.5 * (-Math.pow(2, -10 * --t) + 2);
            },
        //指数式减速
            easeOutExpo: function (t){
                return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1;
            },
        // 先回弹,再加速
            swingFrom: function (t){
                return t * t * ((BACK_CONST + 1) * t - BACK_CONST);
            },
        
        // 多走一段,再慢慢的回弹
            swingTo: function (t){
                return (t -= 1) * t * ((BACK_CONST + 1) * t + BACK_CONST) + 1;
            },
        
        //弹跳
            bounce: function (t){
                var s = 7.5625,
                    r;
        
                if (t < (1 / 2.75)){
                    r = s * t * t;
                }else if (t < (2 / 2.75)){
                    r = s * (t -= (1.5 / 2.75)) * t + .75;
                }else if (t < (2.5 / 2.75)){
                    r = s * (t -= (2.25 / 2.75)) * t + .9375;
                }else{
                    r = s * (t -= (2.625 / 2.75)) * t + .984375;
                }
        
                return r;
            }
        };
        
        function MyAnimator(duration, ease, callBack){
            this.duration = duration;
            this.ease = ease;
            this.callBack = callBack;
        }
        MyAnimator.prototype = {
            start: function (){
                var startTime = new Date();
                var that = this;
                requestAnimationFrame(function step(){
                    var p = Math.min(1, (new Date() - startTime) / that.duration)
                    var e = that.ease(p);
                    that.callBack(e);
                    if (p < 1){
                        requestAnimationFrame(step)
                    }
                })
            }
        }
        
    1. css3_transfrom属性

    转换, 变换

    • 可以改变位置(平移),旋转, 扭曲, 缩放
    • 它的属性值,是一些css函数

    特点

    1. 位置还在原来的地方,仅仅是它的样式在移动,用它去做一些动画,效率会比从前更改left | top定位之后更高的多

    2. 变换的时候,总是相对于它没有添加这个属性的位置来变换

    3. 不管任何的变换,它都会有一个参考的变换点,默认都是元素的几何中心。可以通过transform-origin来更改参考点

       p {
           width: 100px;
           height: 100px;
           background-color: gray;
           position: absolute;
           
           left: 50%;  /*相对于父容器的宽度的50%*/
           top: 50%;  /*相对于父容器的宽度的50%*/
           transform: translate(-50%, -50%);  /*参照与自己的宽度50%*/
       }
      
       div{
           width: 100px;
           height: 100px;
           background-color: pink;
           margin: 20px;
       }
       .box1{
           background-color: gray;
           transform-origin: 200px 0;
           transform: rotate(-10deg); /*让元素顺时针旋转 45°*/
       }
      
    4. 使用自定义动画

      <script>
      var box = document.querySelector("div");
      var animator = new MyAnimator({
          direction : "normal",
          durations: [1000, 2000, 1000, 2000],
          eases: [Easing.linear, Easing.bounce, Easing.easeBoth, Easing.bounce],
          callBacks: [function (e){
              box.style.transform = "translate(" + 1000 * e + "px,0)"
          }, function (e){
              box.style.transform = "translate(1000px," + 600 * e + "px)"
          }, function (e){
              box.style.transform = "translate(" + 1000 * (1 - e) + "px,600px)"
          }, function (e){
              box.style.transform = "translate(0px," + 600 * (1 - e) + "px)"
          }]
      })
      animator.start("2");
      
      
      
      /*执行动画序列*/
      function MyAnimator(opts){
          this.opts = opts;
      }
      
      MyAnimator.prototype = {
          start: function (count){
              if (count == undefined || count == null || count <= 0) count = 1;
      
              var durations = this.opts.durations,
                  eases = this.opts.eases,
                  callBacks = this.opts.callBacks,
                  direction = this.opts.direction;
      
              var startTime = new Date(),
                  self = this,
                  index = 0;  // 表示正在执行的动画的索引
              var i = 0;
              requestAnimationFrame(function step(){
                  var p = Math.min(1, (new Date() - startTime) / durations[index]);
                  /*self.callBacks[index](self.eases[index](p));*/
                  var e = eases[index](p);
                  if (i % 2 == 1 && direction == "reverse"){
                      e = 1 - e;
                  }
                  callBacks[index](e);
      
                  if (p == 1){  // fun fun fun
                      index++;
                      if (index < callBacks.length){
                          startTime = new Date();
                          requestAnimationFrame(step);
                      }else{
                          count--;
                          i++;
                          if (count > 0){
                              index = 0;  // 如果完成了一次, 下一次继续从序列中第 0 个继续执行
                              startTime = new Date();
                              if (direction == "reverse"){
                                  durations.reverse();
                                  eases.reverse();
                                  callBacks.reverse();
                              }
                              requestAnimationFrame(step)
                          }
                      }
                  }else{
                      requestAnimationFrame(step);
                  }
              })
          }
      }
      

    相关文章

      网友评论

          本文标题:Dom_坐标属性及动画算子等(三)

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