→デモページ: Explode.js
何をする必要があります:
- 要素をN * N個のセルに切り取る
- 各セルに「爆発」要素のコピーを配置します
- 各セルのマージンをシフトする
- 各セルを正しい方向にアニメートする
要素を切り取る
これが最も簡単な部分です。 指定:ブラスト用の特定の要素(テキスト付きの画像やブロックなど)およびセル数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ソースはこちらです。