JavaScript完璧な運動枠組みの階段を進む旅

11227 ワード

ガイド:
運動フレームの実現構想運動は、つまり、left、right、width、height、opacityの値を一定期間で変えて目的地に到達したら停止します.今は以下の手順で運動フレームのパッケージを行います.均等運動、緩衝運動、多物体運動、任意の値の変化.
フレームワークの実現構想
  ,            left、right、width、height、opacity  ,         。
今は以下の手順で運動フレームのパッケージを行います.均等運動、緩衝運動、多物体運動、任意の値の変化.
(一)定速運動速度動画運動の基礎
どうやってdivを動かすか?
元素の絶対位置を設定します.絶対位置を決めた後に、left、top等値だけ有効になります.タイマーの使用(動的変更値)は、ここでset Interval()を使用して指定時間ごとにコードを実行します.タイマーset Interval(関数、インタラクティブ時間(ミリ秒):実行時に、ページをロードした後、指定された時間ごとにコードを実行します.タイマーclear Intervalをキャンセルする方法は、set Interval()によって設定されたインタラクション時間をキャンセルすることができます.現在の位置、サイズなどを取得します.offset Left(現在の要素は親要素の位置に対して)速度とは、物体が動くスピードタイマーの間隔で、値の大きさを変えます.上記の情報によって、私達はパッケージ運動フレームを開始し、変化したdivを作成することができます.
1.  /** 
2.  *     -1-   
3. *@param {HTMLElement} element        
4.  * /
5.  var timer = null;
6.  function startMove(element){
7.     timer = setInterval( function () { //          
8.            element.style.left = element.offsetLeft + 5 + "px;
9.      },30);
10. }
あなたは見間違えていません.そんなに簡単です.でも待ってください.どうして止まらないですか?WTRF私たちは運動終了条件がないからです.幸い、まだ比較的簡単です.間はタイマーの内部にあり、目標値に達すると判断し、タイマーをクリアすればいいです.
1.  /** 
2.  *     -2-    
3.  *@param {HTMLElement} element        
4.  *@param {number}    iTarget       
5.  */
6.  var timer = null;
7. function startMove( element, iTarget) {
8.      timer = setInterval ( function ( ) {
9.          element.style.left = element.offsetLeft + 5 + "px";
10.        if (element.offsetLeft ===iTarget) { //     
11.              clearInterval ( timer );
12.         }; 
13.     }, 30);
14.  }
これで完成ですか?まだいくつかのバグがあります.
運動中のバグ
速度はいくつかの値を取ると停止できなくなります.位置に着いたらクリックしても繰り返しクリックして速度を上げます.変更できません.
バグを解決する
速度はいくつかの値を取ったら止まらないです.(このBugは後で解決します.進化の過程で自然に解決します.)運動と停止を分離します.運動を開始する時、すでにタイマーを閉じて速度を変数に保存します.
1.  /**
2.  *     ‐3‐  Bug
3.  */
4. vartimer=null;
5.  function startMove ( element , iTarget ) {
6.      clearInterval ( timer ) ; //             
7.      timer = setInterval ( function ( ) {
8.            var iSpeed = 5 ;//        
9.            //         ( if / else )
10.          if (element.offsetLeft == iTarget ) { //     
11.                clearInterval ( timer );
12.           } else {
13.                element.style.left = element.offsetLeft + iSpeed + "px";
14.            };
15.     } , 30);
16. }
このように簡単な運動フレームが完成しました.でも、もうちょっと待ってください.右に行くしかないですか急がないでください.速度を変数に変えるという定義をしたのではないですか?それをいくつか処理するだけでいいです.var i Speed=5
1.  //         ,          
2.  var iSpeed = 0 ;
3.  if (element.offsetLeft < iTarget) {
4.      iSpeed = 5 ;
5.  } else {
6.      iSpeed = -5;
7.  };
透明アニメーション
変数アルファで現在の透明度を保存します.上のelement.offset Leftを変数alphaに変更します.運動と停止条件の部分を変更します.以下のとおりです
1.  //           
2.  if ( alpha === iTarget ) {
3.       clearInterval ( timer ) ;
4.  } else {
5.        alpha += speed;
6.        element.style.filter = 'alpha(opacity:'  + alpha + ')' ; //   IE
7.        element.style.opacity = alpha / 100; //   
8.   }
(二)動画のバッファリング
考えてみます.どうすれば緩衝動画になりますか?以下の点があるべきです.徐々に遅くなります.最後の停止距離が遠ければ長いほど速度が大きくなります.距離によって速度が決定されます.Math.ceir(iSpeed)を下に向けて整理します.Math.flor(iSpeed)はやはりスピードに対して文章を書きます.
1.   /**
2.   *     -4-    
3.   */
4.   functionstartMove ( element,iTarget ) {
5.        clearInterval ( timer );
6.        timer = setInterval ( function ( ) {
7.        //          ,          
8.               var iSpeed = ( iTarget - element.offsetLeft ) / 10; // (    -    ) /      =   
9.               ISpeed = ISpeed  > 0 ? Math.ceil ( iSpeed ) : Math.floor ( iSpeed ) ; //     
10.             if (element.offsetLeft === iTarget ) //     
11.                    clearInterval ( timer ) ;
12.              } else {
13.                      element.style.left = element.offsetLeft + iSpeed + "px";
14.              }
15.        }, 30);
16.  }
ここまで来たら、このバグは自動的に解決されます.例:バッファメニューがページに沿ってスクロールするバッファサイドバーの潜在的な問題目標値が整数でない場合
(三)多物体運動
思考:どのように多物体運動を実現しますか?タイマーに問題があります.各divのタイマーはオブジェクトの属性として直接にelement.timerを使ってタイマーをオブジェクトの一つの属性にします.パラメータの伝達:物体/目標値は簡単です.上のフレームを以下のように変更します.
(四)任意の値の変化
咳を吐く.私たちはdivに1 pxの枠を追加します.boder:1 px sold〓〓の後で下のコードを試しにきます.
1.  setInterval ( function() {
2.      oDiv.style.width=oDiv.offsetWidth‐1+"px";
3.  },30)
えっと、不思議なことが起こりました.what私が設定したのは幅が減っているのではないですか?どうしてナイマが増えましたか?いいえ、大兄弟です.いったいどこで問題が起きましたか?一緒に資料を探して、文書を見てみます.もともとオフセットという一連の属性が存在し、他の属性に邪魔されている問題があります.はい、使えないなら、ついでに任意の値を変えてみましょう.
ステップ1:実際のスタイルを取得する
offset Left.などを使ってスタイルを取得する場合、枠やpaddingなどの要素幅の高さを変更できる属性が設定されているとBUGが発生します.検索により、element.currentStyle(atr)は計算後の属性を取得できます.しかし、互換性の問題で、get Style関数をカプセル化する必要があります.(悪いIE)CSSのbox-sizing属性に合わせてborder-boxとして同じ効果がありますか?(自己主張、未検証)
1.   /**
2.    *         
3.    * @param {HTMLElement} element         html  
4.    * @param {String]}attr           
5.    * @returns {String}            
6.    */
7.    functiongetStyle(element,attr){
8.        //IE  
9.        if ( element.currentStyle ) { 
10.            return element.currentStyle[attr];
11.      //   
12.      } else {
13.            return getComputedStyle ( element , false ) [attr]; 
14.       }
15.   }
第二ステップ:元の関数を改造する
パラメータを追加して、atrは変更が必要な属性値を表します.element.offset Leftはget Styleです.get Style(element,atr)は直接使用できません.これは取得した文字列、例:10 pxです.変数iCurrrentはパーrseInt()を使用して、スタイルを数値に変換します.element.style.leftはelement.style[atr]です.
1.   /**
2.    *     ‐4‐     
3.    * @param {HTMLElement} element        
4.    *@param{string} attr        。
5.    * @param {number} iTarget      
6.    */
7.    functionstartMove ( element , attr , iTarget ) { 
8.         clearInterval(element.timer);
9.         element.timer = setInterval ( function ( ) {
10.              //         ,          
11.       variCurrent=0;
12.       iCurrent=parseInt(getStyle(element,attr));//      
13.             variSpeed=(iTarget‐iCurrent)/10;//(   ‐   )/    =  
14.             iSpeed=iSpeed>0?Math.ceil(iSpeed):Math.floor(iSpeed);//    
15.             if(iCurrent===iTarget){//    
16.                    clearInterval(element.timer);
17.              } else {
18.                      element.style[attr]=iCurrent+iSpeed+"px";
19.              };
20.         },30);
21.    };
試してみてください.これでいいですか?上に書いた透明度の変化を覚えていますか?もう一度試してみたらだめです.(ナンセンス、透明度のある「px」単位を見たことがありますか?--白眼視)
ステップ3:透明度互換処理
思考:これらの属性を修正する必要がありますか?atrが透明度属性のopacityかどうかを判断します.速度に対して処理を行う.透明度の場合は、取得した透明度が小数点以下となるため、*100が必要であり、また、コンピュータの浮動小数点の問題により、小数点以下を四捨五入して整数とする必要があります.使用:Math.round(parseFloat)*100.さもないと、デフォルトの速度を使い続けます.結果出力部分を変更します.透明度の属性を判断し、透明度の方法を使用しない場合は、デフォルトの出力形式を使用します.
1.   /**
2.    *     ‐5‐     
3.    * @param {HTMLElement} element        
4.    *@param{string} attr        。
5.    * @param {number} iTarget      
6.    */
7.    function  startMove ( element , attr , iTarget ) {
8.          clearInterval ( element.timer );
9.          element.timer = setInterval ( function ( ) {
10.              //         ,          
11.              var iCurrent=0;
12.              if ( attr === "opacity" ){//       。
13.                    iCurrent = Math.round ( parseFloat ( getStyle ( element , attr ) ) * 100 );
14.              } else { //    
15.                    iCurrent=parseInt(getStyle(element,attr));//       }
16.              variSpeed=(iTarget‐iCurrent)/10;//(   ‐   )/    =  
17.              iSpeed=iSpeed>0?Math.ceil(iSpeed):Math.floor(iSpeed);//    
18.              if(iCurrent===iTarget){//    
19.                    clearInterval(element.timer);
20.               } else {
21.                      if ( attr==="opacity"){//     ,  
22.                          element.style.filter="alpha(opacity:"+(iCurrent+iSpeed)+")";//IE
23.                          element.style.opacity=(iCurrent+iSpeed)/100;//  
24.                      }else{//  
25.                          element.style [ attr ] =iCurrent+iSpeed+"px";
26.                      }
27.                  }
28.              },30);
29.     }
ここでは、この動きの枠組みはほぼ完成しました.しかし、私たちは完璧を求めるのではないですか?進化し続ける
(五)チェーン動画
チェーンアニメ:その名の通り、この運動が止まった時に次の運動が始まります.どうやって実現しますかコールバック関数を使用します.動きが停止した場合、実行関数にfuncイメージ参(コールバック関数)を追加します.現在の属性が目的地に到達した場合、iCurrrent==iTargetは、コールバック関数が存在するかどうかを判定し、実行します.if(iCurrrent==iTarget){/終了運動clear Interval(element.timer);if(func){func()//フィードバック関数}good、チェーン動画が完成!完璧まであと一歩!
(六)同時運動
どうやって同時運動を実現しますか?JSONを使用して複数の値を転送し、for inサイクルを使用して、属性と値を巡回します.タイマーの問題(運動前停止)サイクル外で変数を設定し、すべての値が目標値に達したと仮定して、サイクル中に目標値に到達したかどうかを検出し、値がない場合はfalseになります.サイクル終了後、目標値に到達したかどうかを検出します.はい、タイマーを消去します.atrとiTargetの2つの形を削除して、Jsonに変更します.関数開始時にマークvar flargag/trueを設定します.すべての動きが終点に到達すると仮定します.タイマー内でfor inを使用して、属性と目標を遍歴して、元のatrとiTargetを書き換えて、jsonの属性と値のために運動終了条件を修正します.各項目の実際の属性値iCurentだけあって、目標値json[atr]に等しい時、flargはtrueです.タイマーをクリアして、折り返しがあるかどうかを判断します.そうでなければ、すべての属性値が目標値に等しくなるまでコードを実行し続けます.完璧な運動フレーム
1.  /**
2.  *         
3.  *@param {HTMLElement} element         html  
4.  *@param {String]}attr           
5.  * @returns {String}            
6.  */
7.  function getStyle(element,attr){
8.    //IE  
9.    if ( element.currentStyle ) {
10.      return element.currentStyle[attr];
11.      //  
12.      } else {
13.          return getComputedStyle(element,false)[attr];
14.      }
15.  }
16.  /**
17.  *       
18.  *@param{HTMLElement}element     
19.  *@param{JSON}  json   :   
20.  * @property{String}attr    
21.  * @config {Number}target    
22.  *@param{function} func   ,    ,    。
23.  */
24.  function startMove ( element , json , func ) {
25.    var flag=true;//          .
26.    clearInterval(element.timer);
27.    element.timer=setInterval(function(){
28.       for(var attr in json){
29.       //1.       。
30.       var iCurrent=0;
31.       if(attr==="opacity"){//       。
32.          iCurrent=Math.round(parseFloat(getStyle(element,attr))*100);
33.        }else{//    
34.           iCurrent=parseInt(getStyle(element,attr));//      
35.        }
36.        //2.     ,      
37.        var iSpeed=(json[attr]‐iCurrent)/10;//(   ‐   )/    =  
38.        iSpeed=iSpeed>0?Math.ceil(iSpeed):Math.floor(iSpeed);//    
39.        //3.       ,    
40.        if(iCurrent!=json[attr]){
41.           flag=false;//    
42.           if(attr==="opacity"){//     ,  
43.              element.style.filter="alpha(opacity:"+(iCurrent+iSpeed)+")";//IE
44.              element.style.opacity=(iCurrent+iSpeed)/100;//  
45.            }else{//  
46.                element.style[attr]=iCurrent+iSpeed+"px";
47.            }
48.        }else{
49.            flag=true;
50.        }
51.        //4.     ,    
52.        if(flag){
53.           clearInterval(element.timer);
54.           if(func){
55.               func();
56.           }
57.         }
58.       }
59.     },30);
60.   }
フレームワークまとめ
フレームの進化過程
フレーム
変化
statrMove(element)
運動する
startMove(element,iTarget)
定速-->バッファ-->多物体
startMove(element,atr,iTarget)
任意の値
startMove(element,atr,iTarget,func)
チェーン運動
startMove(element,json,func)
多値(同時)>>完璧な運動フレーム
この文章は-愛思資源ネットから転换して、転載して出所を明記して、ありがとうございます.