イブニングクラス:純粋なJSに対する爆発効果

今日は、追加のライブラリを使用せずにExplodeエフェクトがどのように実装されるかを分析します。



→デモページ: Explode.js







何をする必要があります:





要素を切り取る



これが最も簡単な部分です。 指定:ブラスト用の特定の要素(テキスト付きの画像やブロックなど)およびセル数N * N N * Nのディーバを作成して配置し、要素のクローンをシフトするサイクルを作成しています。



作業に必要な変数を宣言します。



function Explode( elem, N ) { N = N || 3; var pos = elem.getBoundingClientRect(); var top = pos.top; var left = pos.left; var width = Math.round( elem.clientWidth / N ); var height = Math.round( elem.clientHeight / N ); // [...]
      
      





セルを作成します。



 for ( var i = 0; i < N; i++ ) { for ( var j = 0; j < N; j++ ) { var tile = document.createElement( "DIV" ); document.body.appendChild( tile ); // [...] } }
      
      





セルに必要なスタイルを設定します(このコードは既にループ内にあります)。



 tile.style.position = "fixed"; tile.style.width = width + "px"; tile.style.height = height + "px"; tile.style.top = (top + height * i) + "px"; tile.style.left = (left + width * j) + "px"; //         , //       tile.style.overflow = "hidden";
      
      





次に、各セルに要素のクローンを挿入します。



 var tileContent = elem.cloneNode( true ); tile.appendChild( tileContent );
      
      





次に、すべてのセルのセットが全体像のように見えるように、各セルのクローンを移動する必要があります(各セルには左上隅があります)。



 tileContent.style.marginTop = (-height * i - pos.top) + "px"; tileContent.style.marginLeft = (-width * j - pos.left) + "px";
      
      





つまり セルの高さまでセル番号を垂直にシフトします。 同様に、左にシフトします。 -pos.top-pos.leftは、ウィンドウの端に対して要素がシフトする場合に必要です(ほとんどの場合シフトします)。 これらの値が削除されない場合、セルは空になるか、要素の間違った部分になります-「ネイティブ」インデントも考慮されるためです。



タスクの前半は完了します-画像はセルに「カット」され、各セルは個別に操作できます(つまり、異なる方向にアニメーション化できます)が、同時にユーザーにとって画像は変化しません。



次に、各セルをアニメーション化する方向を決定する必要があります。 つまり 左上が飛んで左に、右のセルがちょうど上に飛んでいる、などです。これにより、「爆発」の効果が生じます。 補助関数の方向(i、j、N)を記述する必要があります。ここで、iとjはセル番号(ループ内)で、Nは縦横のセル数です。



試行番号1



最初は、特定の数字(たとえば、時計回りに0-上、1-上および右など)を返し、そこから方向を決定するというアイデアがありました。 一見すると、これは便利で直感的なように見えましたが、実際には繰り返しスタイルのコードが大量に生成されました。



 function direction (i, j, N) { if ( i == 0 && j == 0 ) return 7; //    if ( i == 0 && j < N - 1 ) return 0; //   if ( i == 0 && j == N - 1 ) return 1; //    // [...]
      
      





これをアニメーション化する方法を想像するのも怖いです。 それぞれの場合にifを書きますか? いいえ、何か他のものが必要です。



この方法には2つの欠点があります。



-かさ高

-まったく正しい値ではありません。 たとえば、N = 5の場合、左上のセルは左上にアニメーション化され、すべてが正しいですが、その右側の次のセルは厳密に上に飛んでいきますが、私は上に少し左に行きたい(しかしそれほどではありません)



試行番号2



2次元配列N * Nを作成し、ゼロで埋め、要素(i、j)を1に設定し、それを「検索」し、配列から1つのレイヤーを再帰的に切り取ります(つまり、5x4配列から4x4配列を作成します)。 明らかなプラスは、ifとかさばるコードのヒープがないことです。 マイナスは同じです-非常に必要な値ではありません。



残念ながら、私は古いソースコードを保存しなかったので、この謎を書きたいとは思いません。したがって、今回はソースの例はありません。



試行3、成功



ベクトル。 これはコンパクトで便利なソリューションであり、「まったく正しくない値」の問題も解決します。 セルが中心からどれだけ離れているかを調べ、特定のベクトル(x、y)を計算し、 xおよびyに基づいて、セルを方向にアニメートします。



 function direction( i, j, N) { return [ (N-1) / 2 - i, j - (N-1) / 2 ] };
      
      





簡単だった...



より明確にするために、 N = 7でセルに与えられる値は次のとおりです。



画像






物事は小さいままです。各セルを特定の方向にアニメーション化します。 ループ本体では、各セルに対して補助関数animateStartを呼び出します。



 animateStart( tile, left + width * j, top + height * i, direction( i, j, N ) );
      
      





ここで、最初の引数はセル自体、2番目と3番目はその初期座標、最後は2つの数値の配列で表されるベクトル(x、y)です。



それでは、animateStart関数の作成を始めましょう。



 function animateStart( elem, posX, posY, dir ) { var vY = dir[0]; //    var vX = dir[1]; //    var start = new Date().getTime(); //    // toX  toY -   // ,      (3, -3),   //       150    //     var toY = posY - 50 * vY; var toX = posX + 50 * vX; setTimeout( animate, 10 ); //   // [...]
      
      





それでは、animate関数を書きましょう。 これがアニメーションの進行です。 10ミリ秒ごとに開始し、セルを方向にわずかに移動します。 したがって、スムーズなアニメーションの効果が作成されます。



 function animate () { //  ,   - 0,   - 1 var m = (new Date().getTime() - start) / 500; if (m > 1) m = 1; elem.style.top = (posY + (toY - posY) * m) + "px"; //   elem.style.left = (posX + (toX - posX) * m) + "px"; //    elem.style.opacity = 1 - m; //     "",   if (m < 1) setTimeout( animate, 10 ); //     1,    }
      
      





最終タッチ:元のアイテムを削除します。



 elem.parentNode.removeChild( elem );
      
      





プラグインの準備ができました! デモページは記事の冒頭にあり、jsソースはこちらです。



All Articles