ホームページ >ウェブフロントエンド >jsチュートリアル >RequestAnimationFrameを使用したシンプルなアニメーション

RequestAnimationFrameを使用したシンプルなアニメーション

Lisa Kudrow
Lisa Kudrowオリジナル
2025-02-24 08:41:09635ブラウズ

Simple Animations Using requestAnimationFrame

コアポイント

  • requestAnimationFrameは、ブラウザの描画サイクルと同期したアニメーションの書き込みに使用されるヘルパー関数であり、それにより、よりスムーズでCPUを節約するアニメーション効果を実現します。すべての最新のブラウザでサポートされており、古いブラウザーと互換性があります。
  • requestAnimationFrame animateを使用して作成された関数は、一連の関数をパラメーターとして受け入れるように設計できます。これは、シーケンスで呼び出され、アニメーションシーケンスを実装します。この関数は、アニメーションの進行状況を追跡し、アニメーションの終了時間を計算できます。
  • requestAnimationFrameブラウザのリフレッシュレートと同期して動作するため、setTimeoutまたはsetIntervalよりも効率的にアニメーションを作成します。 JavaScriptフレームワークまたはライブラリで使用でき、CSSプロパティ、キャンバスアニメーション、SVGアニメーション、スクロールまたはユーザーインタラクションベースのアニメーションなど、さまざまなアニメーションを処理できます。

dom要素アニメーションでは、数ミリ秒ごとにCSSスタイルを変更して、動きの幻想を作成します。これは、コールバック関数をsetTimeoutに渡し、そのコールバック関数のノードのスタイルオブジェクトを変更することを意味します。次に、もう一度setTimeoutを呼び出して、次のアニメーションフレームをキューアップします。 requestAnimationFrameこの新しいヘルパー関数は、アニメーションのために生まれました。最初はFirefox 4で見られ、IE 10を含むすべてのブラウザに徐々に採用されています。幸いなことに、古いブラウザと互換性があるのは簡単です。

<code class="language-javascript">window.requestAnimationFrame(callbackFunction);</code>

setTimeout(指定された時間遅延の後に実行)とは異なり、ブラウザが次回画面を描画するときにrequestAnimationFrameコールバック関数を実行します。これにより、ブラウザの描画サイクルと同期できるため、あまり頻繁に描画しないか、頻繁に頻繁に描画しないようになります。つまり、アニメーションは非常にスムーズで、CPUに過負荷になりません。

ブラウザ互換性処理

現在、すべてのブラウザにはrequestAnimationFrameの接頭辞付きバージョンがあります。そのため、どのバージョンがサポートされているかを検出して参照しましょう。

<code class="language-javascript">var _requestAnimationFrame = function(win, t) {
  return win["webkitR" + t] || win["r" + t] || win["mozR" + t]
          || win["msR" + t] || function(fn) { setTimeout(fn, 60) }
}(window, "equestAnimationFrame");</code>
正方形のブラケット表記を使用して、ウィンドウオブジェクトのプロパティにアクセスする方法に注意してください。文字列の連結を使用して動的にプロパティ名を構築しているため、四角いブラケット表記を使用します。ブラウザがサポートしていない場合、60ミリ秒後に呼び出して同様の効果を達成する通常の関数に戻ります。

setTimeout

アニメーション関数構造

次に、アニメーションをシミュレートするために

を繰り返し呼び出す単純な関数を構築しましょう。アニメーションを実装するには、繰り返し呼ばれるエントリポイントと内部関数(ステップ関数と呼ばれる)として外部関数が必要です。

<code class="language-javascript">window.requestAnimationFrame(callbackFunction);</code>

ステップ関数を呼び出すたびに、アニメーションの進行状況を追跡して、いつ終了するかを知る必要があります。アニメーションが終了する時間を計算し、各サイクルの残りの時間に基づいて進行状況を計算します。

<code class="language-javascript">var _requestAnimationFrame = function(win, t) {
  return win["webkitR" + t] || win["r" + t] || win["mozR" + t]
          || win["msR" + t] || function(fn) { setTimeout(fn, 60) }
}(window, "equestAnimationFrame");</code>

new Date()を使用して、現在の時間をミリ秒単位で取得していることに注意してください。プラス記号は、日付オブジェクトを数値データ型にキャストします。 rate変数は0〜1の数値であり、アニメーションの進行率を示しています。

