2011-05-25 79 views
11
  1. 首先,是否有可能找出 什麼是 javascript(大多數液晶顯示器爲60Hz)的顯示器幀/刷新率?
  2. 其次,有沒有什麼辦法 說後 每X幀執行的功能?

有幾個人問我爲什麼需要這個。這裏是上下文:我有一個動畫(一個接一個渲染一個幀的無限循環)。每次迭代的輸出需要與顯示器刷新頻率同步,否則將發生tearing。我現在的做法是在loop方法中使用setTimeout(loop, 16)。它的工作。第二個參數需要是1 /(刷新率),這就是爲什麼我問這個問題。是否有可能找出什麼是JavaScript中的顯示器幀率?

+0

的問題不是 「如何」,而是 「爲什麼」 。特別是對於後者。 – ThiefMaster 2011-05-25 21:19:25

+0

也許通過使用Native Client和JavaScript? – Shaz 2011-05-25 21:23:34

+0

我無法想象你想在幀刷新時執行回調的情況......你想每秒調用60次什麼函數?你要調用SOMETHING畢竟(假設你可以得到的是首先該信息計數到X幀。 – colinross 2011-05-25 21:23:38

回答

10

對於使用window.requestAnimationFrame的現代瀏覽器,您可能會有一些運氣,可以通過一個簡單的回調來測量連續調用和計算FPS之間的時間。

你也應該能夠輕鬆地跳過渲染功能每隔n調用,以減少所需的幀速率。

我把一個粗略的例子在http://jsfiddle.net/rBGPk/ - 數學可能會稍有不妥,但應該足以顯示的總體思路。

+0

62 fps的,是好? – 2011-05-25 22:13:20

+0

@Alnitak謝謝這個真正有用的回覆(再次)我調整了你的小提琴來計算兩個動畫幀之間的長距離,以便我們可以在我們的研究中將它用作所需演示時間的最小倍數http://jsfiddle.net/bn8kbw3t / – Ruben 2014-11-17 13:54:11

2

這就是我的做法。它通過測量兩個連續幀之間的毫秒數來工作。

警告:它並不總是返回正確的答案,因爲有時一個動畫幀被跳過。只要你的頁面不忙於做其他事情,它一般會工作。

// Function that returns a promise for the FPS 
 
function getFPS() { 
 
    return new Promise((resolve) => { 
 
    requestAnimationFrame((timeFrame1) => { 
 
     requestAnimationFrame((timeFrame2) => { 
 
     resolve(1000/(timeFrame2 - timeFrame1)); 
 
     }); 
 
    }); 
 
    }); 
 
} 
 

 
// Calling the function to get the FPS 
 
getFPS().then((fps) => console.log(fps));

有一個小竅門,以原來的海報,你也許並不需要測量FPS爲您的目的。相反,請重複調用requestAnimationFrame(遞歸)並使用當前時間來確定在當前幀中呈現的內容。有些框架可能會跳過,但沒有避免它。

0

這是魯棒的方法,使用該方法requestAnimationFrame。

function calcFPS(opts){ 
    var requestFrame = window.requestAnimationFrame || 
     window.webkitRequestAnimationFrame || 
     window.mozRequestAnimationFrame; 
    if (!requestFrame) return true; // Check if "true" is returned; 
            // pick default FPS, show error, etc... 
    function checker(){ 
     if (index--) requestFrame(checker); 
     else { 
      // var result = 3*Math.round(count*1000/3/(performance.now()-start)); 
      var result = count*1000/(performance.now()- start); 
      if (typeof opts.callback === "function") opts.callback(result); 
      console.log("Calculated: "+result+" frames per second"); 
     } 
    } 
    if (!opts) opts = {}; 
    var count = opts.count||60, index = count, start = performance.now(); 
    checker(); 
} 

count值時,FPS的更精確的值,和較長的FPS測試將越高。

其他邏輯可以用來舍入到15/12s,即24​​,30,48,60,120 ... FPS。


這裏的編譯版本(舍入到3 FPS):

function calcFPS(a){function b(){if(f--)c(b);else{var e=3*Math.round(1E3*d/3/(performance.now()-g));"function"===typeof a.callback&&a.callback(e);console.log("Calculated: "+e+" frames per second")}}var c=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame;if(!c)return!0;a||(a={});var d=a.count||60,f=d,g=performance.now();b()} 

使用像這樣:

calcFPS(); // Only logs to console (you can remove the console log, 
      // making this call redundant) 

calcFPS({count: 30}); // Manually set count (the test should take 500ms 
         // on a 60FPS monitor 

calcFPS({callback: useFPS}); // Specify a callback so you can use the 
          // FPS number value 

var FPS = 0, err = calcFPS({count: 120, callback: fps => FPS = fps}); 
if (err) FPS = 30; 
相關問題