国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Javascript動畫效果(3)

2019-11-20 08:46:43
字體:
來源:轉載
供稿:網友

前面我們已經介紹了速度動畫、透明度動畫、多物體運動和任意值變化,并且我們在Javascript動畫效果(二)中介紹到我們封裝了一個簡單的插件雛形,接下來我們對前面的動畫效果進行進一步擴充,盡量將我們的框架做到更實用。在這里我們還需要了解兩個運動,一個是鏈式運動,一個是同時運動。它們間的區別分別是:鏈式運動是指運動一個接著一個(一個運動完成馬上進行下一個運動);而同時運動是指所有的運動同時進行。在這里,我們該如何實現呢?

1、鏈式運動

  前面的效果中,我們已經能對任意值進行相應的變化,我們該如何在一個動畫后添加一個動畫呢?

  思路:我們能不能在參數中傳入一個函數,當一個效果完成后馬上執行后面的函數(效果),該函數可以是想要的動畫效果

  實現:在function startMove(obj,attr,iTarget)中在傳入一個參數fn,代表一個函數。這時我們還需要修改的有在定時器的后面增加一個判斷if(fn){fn(); },當存在fn函數時執行fn函數,當不存在fn函數時清除定時器。這樣我們的window.onload函數也應該發生相應變化,代碼如下:

window.onload = function() {  var Li = document.getElementById('li1');  Li.onmouseover = function() {    startMove(Li, 'width', 400, function() {      startMove(Li, 'height', 200, function() {        startMove(Li, 'opacity', 100);      });    });  };  Li.onmouseout = function() {    startMove(Li, 'opacity', 30, function() {      startMove(Li, 'height', 100, function() {        startMove(Li, 'width', 200);      });    });  };};

所以我們得到鏈式運動的如下代碼:

