ホームページ  >  記事  >  ウェブフロントエンド  >  Javascript アニメーションの実装原則の簡単な分析_JavaScript スキル

Javascript アニメーションの実装原則の簡単な分析_JavaScript スキル

WBOY
WBOYオリジナル
2016-05-16 16:11:451122ブラウズ

次のようなアニメーション機能要件があるとします。div の幅を 100px から 200px に変更します。書かれたコードは次のようになります:

コードをコピー コードは次のとおりです:


function animate1(要素, endValue, 継続時間) {
var startTime = new Date(),
startValue = parseInt(element.style.width),
ステップ = 1;

var timerId = setInterval(function() {
var nextValue = parseInt(element.style.width) step;
element.style.width = nextValue 'px';
If (nextValue >= endValue) {
clearInterval(timerId);
// アニメーションの表示に時間がかかります
element.innerHTML = 新しい日付 - startTime;
}
}, 期間 / (endValue - startValue) * ステップ);
}

animate1(document.getElementById('test1'), 200, 1000);


原則として、200px に達するまで一定の間隔で 1px ずつ増やしていきます。ただし、アニメーション終了後の表示時間は1秒以上(通常1.5秒程度)かかります。その理由は、setInterval が厳密に実行間隔を保証するものではないためです。

もっと良い方法はありますか?小学校の算数の問題を見てみましょう:

コードをコピー コードは次のとおりです:

建物 A と建物 B は 100 メートル離れています。ある人が建物 A から建物 B まで一定の速度で歩き、目的地に到着するまで 3 分で建物 A からどのくらい離れていますか。

等速運動のある瞬間の距離を求める計算式は、「距離 * 現在時刻 / 時刻」です。したがって、答えは 100 * 3 / 5 = 60 となるはずです。

この質問によってもたらされたインスピレーションは、特定の瞬間における距離が特定の公式によって計算できるということです。同様に、アニメーション プロセス中の特定の瞬間の値も、累積する代わりに数式を使用して計算できます。

コードをコピーします コードは次のとおりです:


function animate2(要素, endValue, 継続時間) {
var startTime = new Date(),
startValue = parseInt(element.style.width);

var timerId = setInterval(function() {
var パーセント = (新しい日付 - 開始時刻) / 期間;

var stepValue = startValue (endValue - startValue) * パーセント;
element.style.width = stepValue 'px';

if (パーセンテージ >= 1) {
clearInterval(timerId);
element.innerHTML = 新しい日付 - startTime;
}
}, 13);
}

animate2(document.getElementById('test2'), 200, 1000);

この改善により、アニメーションの実行時間の誤差は最大でも 10 ミリ秒にとどまることがわかります。しかし、問題は完全には解決されていません。ブラウザ開発ツールで test2 要素を確認すると、test2 の最終的な幅が 200px を超える可能性があることがわかります。 animate2 関数のコードを注意深く調べると、次のことがわかります。

1.percentage の値は 1 より大きい場合がありますが、これは Math.min を通じて最大値を制限することで解決できます。
2. パーセンテージの値が 1 を超えないことが保証されている場合でも、endValue または startValue が 10 進数である限り、(endValue - startValue) * パーセンテージの値ではエラーが発生する可能性があります。これは、Javascript の 10 進数演算の精度が低いためです。足りない。実際、確認したいのは最終値の精度なので、パーセンテージが 1 の場合は、endValue を直接使用します。

したがって、animate2 関数のコードは次のように変更されます:

コードをコピー コードは次のとおりです:

function animate2(要素, endValue, 継続時間) {
var startTime = new Date(),
startValue = parseInt(element.style.width);

var timerId = setInterval(function() {
// パーセンテージが 1 を超えないようにしてください
varpercent = Math.min(1, (新しい日付 - 開始時刻) / 期間);

var stepValue;
If (パーセンテージ >= 1) {
// 最終値の精度を確保します
stepValue = endValue;
} else {
stepValue = startValue (endValue - startValue) * パーセント;
}
element.style.width = stepValue 'px';

if (パーセンテージ >= 1) {
clearInterval(timerId);
element.innerHTML = 新しい日付 - startTime;
}
}, 13);
}

最後の質問が 1 つあります。setInterval の間隔が 13ms に設定されているのはなぜですか?その理由は、現在のモニターのリフレッシュ レートは一般に 75 Hz を超えないためです (つまり、1 秒あたり 75 回リフレッシュされる、つまり、約 13 ミリ秒ごとにリフレッシュされる) ため、間隔をリフレッシュ レートと同期させる方がよいでしょう。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。