2012-04-18 16 views
5

Come menzionato nel titolo, sto cercando di creare un metronomo basato su jQuery/JavaScript insieme al tag HTML <audio /> per riprodurre il suono.HTML5/jQuery metronome - problemi di prestazioni

funziona "bene", ma mi sembra il metodo setInterval non funziona con sufficiente precisione. Ho cercato alcuni thread qui, ma poiché sono nuovo sia per jQuery che per JavaScript e non ho trovato una soluzione funzionante. Lo stesso vale per la "nuova scheda aperta e setInterval arresti o ritardi" - problema. Ho provato a impedirlo con stop(true,true) ma non ha funzionato come previsto.

Voglio il metronomo per l'esecuzione "in background" senza cambiare ritmo quando si apre una nuova scheda e fare qualcosa lì. Anche io voglio un metronomo esatto di sicuro;)

Ecco il mio ambiente di test si trova: http://nie-wieder.net/metronom/test.html

Al momento, JS-Code e HTML markup sono tutti nella fonte test.html, in modo da poter guardare lì .

Inoltre, ecco la questione (come penso) JS-codice che utilizzo:

$(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); 
      } 
     }); 
}); 

Qualsiasi aiuto sarebbe grande, io sono a corto di idee per ora.

risposta

5

setInterval non è preciso. quello che si può provare a fare è qualcosa di simile:

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

Questo (ogni centesimo di secondo) confrontare la 'timestamp' con il tempo corrente per vedere se il diff è un secondo o più (deviazione è di 0,01 secondi) e se è log 'tick' e ripristina il timestamp corrente.

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

Questo è l'approccio migliore per qualcosa che deve essere il momento preciso (IMO).

Update: se si modifica l'impostazione del tempo setTimeout ... si ottiene meno di deviazione. http://jsfiddle.net/rlemon/UqbwT/1/

Secondo aggiornamento: Dopo aver esaminato questo post ho pensato che ci deve essere un modo più preciso di utilizzare i timer in javascript .. quindi con un po 'di ricerca sono venuto acrossed this articolo. Ti suggerisco di leggerlo.

+0

prima di tutto grazie per la risposta molto veloce. Ho aggiornato il tuo violino qui: http://jsfiddle.net/ping/UqbwT/3/ per verificare se il tuo approccio funziona per me. Sembra che non lo faccia, almeno sul mio macbook (firefox 11). O sono solo io a vedere quei ritardi dopo un po 'di tempo? (il segno di spunta indica> 600 o> 700 per un po 'di tempo). – Dominik

+0

potrebbe essere un problema con l'implementazione. ma in fondo l'idea è ancora valida. Non puoi fare affidamento sulle funzioni di temporizzazione del browser. non sono accurati e tu ** vedrai ** la deviazione. Si preferisce invece eseguire un ciclo costante sullo sfondo guardando la data e l'ora reali e usando ciò per determinare se è passato un secondo. – rlemon

+0

sì, hai ragione, grazie per la tua risposta finora. Penso che andrò avanti con la tua soluzione e creare un'app java o qualcosa per le persone che vogliono "di più";) Grazie mille. Almeno hai ragione, è un problema di implementazione e penso di non poterlo fare molto di più. – Dominik

Problemi correlati