js動畫效果總結

js動畫函數封裝--單物體運動

  1. 對一個div進行寬高屬性的變化,對透明度屬性進行變化。javascript

    *{margin: 0; padding: 0;}    /\*樣式\*/    
          <div id="parent"><div id="son">分享</div> </div>    /*結構*/       
          #parent {position: relative; width: 200px; height: 200px; background-color: #f00; margin-left: -200px;}
          #son {position: absolute; width: 30px; height: 50px; background-color: green; top: 50%; right:-30px; transform: translateY(-50%); text-align: center; }  
           window.onload=function(){ //首先加載函數在dom加載後
           var parent=document.getElementById("parent"); //得到父級dom元素
           parent.onmousemove=function(){ //當鼠標在父級元素上移動時,觸發事件
           move(10,0);    //move 函數對進行處理
           }
           parent.onmouseout=function(){ //當鼠標離開父級元素時,觸發事件
           move(-10,-200);    }}  
           var timer=null; 
           function move(speed,target){
           clearInterval(timer); //每次在進入move以前都清除定時器
           var parent=document.getElementById("parent");
           timer=setInterval(function(){ //設置定時器
           if(parent.offsetLeft==target){ //假如知足條件,清除定時器
           clearInterval(timer);
           }else{ //不然進行進一步處理
              parent.style.marginLeft=parent.offsetLeft+speed+"px";
                }
       },30);
       }   /*js代碼*/

    這裏可能像我這樣的新手對 parent.offsetLeftmarginLeft對這些屬性比較陌生,具體能夠參考這篇文章 offsetLeft,有圖有真相。java

  2. 透明度屬性的處理node

    #opcity {width: 200px; height: 200px; background-color: #f00; filter: alpha(opacity=30); /*兼容IE9 如下*/opacity: 0.3; } /*樣式*/
       <div id="opcity"></div> /*結構*/
       window.onload=function(){
           var opcity=document.getElementById("opcity");
           opcity.onmousemove=function(){
           move(100);    
           }
           opcity.onmouseout=function(){
           move(30);    
           }
       }
       var timer=null;
       var op=30;
       function move(arg){
            clearInterval(timer);
            var opcity=document.getElementById("opcity");
            timer=setInterval(function(){
             var speed=0;
             if(op<arg){
            speed=10;    
             }else {
            speed=-10;
             }
              if(op==arg){
                clearInterval(timer);
             }else {
                 op+=speed;
                 opcity.style.filter="alpha(opacity="+op+")"; /*兼容IE的寫法*/
                 opcity.style.opacity=op/100;
             }
       },30);
       }   /*js代碼*/

    這裏的代碼基本和上面基本上是同樣的,主要是要對 opacity進行處理,這裏在後面還有一種處理辦法,因爲opacity 傳進來是0.3這樣的小數,能夠先用parseFloat()對opacity進行處理,而後在乘以100使其變成一個整數,而後在進行後面的處理。chrome

js動畫函數封裝--多物體運動

