クラシックアニメーション
彼は古典的なアニメーション機能に最初にすべての、と言ってあまり話をしませんでした。
function animate(element, name, from, to, time) {
time = time || 800; //默认0.8秒
var style = element.style,
latency = 60, // 每60ms一次变化
count = time / latency, //变化的次数
step = Math.round((to - from) / count), //每一步的变化量
now = from;
function go() {
count--;
now = count ? now + step : to;
style[name] = now + 'px';
if (count) {
setTimeout(go, latency);
}
}
style[name] = from + 'px';
setTimeout(go, latency);
}
かかわらず、この関数の設計の制限のため、唯一のスタイルを変更するために、ユニットとしてPXできるよう。専用ビューのファンクションポイントの実装から、これは非常に古典的なアニメーションのアイデアすることができ、基本的なロジックは、以下のコンポーネントで構成されています。
- 起点値取得
from
及び終了値をto
アニメーションするために必要な時間によってtime
、及び調査の各インターバルのためlatency
に必要な、計算された値の変化の数count
および各変化の量step
。 - 開き、
setTimeout(fn, latency);
次の調査にステッピングします。 - 次回の調査では、アニメーションが終わっていない場合は、次の調査を継続し、ステップ2に戻って、ステップたら、プロパティを設定します。
この機能は、非常にうまく機能し、サイトやシステムの数十万人を務め、コアjQueryのアニメーション機能が実際にしたsetInterval機能以外の何ものでもありません。
アニメーションの流暢さにもいくつかの問題になります上記の機能につながるより多くの注意、してきたがしかし、現在のシステムの複雑さが着実に増加して、より多くの、アニメーション。例えば100アニメーションを開いている間は、上記機能によれば、タイマは、これらのタイマーの間の演奏スケジュールに若干の影響を実行している間100が存在するであろうことは明らかです。通常の環境では、これらの約束の影響は何の関係もありませんが、この映画の中で流暢環境のための非常に高い要求を持っていますが、わずかな衝撃が悪いユーザ体験を生成することができます。
この場合、一部の開発者は、あるフレームの一元管理に基づいてアニメーションフレームワークを発明し、彼はアニメーションフレームをトリガーするタイマーを使用して、これらのフレームを登録するためのさまざまなアニメーションは、各フレームに複数のアニメーションを扱いますプロパティの変更。これは、タイマースケジューリングオーバーヘッドを減少させるという利点を有するが、フレーム、フレーム統合管理をアニメーション、開発者、APIの監視フレームを提供するため、開発、維持するために必要とされています。
ダイレクトブラウザのサポート
最終的には、ブラウザのメーカーは、それが実際にそれらによって行うことができ、およびブラウザベースのレベルは、次のようなより多くの最適化を、持つことができることを見出しました。
- DOMのすべての操作の調査、および一度だけのレイアウト塗料用。
- アニメーション要素が発生隠されている場合は、ペイントを行っていません。
だから、私たちが呼ばれ、ブラウザのAPIを立ち上げrequestAnimationFrame
、この機能のために、MDC関連ページが簡単な言葉で、より詳細な説明があり、この機能は使用の2種類があります。
- コール
requestAnimationFrame
コールバックパラメータ、アニメーションは、コールバックを呼び出し、その後、次のフレームを渡し、関数。 - パラメータは、直接、関数を呼び出して、次のフレームがトリガーされたときにアニメーションフレームを開始し、また、トリガーされます合格しない
window.onmozbeforepaint
イベントを登録することで、イベントをアニメーション化することができます。
第二の方法は、Firefox上で独自のイベントを依存しているように、及びbeforepaint
イベントが基準に入らなかった、それが推奨されていないか、最初の方法の使用が優れています。この時点で、我々はそうアニメーションのロジックになることができます。
- 現在の時刻を記録し
startTime
、アニメーションの始まりとしての時間を。 - 次のフレームを要求し、コールバック関数を取ります。
- 次のフレームがトリガされると、コールバック関数は、現在の時間の最初のパラメータであり、次いで、
startTime
所定の時間間隔とを比較しますellapseTime
。 - 裁判官は、
ellapseTime
予め設定されたアニメーション時間を超えたtime
超えた場合には、映画が終了し、。 - 変更のアニメーションプロパティの間の差を計算
differ = to - from
し、その後に決定ellapseTime
変更する必要がありますどのくらいの時間step = differ / time * ellapseTime
。 - 位置の計算では変更のように見える
Math.round(from + step)
、とスタイルに再割り当て。 - 次のフレームを要求し続けます。
新しいアニメーション機能
ここでは、ブランドの新しいアニメーション機能は次のとおりです。
function animate(element, name, from, to, time) {
time = time || 800; // 默认0.8秒
var style = element.style,
startTime = new Date;
function go(timestamp) {
var progress = timestamp - startTime;
if (progress >= duration) {
style[name] = to + 'px';
return;
}
var now = (to - from) * (progress / duration);
style[name] = now.toFixed() + 'px';
requestAnimationFrame(go);
}
style[name] = from + 'px';
requestAnimationFrame(go);
}
この時点で、私がいないすべてのブラウザがサポートしている問題が残されrequestAnimationFrame
た機能を、そう簡単な修正を行います。
Firefoxのビューの特性に応じてmozRequestAnimationFrame
60 FPSのための最高の提供、及び各フレームが1秒を使用して計算されるような、各フレームの時間のかかる計算に基づいて調整され、彼はアニメーション1FPSを提供することであろう。
クロームの高いバージョンは、この関数が呼び出された実現webkitRequestAnimationFrame
私たちはオペラがあるだろう未来を予見することができ、oRequestAnimationFrame
かつIE msRequestAnimationFrame
互換性の単純なプロセスを実行するために一緒にので、ここで:
requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
function(callback) { setTimeout(callback, 1000 / 60); };
参考資料
この記事パーマネントアドレス:http://www.otakustay.com/animation-and-requestanimationframe/
ます。https://www.cnblogs.com/GrayZhang/archive/2011/04/18/animation-and-requestanimationframe.htmlで再現