アニメ関数の改善

関数の入力と出力を考慮する必要があります。関数が関数と持続時間をパラメーターとして受け入れるようにしましょう。

<code class="language-javascript">function animate() {
  var step = function() {
    _requestAnimationFrame(step);
  }
  step();
}</code>

このようにこの関数を呼び出すことができます:

<code class="language-javascript">function animate() {
  var duration = 1000 * 3,  // 3 秒
      end = +new Date() + duration;

  var step = function() {
    var current = +new Date(),
        remaining = end - current;

    if (remaining < 60) {       // 如果剩余时间少于 60 毫秒,则在此结束动画
      return;
    } else {
      var rate = 1 - remaining / duration;
      // 执行一些动画操作
    }

    _requestAnimationFrame(step);
  }
  step();
}</code>

run関数では、ノードの幅を「100px」から「300px」にアニメーション化するコードを配置します。

<code class="language-javascript">function animate(item) {
  var duration = 1000 * item.time,
      end = +new Date() + duration;

  var step = function() {
    var current = +new Date(),
        remaining = end - current;

    if (remaining < 60) {
      item.run(1);  // 1 = 进度为 100%
      return;
    } else {
      var rate = 1 - remaining / duration;
      item.run(rate);
    }

    _requestAnimationFrame(step);
  }
  step();
}</code>

アニメーション関数の改善

正常に動作しますが、私が本当に望んでいるのは、順番に呼ばれる関数の配列を入力できることです。このようにして、最初のアニメーションが終了した後、2番目のアニメーションが開始されます。配列をスタックとして扱い、アイテムを一度に1つずつポップします。入力を変更しましょう:

<code class="language-javascript">animate({
  time: 3,  // 以秒为单位的时间
  run: function(rate) { /* 使用 rate 执行某些操作 */ }
});</code>
アニメーションが最初に実行された場合、

はnullで、itemは60ミリ秒未満なので、アレイから最初のアイテムをポップして実行を開始します。アニメーションの最後のフレームでは、remainingも60未満なので、現在のアニメーションを完了し、次のアイテムを配列からポップアップして、次のアイテムをアニメーション化します。また、私は緩和式を通じてremaining値を渡したことに注意してください。 0〜1の値は、立方体の割合で成長し、硬く見えます。アニメーション関数を呼び出すために、次のことを行います。 rate

最初にボックスの幅が展開し、2秒かかり、高さが拡大し、2秒かかることに注意してください。
<code class="language-javascript">animate({
  time: 3,
  run: function(rate) {
    document.getElementById("box").style
      .width = (rate * (300 - 100) + 100) + "px";
  }
});</code>

コード最適化

コードを少しクリーンアップしましょう。何度か

を呼び出すことに注意してください。これはあまり良くありません。キャッシュしてキャッシュして、開始値と終了値をキャッシュしながらキャッシュしましょう。

getElementById

<code class="language-javascript">function animate(list) {
  var item,
      duration,
      end = 0;

  var step = function() {
    var current = +new Date(),
        remaining = end - current;

    if (remaining < 60) {
      if (item) item.run(1);  // 1 = 进度为 100%

      item = list.shift();  // 获取下一个项目

      if (item) {
        duration = item.time * 1000;
        end = current + duration;
        item.run(0);  // 0 = 进度为 0%
      } else {
        return;
      }
    } else {
      var rate = remaining / duration;
      rate = 1 - Math.pow(rate, 3);  // 缓动公式
      item.run(rate);
    }

    _requestAnimationFrame(step);
  };
  step();
}</code>
関数は常に自己完結型のオブジェクトの一部であり、

変数を介してオブジェクトのすべてのプロパティにアクセスできるため、メイン関数を変更する必要はないことに注意してください。これで、ステップ関数を実行するたびに、すべての変数をキャッシュします。それでおしまい。 runを利用し、古いブラウザーにフォールバックを提供するシンプルなアニメーションヘルパー関数。 this requestAnimationFrame

(この環境でJavaScriptコードを実行できないため、スクリプトデモパーツは省略されています。

(コンテンツが元のテキストから高度に複製されているため、擬似オリジナルを完了するためにコアポイントを維持するだけであるため、単純なアニメーションにrequestAnimationFrameを使用するFAQセクションも省略されています。)

以上がRequestAnimationFrameを使用したシンプルなアニメーションの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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