首頁 >web前端 >js教程 >如何使用 requestAnimationFrame 控制 fps?

如何使用 requestAnimationFrame 控制 fps?

WBOY
WBOY轉載
2023-08-29 08:41:021114瀏覽

如何使用 requestAnimationFrame 控制 fps?

fps 這個字通常與我們需要使用動畫的影片和遊戲相關。 fps 是每秒影格數的縮寫,表示目前畫面重新渲染的次數。

例如,影片是一排連續的影像。這意味著它以非常短的間隔顯示圖像,因此用戶無法知道它正在單獨顯示圖像。如果我們降低影片的 fps,它可能看起來像圖像動畫而不是影片。因此,更高的 fps 可以提供更好的結果。基本上,fps 告訴我們一秒鐘內應該更新螢幕多少次。

有時,我們需要使用 JavaScript 來控制 fps。我們可以使用不同的方法,我們將在本教程中學習這些方法。

使用 SetTime() 函數

setTimeout() 函數將回呼函數作為第一個參數,將時間間隔作為第二個參數。在這裡,我們可以在每個時間間隔後重新渲染螢幕來控制 fps。

文法

使用者可以依照下面的語法使用setTimeout()函數來控制fps。

setTimeout(() => {
   requestAnimationFrame(animate);
}, interval);

我們使用 requestAnimationFrame() 方法在上述語法中呼叫了 animate() 函數。

步驟

  • 第 1 步 - 定義totalFrames 變數並初始化為零。它將記錄總幀數。

  • 步驟 2 - 另外,定義 fps 變數並儲存 fps 的值。

  • 第3步 - 定義intervalOffps變數並將間隔儲存到其中。它儲存 1000/fps,其中 1000 是毫秒,我們透過將其除以 fps 得到時間間隔。

  • 第 4 步 - 將目前時間儲存在 startTime 變數中。

  • 第 5 步 - 呼叫 animate() 函數。

  • 步驟 5.1 - 在每個 internvalOffps 之後使用 setTimeout() 函數呼叫 requestAnimationFrame() 函數。

  • 步驟 5.2 - 在 setTimeout() 函數的回呼函數中,使用者可以編寫程式碼來重新渲染螢幕或在 Canvas 上繪製形狀。

  • 步驟 5.3 - 使用 Date() 物件並取得目前時間。當前時間減去開始時間即可得到經過時間。

  • 步驟 5.4 - 使用數學函數,取得總 fps 和總時間。

範例 1

在下面的範例中,我們使用 setTimeout() 函數來控制 fps。我們使用“3”作為 fps 的值。因此,我們的 fps 間隔等於 1000/3。因此,我們將每 1000/3 毫秒呼叫一次 requestAnimationFrame() 方法。

<html>
<body>
   <h3> Using the <i> setTimeOut() method </i> to control the fps with requestAnimationFrame </h3>
   <div id="output"> </div>
   <script>
      let output = document.getElementById("output");
      // Initial frame count set to zero
      var totalFrames = 0;
      var current, consumedTime;
      
      // Set the fps at which the animation will run (say 10 fps)
      var fps = 3;
      var intervalOffps = 1000 / fps;
      var AfterTime = Date.now();
      var starting = AfterTime;
      animate();
      function animate() {
         setTimeout(() => {
         
            //  call the animate function recursively
            requestAnimationFrame(animate);
            
            // get current time
            current = Date.now();
            
            // get elapsed time since the last frame
            var elapsed = current - starting;
            
            //Divide elapsed time with frame count to get fps
            var currentFps =
            Math.round((1000 / (elapsed / ++totalFrames)) * 100) / 100;
            output.innerHTML = "Total elapsed time is equal to = " + Math.round((elapsed / 1000) * 100) / 100 + "<br>" + " secs @ ";
            output.innerHTML += currentFps + " fps.";
         }, intervalOffps);
      }
   </script>
</body>
</html>

使用 Date() 物件

我們可以使用 Date() 物件來取得目前時間和上一幀時間之間的差異。如果時間差超過幀間隔,我們將重新渲染螢幕。否則,我們將等待完成單幀。

