阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

      教程列表

      抓包专区
      测试专区

      JavaScript 动画原理

      基础动画库以动画原理

      最动画要做绝对定位,写left,写top;定好位置;

      动画主要是从5个方向改变:

      • 宽度 (width)
      • 高度 (height)
      • 水平 (left)
      • 垂直 (top)
      • 透明度 (opacity)

      JS写动画,主要是学逻辑关系,深入研究闭包作用域;并不是完全用JS写动画。CSS3做这个会更好;

      this关键字:

      this是谁,和在哪儿定义没有关系,只和在哪儿执行有关系,看它的执行主体是谁;自执行函数是在window,所以this是window;

      (只有执行的时候才能知道this是谁;)

      动画要考虑临界值的问题;每走一步之前先做判断,判断当前的位置+步长,是否大于等于目标值;如果大于等于目标值;则停在目标值上;

      定时器的清理;定时器开启之前要记得清理,这样可以避免作用域累计;示例代码如下

      clearTimeout(timer);//timer里储存的是定时器的序列号,1,2,3,4,5,6,7,8,9之类的;代表某个定时器;清除的就是定时器的序列号;
      //没开一次定时器,就会产生一个定时器的序列号;
      
          var cur=getCss(ele,"left");
          if(cur<target){//当前位置小于目标值;
              if(cur+11>=target){//临界值的判断;
                  ele.style.left=target+"px";
              }else{
                  ele.style.left=getCss(ele,"left")+11+"px";
              }
              timer=window.setTimeout(function(){move(ele,target)},30)
      
      • 如果当前起始的位置小于我们的目标值的话,我们需要往右走,如果当前起始的位置大于我们的目标值的话,往左走,相等的话不走
        
      • 不管方向,都需要做临界判断,为了保障临界点的准确性,需要在判断的时候加上我们的步长
        

        动画中的几部分:

      1. 开始位置、结束位置、总距离;(总距离=结束位置-开始位置)
        
      2. 总运动时间、定时器间隔时间 、步长 ;(步长=(总距离/总运动时间)*定时器间隔时间)
        
      3. 运动的方式:匀速、减速、加速、变速
        

      文字介绍2

      动画部分

      最动画要做绝对定位,写left,写top;定好位置;

      动画主要是从5个方向改变:

      • 宽度 (width)
      • 高度 (height)
      • 水平 (left)
      • 垂直 (top)
      • 透明度 (opacity)

      JS写动画,主要是学逻辑关系,深入研究闭包作用域;并不是完全用JS写动画。CSS3做这个会更好;

      同步和异步编程

      js是单线程的编程方法;

      • 同步:上面事情等待,在此期间我要一直等,只有这件事做完才能做下件事情
      • 异步:模拟多线程,上面的事情正在等待中,我们不需要等它,继续做下面的事情,当下面的事情做完了,然后我们发现上面的事情也等待完成了,在执行上面的事情

      同步编程的例子:

       function fn() {
       for (var i = 0; i < 1000; i++) {
       }
       console.log(i);//只有循环完成才能输出i
       return i;
       }
       var c = fn();
       console.log(c);//只有fn执行完成后才会输出c
      

      异步编程例子:

      1、所有的事件绑定都是异步编程
      
      oDiv.onclick=function(){}
      window.onload=function(){}
      console.log(100);
      
      2、定时器都是异步编程
      定时器的等待时间是有最小值的 每个浏览器都有一个最小值,即使你写的是0,也不是立即执行;定时器和别的代码是两个频道的。异步执行;作用域和预解释的时候有总结过;
      var num = 12;
      window.setTimeout(function () {
          num++;
          console.log(num);
      }, 5);
      for (var i = 0; i < 10000; i++) {//这个循环时间肯定大于5ms,但是也是先从上倒下执行,只有下面的代码都执行完成,才会返回头看定时器是否到时间,到了在执行定时器里面的
      }
      console.log(num);
      //先输出12然后在输出13;说明是先执行完for循环和后面的打印;然后才切到定时器的执行的;
      

      动画中的几部分:

      1. 开始位置、结束位置、总距离;(总距离=结束位置-开始位置)
        
      2. 总运动时间、定时器间隔时间 、步长 ;(步长=(总距离/总运动时间)*定时器间隔时间)
        
      3. 运动的方式:匀速、减速、加速、变速
        

      代码1

      <!DOCTYPE html>
      <html>
      <head lang="en">
          <meta charset="UTF-8">
          <title>从左向右运动</title>
          <style>
              #div1{
                  width: 200px;height: 200px;background:red;position: absolute;left: 0;top:0;
              }
          </style>
      </head>
      <body>
      <div id="div1"></div>
      </body>
      </html>
      <script>
          var oDiv=document.getElementById("div1");
          oDiv.onclick=function(){
              move(this,600)
          };
          function move(ele,target){
              if(getCss(ele,"left")<target){
                  ele.style.left=getCss(ele,"left")+5+"px";
                  window.setTimeout(function(){move(ele,target)},30)
              }
          };
          function getCss(ele,attr){
              //变量未定义不能直接用,如果相判断一个变量是否存在可以typeof;
              //属性未定义可以直接使用;
              if(typeof getComputedStyle){
                  return parseFloat(getComputedStyle(ele,null)[attr]);
              }else{
                  return parseFloat(attr.currentStyle[attr]);
              }
          };
      
      </script>
      

      代码2

      <!DOCTYPE html>
      <html>
      <head lang="en">
          <meta charset="UTF-8">
          <title>从右向左运动</title>
          <style>
              ul,li{list-style: none;}
              #div1{
                  width: 200px;height: 200px;background:red;position: absolute;left: 600px;top:0;border-radius:50%;
              }
              .ul{position: absolute;left: 100px;top: 300px;}
              .ul li{float: left;margin-right: 10px;color: #FFF;cursor: pointer;}
              #left{width: 40px;height: 40px;background:#000000;}
              #right{width: 40px;height: 40px;background:#000000;}
          </style>
      </head>
      <body>
      <div id="div1"></div>
      <ul class="ul">
          <li id="left">左</li>
          <li id="right">右</li>
      </ul>
      </body>
      </html>
      <script>
          var oDiv=document.getElementById("div1");
          var oLeft=document.getElementById("left");
          var oRight=document.getElementById("right");
          var timer=null;//全局变量;
          oLeft.onclick=function(){move(oDiv,0)};
          //点完left后,move运行,还要开启一个定时器;等30ms;timer=function(){move(ele,target)},在等待时候,15ms点了一下右,move方法再去执行;会清除timer;
          oRight.onclick=function(){move(oDiv,800)};
          function move(ele,target){
              clearTimeout(timer);
              var cur=getCss(ele,"left");
              if(cur<target){//当前位置小于目标值;
                  if(cur+11>=target){//临界值的判断;
                      ele.style.left=target+"px";
                  }else{
                      ele.style.left=getCss(ele,"left")+11+"px";
                  }
                  timer=window.setTimeout(function(){move(ele,target)},30)
              }else if(cur>target){//当前位置大于目标值
                  if(cur-11<=target){
                      ele.style.left=target+"px";
                  }else{
                      ele.style.left=getCss(ele,"left")-11+"px";
                  }
                  timer=window.setTimeout(function(){move(ele,target)},30)
              }
          };
          function getCss(ele,attr){
              //变量未定义不能直接用,如果相判断一个变量是否存在可以typeof;
              //属性未定义可以直接使用;
              if(typeof getComputedStyle){
                  return parseFloat(getComputedStyle(ele,null)[attr]);
              }else{
                  return parseFloat(attr.currentStyle[attr]);
              }
          };
      
      </script>
      

      代码3

      <!DOCTYPE html>
      <html>
      <head lang="en">
          <meta charset="UTF-8">
          <title>从右向左运动</title>
          <style>
              ul,li{list-style: none;}
              #div1{
                  width: 200px;height: 200px;background:red;position: absolute;left: 600px;top:0;border-radius:50%;
              }
              .ul{position: absolute;left: 100px;top: 300px;}
              .ul li{float: left;margin-right: 10px;color: #FFF;cursor: pointer;}
              #left{width: 40px;height: 40px;background:#000000;}
              #right{width: 40px;height: 40px;background:#000000;}
          </style>
      </head>
      <body>
      <div id="div1"></div>
      <ul class="ul">
          <li id="left">左</li>
          <li id="right">右</li>
      </ul>
      </body>
      </html>
      <script>
          var oDiv=document.getElementById("div1"),
                  oLeft=document.getElementById("left"),
                  oRight=document.getElementById("right");
          /*确定左右的终点*/
          var cW = document.documentElement.clientWidth || document.body.clientWidth;
          var tarR = cW - oDiv.offsetWidth,
                  tarL = 0;
      
          oLeft.onclick=function(){
              move(oDiv,tarL);
          };
          oRight.onclick=function(){
              move(oDiv,tarR);
          };
      
          var timer=null;//全局变量;
          function move(oDiv,target) {
              var start = getCss(oDiv,"left"),
                      count = start;
              _move();
              function _move() {
                  clearTimeout(oDiv.timer);
                  if (start < target) {//右
                      if (count + 10 >= target) {
                          setCss(oDiv, "left", target);
                          return;
                      }
                      count += 10;
                      setCss(oDiv, "left", count);
                  } else if (start > target) {//左
                      if (count - 10 <= target) {
                          setCss(oDiv, "left", target);
                          return;
                      }
                      count -= 10;
                      setCss(oDiv, "left", count);
                  } else {
                      return;
                  }
                  oDiv.timer = setTimeout(_move, 10);
              }
          }
          function getCss(curEle,attr) {
              var reg = /^(?:margin|padding|border|float|position|display|background|backgroundColor)$/;
              var flag="getElementsByClassName" in document;
              var value = flag ? window.getComputedStyle(curEle, null)[attr] : curEle.currentStyle[attr];
              return !reg.test(attr) ? parseFloat(value) : value;
          }
          function setCss(curEle,attr,value) {
              if(typeof value!=="undefined"){
                  switch (attr) {
                      case "opacity":
                          curEle["style"][attr] = value;
                          curEle["style"]["filter"] = "alpha(opacity=" + (value * 100) + ")";
                          break;
                      case "zIndex":
                          curEle["style"][attr] = value;
                          break;
                      default:
                          curEle["style"][attr] = !isNaN(value) ? value += "px" : value;
                  }
              }
          };
      </script>
      

      代码4

      <!DOCTYPE html>
      <html>
      <head lang="en">
          <meta charset="UTF-8">
          <title>从右向左运动</title>
          <style>
              ul,li{list-style: none;}
              #div1{
                  width: 200px;height: 200px;background:red;position: absolute;left: 600px;top:0;border-radius:50%;
              }
              .ul{position: absolute;left: 100px;top: 300px;}
              .ul li{float: left;margin-right: 10px;color: #FFF;cursor: pointer;}
              #left{width: 40px;height: 40px;background:#000000;}
              #right{width: 40px;height: 40px;background:#000000;}
          </style>
      </head>
      <body>
      <div id="div1"></div>
      <ul class="ul">
          <li id="left">左</li>
          <li id="right">右</li>
      </ul>
      </body>
      </html>
      <script>
          var oDiv=document.getElementById("div1"),
                  oLeft=document.getElementById("left"),
                  oRight=document.getElementById("right");
          /*确定左右的终点*/
          var cW = document.documentElement.clientWidth || document.body.clientWidth;
          var tarR = cW - oDiv.offsetWidth,
                  tarL = 0;
      
          oLeft.onclick=function(){
              move(oDiv,tarL);
          };
          oRight.onclick=function(){
              move(oDiv,tarR);
          };
      
          var timer=null;//全局变量;
          function move(oDiv,target) {
              var start = setCss(oDiv,"left"),
                      count = start;
              _move();
              function _move() {
                  clearTimeout(oDiv.timer);
                  if (start < target) {//右
                      if (count + 10 >= target) {
                          setCss(oDiv, "left", target);
                          return;
                      }
                      count += 10;
                      setCss(oDiv, "left", count);
                  } else if (start > target) {//左
                      if (count - 10 <= target) {
                          setCss(oDiv, "left", target);
                          return;
                      }
                      count -= 10;
                      setCss(oDiv, "left", count);
                  } else {
                      return;
                  }
                  oDiv.timer = setTimeout(_move, 10);
              }
          }
          function setCss(curEle,attr,value) {//设置CSS属性值和获取CSS;如果三个参数就是设置,2个参数就是获取;att是attribute的缩写;
              if(typeof value==="undefined"){//如果有第三个参数,就是设置Css;如果没有就是获取Css;
                  var reg = /^(?:margin|padding|border|float|position|display|background|backgroundColor)$/;
                  var flag="getElementsByClassName" in document;
                  var value = flag ? window.getComputedStyle(curEle, null)[attr] : curEle.currentStyle[attr];
                  return !reg.test(attr) ? parseFloat(value) : value;
              } else{
                  switch (attr) {
                      case "opacity":
                          curEle["style"][attr] = value;
                          curEle["style"]["filter"] = "alpha(opacity=" + (value * 100) + ")";
                          break;
                      case "zIndex":
                          curEle["style"][attr] = value;
                          break;
                      default:
                          curEle["style"][attr] = !isNaN(value) ? value += "px" : value;
                  }
              }
          };
      </script>
      
      目录
      目录