最新學了一個新的運動函數,與最初學習的有所不同,第一個運動是根據運動速度完成運動 ,第二個則是根據運動的時間來完成運動,而且把之前的函數都進行了一些相容處理,在這裡列出了看一下: 第一種animate1 第二種animate2 總結: animate1中各種運動完成的時間是不一致的,而animate ...
最新學了一個新的運動函數,與最初學習的有所不同,第一個運動是根據運動速度完成運動 ,第二個則是根據運動的時間來完成運動,而且把之前的函數都進行了一些相容處理,在這裡列出了看一下:
第一種animate1
1 function animate1(obj,data,rate,fn){//運動對象,運動數據,[運動速度],[回調函數]
2 //遍歷獲取樣式屬性
3 for(var key in data){
4 //通過閉包將key私有化
5 (function(k){
6 /*
7 獲得樣式寬高等會帶有單位px需要處理掉,
8 如果使用parseInt,當傳入opacity為小數時會變為0,所以使用parseFloat
9 */
10 var cur = parseFloat( (obj.currentStyle || getComputedStyle(obj,null) )[k]);
11
12 //對特殊值進行處理
13 if(k == "opacity"){
14 //透明度當前值和目標值放大100倍,防止小數被捨去
15 cur *= 100;
16 data[k] *= 100;
17 }
18
19 //當前值和目標值相等,直接返回
20 if(cur == data[k]){ return; }
21
22 //通過自身名字定義定時器,解決每個運動共用一個定時器,造成清除其他運動定時器的問題
23 clearInterval(obj[k +'timer']);
24
25 obj[k+'timer'] = setInterval(function(){
26
27 //當前 += (目標-當前)*比率 比率不傳則預設0.2
28 cur += (data[k] - cur) * (rate || 0.2);
29
30 if(Math.round(cur) == data[k]){
31 //如果到達目標值清除定時器,同步數據
32 clearInterval(obj[k+'timer']);
33 cur=data[k];
34
35 //回調,將定時器賦值為0,遍歷每個定時器的值相加,如果所有定時器相加都為0,說明運動已經全部完成,執行回調函數
36 obj[k + "timer"] = 0;
37 var bl = 0;
38 for(var key in data){
39 bl += obj[key + "timer"];
40 }
41 if(bl == 0){
42 //判斷是否傳入回調函數
43 fn && fn.call(obj);
44 }
45 }
46
47 //使用數據時判斷特殊值
48 if(k == "opacity"){
49 //opacity具有相容問題,ie8以下使用filter:alpha(opacity:100)
50 obj.style.opacity = cur / 100;
51 obj.style.filter = "alpha(opacity="+ cur +")";
52 }else{
53 obj.style[k] = cur + "px";
54 }
55 },30)
56 })(key);
57 }
58 }
第二種animate2
function animate2(obj,data,time,fn){//運動對象,運動數據,[運動時間],[回調函數] //保存初始值和變化值 var start = {}; var dis = {}; for(var name in data){ //獲取樣式,根據屬性名保存在json中,{width:200,height:200} start[name] = parseFloat( (obj.currentStyle || getComputedStyle(obj,null) )[name]); //變化值 = 目標值 - 初始值 ----> {width:500,height:300} dis[name] = json[name] - start[name]; } //根據完成的時間獲得運動次數,30為定時器頻率 var count = Math.round((time || 700)/30); //記錄已經運動次數 var n = 0; //將定時器綁定在對象身上,如果不同對象調用不會清除之前的運動 clearInterval(obj.timer); obj.timer = setInterval(function(){ n++; for(var name in data){ //位置:起點 + 距離/次數*n var cur = start[name] + dis[name] / count * n; //對特殊屬性進行判斷 if(name == "opacity"){ obj.style.opacity = cur; obj.style.filter = "alpha(opacity:"+cur*100+")"; } else { obj.style[name] = cur + "px"; } } //如果已經運動次數和總次數相等,則完成運動,清除定時器,執行回調函數 if(n == count){ clearInterval(obj.timer); fn && fn.call(obj); } },30); }
總結:
animate1中各種運動完成的時間是不一致的,而animate2都是在同一時間內完成,
因此,在調用回調函數的時候animate1需要判斷對象中的所有的運動都已經完成,而animate2只要到達運動次數就可以了。
兩個運動函數都能解決正常的動畫效果,並不能說哪個就一定比較好,而且都還有改善的地方,以後學到再繼續完善吧