div {width: 400px; height: 200px; background-color: yellow; border: 2px solid #666; margin-bottom: 20px;} /*樣式*/

<div id="test"></div>
<div id="test1"></div>  /*結構*/

window.onload=function(){
        var test= document.getElementById("test");
        var test1= document.getElementById("test1");
        test.timer=null;
        test1.timer=null;
        test.onmouseover=function(){
           move(this,'width',200);
        }
        test.onmouseout=function(){
           move(this,'width',400);
        }
        test1.onmouseover=function(){
           move(this,'height',400);
        }
        test1.onmouseout=function(){
           move(this,'height',200);
        }
    }
    function move(obj,attr,target){
        clearInterval(obj.timer);
        obj.timer=setInterval(function(){
        var pa=    parseInt(getStyle(obj,attr));    
         var speed=(target-pa)/8;
         speed=(speed>0)?Math.ceil(speed):Math.floor(speed);
             obj.style[attr]=pa+speed+"px";            
     },30);
    }
    function getStyle(obj,attr){
        if(obj.currentStyle){
            return obj.currentStyle[attr]; /*IE 方法*/
        }else {
            return getComputedStyle(obj,false)[attr]; /*chrome ,ff*/
        }
    }  /*js代碼*/
  1. 這裏新封裝一個函數,getStyle()用來獲取DOM元素樣式,對currentStylegetComputedStyle有疑問的能夠參考一下張鑫旭大神的這篇文章currentStyle getComputedStyle,到這一步開始有進一步對函數的封裝,記得開始的時候單物體運動的時候,只有一個屬性,只須要傳一個參數,對 opacity的處理大體也差很少,只是要多一點轉化,對於多物體運動,屬性的值是在變化的,並且test test1一個改變寬,一個改變高,因此能夠對函數能夠進一步封裝,這裏對於opacity處理是有問題的,須要在函數內部進行判斷,選擇不一樣的分支。這裏還要注意的是定時器不能共用,要單獨設置本身的定時器。json

js動畫函數封裝--緩衝運動

基本結構和上面單物體結構相同dom

<script type="text/javascript">
     window.onload=function(){
        var parent=document.getElementById("parent");
        parent.onmousemove=function(){
        move(0);    
        }
        parent.onmouseout=function(){
        move(-200);    
        }
    }
    var timer=null;
    function move(target){
     clearInterval(timer);
     var parent=document.getElementById("parent");
     timer=setInterval(function(){
          var speed=(target-parent.offsetLeft)/20; //緩衝運動
          speed=(speed>0)?Math.ceil(speed):Math.floor(speed);
           if(parent.offsetLeft==target){
             clearInterval(timer);
          }else {
              parent.style.marginLeft=parent.offsetLeft+speed+"px";
          }
    },30);
    }

再單物體運動中,咱們每次都是加上一個恆定大小的值,其實就是一個勻速運動,爲了作一個緩衝運動,咱們首先聯想到火車進站的時候,通常都是先加速,在減速,最後慢慢加速離開,緩衝運動就相似這種狀況parent.style.marginLeft=parent.offsetLeft+speed+"px";,經過傳過來的目標參數與實際樣式的值進行一個作差處理,而後除以一個數字,剛開始是極值,speed的值變化較大,到後面隨着兩值比較接近,speed愈來愈趨近與0,爲了最後能達到目標值,要讓speed變爲1,再慢慢達到目標值,因此會使用Math.floor()和 Math.ceil()向上取整和向下取整函數,假如speed>0,則像上取整,假如speed<0,則向下取整,取值+1和-1.wordpress

js動畫函數封裝--單物體的多屬性同時運動

<div id="test"></div>
div {width: 400px; height: 200px; background-color: yellow; border: 2px solid #666; margin-bottom: 20px; filter: alpha(opacity=30); /**兼容IE 6*/ opacity: 0.3;}
         window.onload=function(){
         var test= document.getElementById("test");
         test.timer=null;
         test.alpha=30;
         test.onmouseover=function(){
         move(this,{"width": 600, "height": 400, "opacity": 100});
        }
        test.onmouseout=function(){
          move(this,{"width": 400, "height": 200, "opacity": 30})
        }
}
      var flag=true;
      function move(obj,json,fn){
      clearInterval(obj.timer);
      obj.timer=setInterval(function(){
        for(attr in json){
          if(attr=="opacity"){
          var pa= parseFloat(getStyle(obj,attr))*100; 
          }else{
           var pa= parseInt(getStyle(obj,attr));
          }
          var speed=(json[attr]-pa)/8;
          speed=(speed>0)?Math.ceil(speed):Math.floor(speed);
          if(json[attr]!=pa){
              flag=false;
            }
        if(attr=="opacity"){
          obj.alpha+=speed;
          obj.style.filter="alpha(opacity="+obj.alpha+")";
          obj.style[attr]=(obj.alpha)/100;
          }else{
          obj.style[attr]=pa+speed+"px";
          }
    }
    if(flag){
      clearInterval(obj.timer);
      if(fn){
        fn();
      }
    }         
     },30);
}
function getStyle(obj,attr){
     if(obj.currentStyle){
        return obj.currentStyle[attr];
     }else {
        return getComputedStyle(obj,false)[attr];
     }
}

爲了實現單物體的多屬性同時運動,使用到json格式傳參,而後對json裏的每個屬性,在定時器裏用for in循環進行遍歷,用getStyle()對獲取屬性進行處理。函數

js動畫函數封裝--單物體的鏈式運動

.clearfix:after {content: "."; display: block; clear: both; visibility: hidden; height: 0;}
   *{margin: 0; padding: 0;}
   #content {width: 660px; height: 210px; border: 2px solid #ccc; margin :20px auto; font-size: 0;}
   #content a {position: relative; display: inline-block; width: 120px; height: 80px;  text-align: center; font: bold 14px/1 Arial; color: #f3f3f3; text-decoration: none; border: 2px solid orange; margin: 10px 20px;}
   #content a:hover {color: orange;}
   #content a p {position: relative; margin-top: 10px; bottom: -45px;}
   #content a i {position: absolute; top: 5px; left: 40px; display: inline-block; filter: alpha(opacity=100); opacity: 1;}
   <div id="content">
    <a href="#">
        <i><img src="images/001.jpg" alt=""></i>
        <p>便民</p>
    </a>
    <a href="#">
        <i><img src="images/002.jpg" alt=""></i>
        <p>充值</p>
    </a>
    <a href="#">
        <i><img src="images/003.jpg" alt=""></i>
        <p>旅行</p>
    </a>
    <a href="#">
        <i><img src="images/004.jpg" alt=""></i>
        <p>繳費</p>
    </a>
    <a href="#">
        <i><img src="images/005.jpg" alt=""></i>
        <p>電影</p>
    </a>
    <a href="#">
        <i><img src="images/006.jpg" alt=""></i>
        <p>音樂</p>
    </a>
    <a href="#">
        <i><img src="images/007.jpg" alt=""></i>
        <p>教育</p>
    </a>
    <a href="#">
        <i><img src="images/008.jpg" alt=""></i>
        <p>能源</p>
    </a>
</div>
        window.onload=function(){
        var content= document.getElementById("content");
        var links= content.getElementsByTagName("a");
        for (var i = 0; i < links.length; i++) {
            links[i].onmouseenter=function(){
                var inode=this.getElementsByTagName("i")[0];
                inode.timer=null;
                inode.alpha=30;
                    move(inode,{marginTop:-40,opacity: 0},function(){
                        inode.style.marginTop=20+"px";
                        move(inode,{marginTop:5,opacity: 100});
                        });
            }
        }
    }
    //獲取樣式
    function getStyle(obj,attr){
        if(obj.currentStyle){
            return obj.currentStyle[attr];
        }else {
            return getComputedStyle(obj,false)[attr];
        }
    }
    //move 函數    
    function move(obj,json,fn){
    clearInterval(obj.timer);
    obj.timer=setInterval(function(){
    var flag=true;
    for(attr in json){
      if(attr=="opacity"){
      var pa= parseFloat(getStyle(obj,attr))*100; 
      }else{
       var pa= parseInt(getStyle(obj,attr));
      }
      var speed=(json[attr]-pa)/8;
      speed=(speed>0)?Math.ceil(speed):Math.floor(speed);
      if(json[attr]!=pa){
          flag=false;
        }
        if(attr=="opacity"){
              obj.alpha+=speed;
              obj.style.filter="alpha(opacity="+obj.alpha+")";
                obj.style[attr]=(obj.alpha)/100;
            }else{
              obj.style[attr]=pa+speed+"px";
            }
    }
    if(flag){
      clearInterval(obj.timer);
      if(fn){
        fn();
      }
    }          
     },30);
  }function getStyle(obj,attr){
  if(obj.currentStyle){
    return obj.currentStyle[attr];
  }else {
    return getComputedStyle(obj,false)[attr];
  }
}

對於鏈式運動,首先move()函數自己多傳入一個函數參數,在move()函數在在處理好函數體的變化後,假如函數參數有值傳入,則要執行後面的函數體,假如後面的參數還有函數參數,則能夠繼續執行下去,這樣就造成了一條執行鏈。我上面這個列子還有一些問題,當你鼠標移動過快,會產生閃爍。具體學習視頻參考慕課網JS動畫效果.學習

相關文章
相關標籤/搜索