<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title>鏈式運動</title>    <style type="text/css">      body,ul,li{ margin: 0px; padding: 0px; }      ul,li{ list-style: none; }      ul li{ width: 200px; height: 100px; background: yellow; margin-bottom: 20px; border: 4px solid #000; filter:alpha(opacity:30); opacity:0.3; }    </style>       </head>  <body>    <ul>      <li id="li1"></li>    </ul>    <script type="text/javascript">      window.onload = function(){        var Li = document.getElementById('li1');        Li.onmouseover = function(){          startMove(Li,'width',400,function(){            startMove(Li,'height',200,function(){              startMove(Li,'opacity',100);            });          });        };        Li.onmouseout = function(){          startMove(Li,'opacity',30,function(){            startMove(Li,'height',100,function(){              startMove(Li,'width',200);            });          });        };      };           function startMove(obj,attr,iTarget,fn){        clearInterval(obj.timer);        obj.timer = setInterval(function(){          var icur = 0;          if(attr == 'opacity'){            icur = Math.round(parseFloat(getStyle(obj,attr))*100);          }else{            icur = parseInt(getStyle(obj,attr));          }          var speed = (iTarget - icur)/10;          speed = speed>0?Math.ceil(speed):Math.floor(speed);          if(iTarget == icur){            clearInterval(obj.timer);            if(fn){              fn();            }          }          else{            if(attr == 'opacity'){              obj.style.filter = 'alpha(opacity:'+(icur+speed)+')';              obj.style.opacity = (icur+speed)/100;            }            else{              obj.style[attr] = icur+speed+'px';            }          }        },30)      }                function getStyle(obj,attr){        if(obj.currentStyle){          return obj.currentStyle[attr];        }        else{          return getComputedStyle(obj,false)[attr];        }      }    </script>  </body></html>

2、同時運動

說到同時運動,你可能會覺得很簡單,直接在onmouseover事件后面同時添加兩個不同的starMove()函數就可以解決了(錯誤思路!),實際上并不是這樣的,當有多個效果時,我們看到的是最后添加的那個效果。也就是說我們想同時改變寬度和高度(高度在后),我們得到的效果為只改變高度,寬度并沒有變化。這里我們應該繼續傳參數么?從鏈式運動來看,傳參數的效果只能在后面添加函數得到連續的動畫效果。

  思路:我們可不可以用JSON的方法來同時改變多個動畫效果?

  實現:將function startMove(obj,attr,iTarget,fn)中的attr和iTarget合并為一個參數:json,我們用for/in的方法來遍歷json中的數據,例如:

var json = {"a":12,"b":21};for(var attr in json){  alert(json);//結果分別是:a,b  alert(json[attr]);//結果分別是:12,21}

 按照此方法,我們依次改變前面的代碼:在定時器函數的后面加上代碼:for(var attr in json) {...},并且修改里面的iTarget為json[attr],再將window.onload函數修改為:

window.onload = function() {  var Li = document.getElementById('li1');  Li.onmouseover = function() {    startMove(Li, {      width: 400,      height: 200,      opacity: 100    });  };  Li.onmouseout = function() {    startMove(Li, {      width: 200,      height: 100,      opacity: 30    });  };};

 這時我們差不多就可以得到我們想要的效果了,但是這樣離我們最終的效果還是查了那么一點點,比如說我們將onmouseover事件中的starMove中的width修改為202,再執行我們的代碼,我們會發現最終的height不是200px,opacity也不是100,如圖:

這樣就很尷尬了,之前我們的效果不是還蠻好的么?我們再回到我們的JS代碼中分析結構,覺得最有可能出錯的就是starMove函數中,我們發現這段代碼的意思有點難理解:

if(json[attr] == icur) {  clearInterval(obj.timer);  if(fn) {    fn();  }}

我們并不知道是不是所有的運動都到達終點時停止所有運動還是當只有一個運動達到終點時立馬停止所有運動。但是通過我們前面的操作,可以知道的實際結果為,只有一個運動到達終點值時,所有的運動都停止了(此時還有運動沒執行完),我們該如何進行操作呢?

  思路:我們可以假定一個參數flag,并且賦值為true,在執行clearInterval(obj.timer);操作前我們先進行判斷if(json[attr] != icur) { flag = false;},后面執行之前else里面的語句,再執行如下語句if(flag = true) {clearInterval(obj.timer); if(fn) {fn();}},這樣我們就可以得到同時運動的完整代碼如下:

<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title>鏈式運動</title>    <style type="text/css">      body,ul,li{ margin: 0px; padding: 0px; }      ul,li{ list-style: none; }      ul li{ width: 200px; height: 100px; background: yellow; margin-bottom: 20px; border: 4px solid #000; filter:alpha(opacity:30); opacity:0.3; }    </style>       </head>  <body>    <ul>      <li id="li1"></li>    </ul>     <script type="text/javascript">      window.onload = function(){        var Li = document.getElementById('li1');        Li.onmouseover = function(){          startMove(Li,{width:202,height:200,opacity:100});        };        Li.onmouseout = function(){          startMove(Li,{width:200,height:100,opacity:30});        };      };             function getStyle(obj, attr) {        if(obj.currentStyle) {          return obj.currentStyle[attr];        } else {          return getComputedStyle(obj, false)[attr];        }      }             function startMove(obj, json, fn) {        //定義標桿        var flag = true; //假設的               clearInterval(obj.timer);        obj.timer = setInterval(function() {          for(var attr in json) {            var icur = 0;            if(attr == 'opacity') {              icur = Math.round(parseFloat(getStyle(obj, attr)) * 100);            } else {              icur = parseInt(getStyle(obj, attr));            }            var speed = (json[attr] - icur) / 10;            speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);            if(json[attr] != icur) {              flag = false;            }            if(attr == 'opacity') {//判斷是否為opacity              obj.style.filter = 'alpha(opacity:' + (icur + speed) + ')';              obj.style.opacity = (icur + speed) / 100;            } else {              obj.style[attr] = icur + speed + 'px';            }            if(flag){              clearInterval(obj.timer);              if(fn){                fn();              }            }           }        }, 30)      }    </script>  </body></html>

 這樣我們的同時運動的動畫效果就實現了。在這里,你有沒有覺得很神奇?

在這里我們已經將一個簡單的運動插件封裝完成了,我們將里面的代碼做一些解釋,并且將它保存為一個foodoir.animate.js文件,代碼如下:

/* * 簡單的運動框架 * 作者:foodoir * 此框架僅作參考!!! * * 使用方法見博文 */ function getStyle(obj, attr) {  if(obj.currentStyle) {    return obj.currentStyle[attr];  } else {    return getComputedStyle(obj, false)[attr];  }} function startMove(obj, json, fn) {   clearInterval(obj.timer); //清除定時器,避免重復生成多個定時器  obj.timer = setInterval(function() {    var flag = true; //假設剛開始時所有運動都已完成    for(var attr in json) { //遍歷json       var icur = null;      //1.判斷類型      if(attr == 'opacity') {        icur = Math.round(parseFloat(getStyle(obj, attr)) * 100);      } else {        icur = parseInt(getStyle(obj, attr));      }      //2.算速度      var speed = (json[attr] - icur) / 5;      speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);      //3.檢測停止      if(icur != json[attr]) {        flag = false;      }      if(attr == 'opacity') {        obj.style.filter = 'alpha(opacity:' + (icur + speed) + ')';        obj.style.opacity = (icur + speed) / 100;      } else {        obj.style[attr] = icur + speed + 'px';      }    }    if(flag) { //當所有運動都完成時,清除定時器      clearInterval(obj.timer);      if(fn) {        fn();      }    }  }, 30);}

 后面,我們將介紹用自己的框架來實現多種動畫效果,并且和jquery中的動畫效果進行比較。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 梁山县| 双峰县| 元氏县| 河津市| 调兵山市| 德格县| 墨竹工卡县| 石城县| 华坪县| 包头市| 祁门县| 兴业县| 安多县| 海林市| 嫩江县| 武冈市| 桑日县| 华阴市| 日喀则市| 商河县| 蚌埠市| 广昌县| 浦东新区| 沂南县| 共和县| 丘北县| 金门县| 渭源县| 洛阳市| 台中市| 双流县| 宁安市| 长岛县| 芦山县| 门源| 晋州市| 彩票| 瑞丽市| 安化县| 静安区| 余庆县|