美文网首页
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