イブニングクラス:純粋な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ソースはこちらです。

Source: https://habr.com/ru/post/J321570/


All Articles