2012-04-18 10 views
5

Como mencioné en el título, estoy tratando de crear un metrónomo basado en jQuery/JavaScript junto con la etiqueta HTML <audio /> para reproducir el sonido.Metrónomo HTML5/jQuery - problemas de rendimiento

Funciona "bien", pero me parece que el método setInterval no funciona con la precisión suficiente. Busqué algunos hilos aquí, pero soy nuevo en jQuery y JavaScript y no encontré una solución funcional. Lo mismo para "abrir nueva pestaña y setInterval stops or lags" - problema. Traté de evitar eso con stop(true,true) pero no funcionó como esperaba.

Quiero que el metrónomo se ejecute "en segundo plano" sin cambiar el tempo al abrir una pestaña nueva y hacer algo allí. También quiero un metrónomo exacta seguro;)

Aquí es mi ambiente de prueba situada: http://nie-wieder.net/metronom/test.html

Por el momento, JS-Code y HTML-markup están todos en la fuente test.html, por lo que puede mirar allí .

Además, aquí es la preocupación (como creo) js-código que utilice:

$(document).ready(function() { 

    //vars 
    var intervalReference = 0; 
    var currentCount  = 1;  
    var countIncrement  = .5;  
    var smin = 10; 
    var smax =240; 
    var svalue = 120; 

    //soundchkbox 
    $(".sndchck").attr("disabled", true); 

    //preload sound 
    $.ajax({ 
     url: "snd/tick.ogg", 
     success: function() { 
      $(".sndchck").removeAttr("disabled"); 
     } 
    }); 

    // tick event 
    var met = $("#bpm").slider({ 
      value: 120, 
      min: smin, 
      max: smax, 
      step: 1, 
      change: function(event, ui) { 
       var delay = (1000*60/ui.value)/2 
       clearInterval(intervalReference); 

       //seems to be the Problem for me 
       intervalReference = setInterval(function(){ 
        var $cur_sd = $('#sub_div_'+currentCount); 
        $cur_sd 
        .stop(true,true) 
        .animate({opacity: 1},15, 
           function() { 
           //Play HTML5 Sound 
           if($('#sound_check:checked').val()){ 
            $('#tick') 
            .stop(true,true) 
            .trigger("play"); 
           } 
            $(this). 
            stop(true,true). 
            animate({opacity:0}); 
           } 
        ); 
        currentCount += countIncrement; 
        if(currentCount > 4.5) currentCount = 1 
       }, delay); 
       createMusicTag(ui); 
      } 
     }); 
}); 

Cualquier ayuda sería grande, estoy fuera de ideas por ahora.

Respuesta

5

setIntervalor no es preciso. lo que puede intentar hacer es algo como:

var timestamp = (new Date()).getTime(); 
function run() { 

    var now = (new Date()).getTime(); 

    if(now - timestamp >= 1000) { 
     console.log('tick'); 
     timestamp = now; 
    } 

    setTimeout(run, 10); 
} 
run(); 

Esto (cada centésima de segundo) comparan el 'sello de tiempo' con la hora actual para ver si el diff es un segundo o más (desviación es de 0,01 segundos) y si es logs 'marque' y restablece la marca de tiempo actual.

http://jsfiddle.net/rlemon/UqbwT/

Este es el mejor enfoque a algo que tiene que ser la hora exacta (OMI).

Actualización: si cambia la configuración del tiempo setTimeout ... obtendrá menos desviación. http://jsfiddle.net/rlemon/UqbwT/1/

Segunda actualización: Después de revisar esta publicación, pensé que debe haber una forma más precisa de usar temporizadores en javascript ... así que con un poco de investigación encontré el artículo this. Yo sugiero que lo leas.

+0

en primer lugar gracias por su respuesta muy rápida. Actualicé tu violín aquí: http://jsfiddle.net/ping/UqbwT/3/ para ver si tu enfoque funciona para mí. Parece que no, al menos en mi macbook (Firefox 11). ¿O solo estoy viendo esos retrasos después de un tiempo? (la marca de verificación muestra> 600 o> 700 por algún tiempo). – Dominik

+0

podría ser un problema con la implementación. pero básicamente la idea todavía es cierta. No puede confiar en las funciones de temporización del navegador. no son precisos y ** verá ** desviación. En su lugar, desea ejecutar un bucle constante en segundo plano mirando la fecha y hora reales y usar eso para determinar si ha pasado un segundo. – rlemon

+0

Sí, tienes razón, gracias por tu respuesta hasta el momento. Creo que continuaré con su solución y crearé una aplicación java o algo para personas que quieran "más";) Muchas gracias. Al menos tienes razón, es un problema de implementación y creo que no puedo hacer mucho más al respecto. – Dominik

Cuestiones relacionadas