ストーリーは問題の声明から始まりました。1日でHTML + javascriptを使用して、約30個のオブジェクトでアニメーションバナーを作成する必要があります。 もちろん、日中はバナーは作成されませんでしたが、3人日で2回努力して作成されました。 割り当てを完了した後、バッチアニメーションライブラリが残っており、これをScenarioと名付けました。 その改訂版についてお話したいと思います。
ライブラリの主なアイデアは、1つのスクリプトですべてのアニメーションオブジェクトに関する情報を収集し、実行のために送信することです。 1つのスクリプトは、通常のjavascript構造であるため、必要な回数だけ実行したり、変更したりできます。
どこからでもスクリプトを実行するのは非常に簡単です。
var newScenario = [...]; $.scenario(newScenario, { complete: function(time) { alert('!'); } });
例の3つのポイントの代わりに何を書くべきかを理解するだけです。
シナリオの説明
シナリオは、アニメーション化されたオブジェクトの配列または1つのアニメーション化されたオブジェクトです。 各アニメーションオブジェクトには、3つの主要なプロパティを含めることができます。
- element-このアニメーション化されたオブジェクトを表すHTML要素または複数の要素へのポインター。 千通りの方法でHTML要素を指すことができるので、ここではこのプロパティの詳細な説明を省略します。
- シーン - シーンの配列または単一のシーン。 この場合、シーンとは、開始時間と終了時間を持つアニメーション化されたオブジェクトのアクションを指します。
- child-子オブジェクトの配列または1つの子オブジェクト。
var newScenario = { element: '#scenario', child: [{ element: '.rocket_smile' child: [{ element: '.fire' }, { element: '.eyes' }, { element: '.ears' }] }, { element: '.rocket_atack' child: { element: '.fire' } }, { element: '.cloud', child: [{ element: ['eq', 0] }, { element: ['eq', 1] } }] };
そして今、魔法はシーンオブジェクトの記述です。
- timeは唯一の必須プロパティです。 2つまたは3つの要素の配列。 最初の要素は、スクリプトの開始からカウントされたミリ秒単位のこのシーンの開始時間です。 $ .scenario()関数を呼び出した瞬間から。 2番目は、同じイベントから計算された終了時間です。 シナリオ全体の合計期間は、シーンの最長の終了時間に等しくなります。
3番目のオプション要素は、このシーンに使用されるイージング関数の名前です。 IsingはjQueryから取得されるため、サードパーティのIsing関数は正常に機能するはずです。 - before-アニメーションを開始する前に要素に適用する必要があるcssプロパティを持つオブジェクト、つまり 時間[0]。
- after-アニメーションの完了後に要素に適用する必要があるcssプロパティを持つオブジェクト。 時間[1]。
- animate-アニメーション化されたcssプロパティとその最終値をリストするオブジェクト。 アニメーション要素の現在のcssプロパティが初期値として取得されます。 これまでのところ、数値のみがサポートされています。
- start -beforeプロパティからcssプロパティを適用した直後に、シーンの開始時に呼び出される関数。
- end -afterプロパティからcssプロパティを適用した直後に、シーンが完了した後に呼び出される関数。
- step-アニメーションの各ステップで呼び出される関数で、現在の時間は時間[0]から時間[1]の間です。
scene: [{ time: [2500, 4000], before: { opacity: 0, show: '' }, animate: { opacity: 1 } after: { opacity: '' } }, { time: [5500, 6500], before: { addClass: 'rocket_wink' }, after: { removeClass: 'rocket_wink' } }]
さて、真空中の雲の球形コード:
{ element: '.cloud', child: [{ element: ['eq', 0], time: [0, 7500, 'linear'], before: { top: -80, display: 'block', left: 300 }, animate: { top: 374 } }, { element: ['eq', 1], scene: [{ time: [2500, 5500, 'linear'], before: { top: -80, display: 'block', left: 500 }, animate: { top: 374 } }, { time: [5500, 9000, 'linear'], before: { top: -80, display: 'block', left: 150 }, animate: { top: 374 } }] }] }
.cloud要素にはアニメーションがまったくなく、eq(0)要素にはシーンプロパティは含まれませんが、timeプロパティ、beforeプロパティ、およびanimateプロパティが含まれていることに注意してください。これにより、スクリプトエントリをさらに減らすことができます。
基本原則で十分です。
jQuery.animateですべてを実行してみませんか。 生きている例
字幕の2番目の部分に答えます。 シナリオを使用して作成されたアニメーションの例を用意しました。 この例は、冒頭で説明したバナーに非常に似ていますが、すべてのアイデンティティを切り取り、メインキャラクターを忍者に置き換えました。 さらに、興味を引くために、jQuery.animate(同じもの)に同じバナーを作成しました。
生きている例
そして、これがjQuery.animateがそのようなタスクにあまり適していない理由です:
- アニメーションが終了すると、Animateは完全な関数を呼び出します。 しかし、彼女は開始前に何も電話しません。 この機能のため、キューを使用する必要があります。
.delay(2500) .queue(function(next) { $(this).css({top: 82, left: 74}); next(); }) .animate({top: 85}, 1500)
- Animateは、現在のjQueryオブジェクト内のすべてのHTML要素を互いに独立してアニメーション化します。 各要素について、アニメーションの終了後に、完全な関数が呼び出されます。 step関数は、アニメーションの各ステップで各要素の各プロパティに対して呼び出されます。 これはさらに不便です。
- animateを使用して、一定の時間だけ単純にステップ関数を実行することはできません。 アニメーション化されたプロパティのセットが空の場合、animateはすぐに結果を返します。 ダーティトリックを使用する必要があります。0から0までの値をアニメーション化します。
- アニメーションの多くの出口点。 10個の異なるオブジェクトが完全なイベントで同時にアニメーションを終了する場合、どれが最終的なバナーコードを配置する必要がありますか? どのような場合、10日後にこのコードを完全に探しますか?
対照的に、シナリオには1つの出口点があります;これは$ .scenario()の完全な関数です
// , var $rocket_smile_fire = $rocket_smile.find('.fire'); $rocket_smile_fire // : , .eq(0) // : marginTop 0, .animate({marginTop: 0}, { duration: 9000, step: function(x, opt) { // this, $rocket_smile_fire .hide() // .eq(((new Date() - opt.startTime) / 100) % $rocket_smile_fire.length) .show(); }, complete: function() { $rocket_smile_fire.removeAttr('style'); } });
もちろん、これは悲しいですが、そうでなければ生きることができます...
キラー機能シナリオ
想像してみてください:あなたが作るアニメーションは20秒続きます。 2秒間続く最後のシーンを作成します。 最後の数秒まで、バナーを表示するのにどれだけ時間が無駄になりますか? jQueryの問題を解決する方法は? ほとんどの作業を行うコードをコメントアウトします。 オブジェクトを移動したコードがコメントアウトされているため、すべてのオブジェクトがその場所にあるという事実ではありません。
シナリオのソリューション-シーンを開始する時間と終了する時間を指定するだけです。 まあ、再生速度を設定することができます。 ヒープのフレームレート。
時間を設定する機能を備えた例
デバッグは楽しみです。
スクリプトについてもう少し
アニメーション化された要素オブジェクトの説明とシーンのコールバック関数は、説明なしで残りました。 ギャップを埋めます。 要素は次の値を取ることができます。
- 欠席する場合があります。 この場合、要素は親アニメーションオブジェクトから取得されます。 これを使用して、複数のシーンのプロパティをグループ化できます。
{ element: '.rocket_smile', // scene: { time: [0, 2500, 'easeInOutSine'], animate: { top: 69 } }, // child: { // before: { addClass: 'rocket_wink' }, after: { removeClass: 'rocket_wink' } scene: [{ time: [0, 1000] }, { time: [2000, 3000] }, { time: [4000, 5000] }] } }
- JQueryオブジェクト 。 たとえば、$( '#scene .element');
- DOMオブジェクト たとえば、ドキュメント。
- 文字列 、CSSセレクター。 親要素のfind()メソッド、または親要素が欠落している場合は$()関数に渡されます。
- 配列 最初の要素は、親要素のメソッドの名前です:find、eq、parentなど。 2番目以降の要素は、このメソッドの引数です。
element: ['eq', 0]
$parent.eq(0)
element: ['eq', 0]
同等です。
最初の要素がfalseの場合、親要素は無視され、引数は$()関数に渡されます。
element: [false, 'input[name="name"]']
$('input[name="name"]')
element: [false, 'input[name="name"]']
同等です。
- アイテムを返す関数 。 関数のパラメーターを介して、親要素が渡されます。
開始、終了、およびステップコールバック関数は、見つかった要素のコンテキストで実行されます。 3つすべてが取る最初の引数は、スクリプトの開始からの経過時間です。 Last-アニメーションオブジェクトによって展開された現在のシーンのオブジェクト:
{ element: '.rocket_smile', button: $('#start-button'), scene: { time: [0, 2500], fadeDuration: 400, start: function(time, scene) { // scene.fadeDuration // scene.button scene.button.fadeOut(scene.fadeDuration); }, animate: { top: 69 } }, }
ステップコールバック関数は、これらの2つのパラメーターに加えて、現在のアニメーションステップに関する詳細情報を持つ別のパラメーターを受け入れます。
-time、スクリプトの開始からの時間。
- 経過 、シーンの開始からの時間。
- 進行 、シーンの開始からの時間、間隔0..1に正規化。
- 位置 、これはイジング関数を適用した後の進捗です。
{ element: '.rocket_atack', scene: { before: { top: 20 }, // , step lastTop: 300, step: function(time, opt, scene) { // var startTop = scene.before.top; // var changeTop = scene.lastTop - startTop; // this — this.css({top: startTop + changeTop * opt.position}); } } }
Githubシナリオコード
今後の計画
- スクリプトを簡単に変更する方法を考えてください。 現在、CSS変換をサポートしており、CSS変換をサポートしていないブラウザーのさまざまなシーンを作成するには、配列内のインデックスによってオブジェクトとシーンを抽出することによって苦しむ必要があります。
- アニメーション化されたプロパティを指定するより柔軟な方法を実装します。 少なくとも記号とピクセル以外の単位を持つ値:
var scene = { before: { top: '20%' }, animate: { top: '40%', left: '+=200px' } }
- タイムライン、レイヤー、フィルターを備えたビジュアルエディターを開発し、WebからFlashをプッシュします。