文法

使用者可以按照下面的語法使用時間間隔來控制幀率。

consumedTime = current - AfterTime;
if (consumedTime > intervalOffps) {
   // rerender screen
}

在上述語法中,消耗時間是當前時間與最後一幀完成時的時間之差。

範例 2

在下面的範例中,我們採用目前幀和最後一幀之間的時間差。如果時間差大於時間間隔,我們重新渲染螢幕。

<html>
<body>
   <h3> Using the <i> Date() object </i> to control the fps with requestAnimationFrame. </h3>
   <div id = "output"> </div>
   <script>
      let output = document.getElementById("output");
      // Initial framecount set to zero
      var totalFrames = 0;
      var current, consumedTime;
      
      // Set the fps at which the animation will run (say 10 fps)
      var fps = 50;
      var intervalOffps = 1000 / fps;
      var AfterTime = Date.now();
      var starting = AfterTime;
      animate();
      function animate() {
      
         // use date() object and requestAnimationFrame() to control fps
         requestAnimationFrame(animate);
         current = Date.now();
         consumedTime = current - AfterTime;
         
         // if the consumed time is greater than the interval of fps
         if (consumedTime > intervalOffps) {
         
            // draw on canvas here
            AfterTime = current - (consumedTime % intervalOffps);
            var elapsed = current - starting;
            
            //Divide elapsed time with frame count to get fps
            var currentFps =
            Math.round((1000 / (elapsed / ++totalFrames)) * 100) / 100;
            output.innerHTML = "Total elapsed time is equal to = " + Math.round((elapsed / 1000) * 100) / 100 + "<br>" + " secs @ ";
            output.innerHTML += currentFps + " fps.";
         }
      }
   </script>
</body>
</html>

範例 3

在下面的範例中,使用者可以使用輸入範圍來設定 fps。之後,當使用者點擊按鈕時,它會執行 startAnimation() 函數,該函數設定 fps 間隔並呼叫 animate() 函數。 animate()函數呼叫drawShape()函數在畫布上繪製形狀並控制fps。

在這裡,我們使用了一些方法在畫布上繪製形狀。使用者可以使用輸入範圍來變更 fps,嘗試對形狀進行動畫處理並觀察動畫的差異。

<html>
<body>
   <h3>Using the <i> Date() object </i> to control the fps with requestAnimationFrame. </h3>
   <!-- creating an input range for fps -->
   <input type = "range" min = "1" max = "100" value = "10" id = "fps" />
   <button onclick = "startAnimation()"> Animate </button> <br><br>
   <!-- canvas to draw shape -->
   <canvas id = "canvas" width = "250" height = "250"> </canvas>
   <script>
      let canvas = document.getElementById("canvas");
      let context = canvas.getContext("2d");
      let animation;
      let intervalOffps, current, after, elapsed;
      let angle = 0;
      // drawing a sha[e]
      function drawShape() {
         context.save();
         context.translate(100, 100);
         
         // change angle
         context.rotate(Math.PI / 180 * (angle += 11));
         context.moveTo(0, 0);
         
         // draw line
         context.lineTo(250, 250);
         context.stroke();
         context.restore();
         
         // stop animation
         if (angle >= 720) {
            cancelAnimationFrame(animation);
         }
      }
      function animate() {
      
         // start animation and store its id
         animation = requestAnimationFrame(animate);
         current = Date.now();
         elapsed = current - after;
         
         // check if elapsed time is greater than interval, if yes, draw shape again
         if (elapsed > intervalOffps) {
            after = current - (elapsed % intervalOffps);
            drawShape();
         }
      }
      function startAnimation() {
      
         // get fps value from input
         let fpsInput = document.getElementById("fps");
         let fps = fpsInput.value;
         
         // calculate interval
         intervalOffps = 1000 / fps;
         after = Date.now();
         requestAnimationFrame(animate);
      }
   </script>
</body>
</html>

以上是如何使用 requestAnimationFrame 控制 fps?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:tutorialspoint.com。如有侵權,請聯絡admin@php.cn刪除