2011-05-25 10 views
11
  1. En primer lugar, ¿es posible averiguar cuál es la frecuencia de actualización/cuadro del monitor en javascript (60Hz para la mayoría de los monitores LCD)?
  2. En segundo lugar, ¿hay alguna forma de para decir ejecutar una función después de cada X cuadros?

Varias personas me preguntaron por qué necesito esto. Aquí está el contexto: tengo una animación (un ciclo sin fin que representa un cuadro tras otro). El resultado de cada iteración debe sincronizarse con la frecuencia de actualización del monitor; de lo contrario, ocurrirá tearing. La forma en que lo estoy haciendo ahora es usar setTimeout(loop, 16) dentro del método loop. Su tipo de trabajo. El segundo parámetro debe ser 1/(frecuencia de actualización), y es por eso que hice esta pregunta.¿Es posible averiguar cuál es la velocidad de cuadro del monitor en javascript?

+0

La pregunta no es "cómo", sino "por qué" . Especialmente para este último. – ThiefMaster

+0

¿Quizás usando Native Client junto con JavaScript? – Shaz

+0

No puedo imaginar una situación en la que desee ejecutar una devolución de llamada en la actualización de cuadros ... ¿Qué función desea llamar 60 veces por segundo? Tienes que estar llamando ALGO para contar hasta X fotogramas después de todo (suponiendo que puedas obtener esta información en primer lugar. – colinross

Respuesta

10

Puede tener algo de suerte en los navegadores modernos que usan window.requestAnimationFrame con una devolución de llamada trivial que mide el tiempo entre las invocaciones sucesivas y calcula el FPS.

También debería poder omitir fácilmente su función de representación cada enésima invocación para reducir la velocidad de fotogramas deseada.

Pongo un ejemplo aproximado en http://jsfiddle.net/rBGPk/ - las matemáticas pueden ser un poco incorrectas, pero debería ser suficiente para mostrar la idea general.

+0

62 fps, ¿eso es bueno? –

+0

@Alnitak Gracias por esta respuesta realmente útil (otra vez). Adapté tu violín para calcular la distancia de largo plazo entre dos cuadros de animación, de modo que podamos usarlo como un múltiplo más pequeño para los tiempos de presentación deseados en nuestros estudios http://jsfiddle.net/bn8kbw3t / – Ruben

2

Así es como lo hago. Funciona midiendo la cantidad de milisegundos entre dos cuadros consecutivos.

Advertencia: No siempre devuelve la respuesta correcta porque a veces se omite un cuadro de animación. Por lo general, funcionará siempre que su página no esté ocupada haciendo otra cosa.

// 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));

Como consejo a su creador original, es probable que no necesita medir los FPS para sus propósitos. En su lugar, invoque requestAnimationFrame repetidamente (recursivamente) y use la hora actual para determinar qué representar en el fotograma actual. Algunos fotogramas pueden omitirse, pero no hay forma de evitarlo.

0

Este es un método robusto, que utiliza el método 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(); 
} 

Cuanto mayor sea el valor de count, más preciso será el valor de la FPS, y el más largo de la prueba se llevará a FPS.

La lógica adicional se puede utilizar para redondear a 15/12, es decir, 24, 30, 48, 60 120 ... FPS.


Aquí está la versión compilada (con redondeo a 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()} 

usados ​​de esta manera:

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; 
Cuestiones relacionadas