2012-04-18 4 views
5

Wie im Titel erwähnt, versuche ich ein jQuery/JavaScript basierte Metronom zusammen mit dem HTML-Code <audio /> zu erstellen, um den Sound zu spielen.HTML5/jQuery Metronom - Leistungsprobleme

Es funktioniert "okay", aber es scheint mir die setInterval Methode funktioniert nicht genau genug. Ich habe hier einige Threads durchsucht, aber ich bin neu in jQuery und JavaScript und habe keine funktionierende Lösung gefunden. Gleiches gilt für das Problem "open new tab und setInterval stops or lags". Ich habe versucht, das mit stop(true,true) zu verhindern, aber es hat nicht wie erwartet funktioniert.

Ich möchte, dass das Metronom "im Hintergrund" läuft, ohne das Tempo zu ändern, wenn man einen neuen Tab öffnet und etwas tut. Auch ich will eine genaue Metronom sicher;)

Hier ist meine Testumgebung befindet: http://nie-wieder.net/metronom/test.html

Im Moment JS-Codes und HTML-Markup sind alle in der test.html Quelle, so dass Sie es sehen können .

Auch hier ist die betreffende (wie ich glaube) js-Code, den ich verwenden:

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

Jede Hilfe wäre toll, ich bin jetzt aus Ideen.

Antwort

5

setInterval ist nicht genau. was können Sie versuchen, tun so etwas wie:

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

Dies wird (jede Hundertstelsekunde), um den ‚Zeitstempel‘ mit der aktuellen Zeit vergleichen, um zu sehen, ob der Unterschied eine zweite oder mehr ist (Abweichung beträgt 0,01 Sekunden) und wenn es logs 'Tick' ist und setzt den aktuellen Zeitstempel zurück.

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

Dies ist der beste Ansatz für etwas, die Zeit genau (imo) sein muss.

Update: Wenn Sie die setTimeout Zeiteinstellung ändern ... erhalten Sie weniger Abweichung.

Zweite Aktualisierung: Nach der Überprüfung dieser Post dachte ich, es muss eine genauere Möglichkeit, Timer in Javascript zu verwenden .. so mit ein wenig Forschung kam ich akroba this Artikel. Ich schlage vor, Sie lesen es.

+0

Zunächst einmal vielen Dank für Ihre sehr schnelle Antwort. Ich habe deine Geige hier aktualisiert: http://jsfiddle.net/ping/UqbwT/3/ um zu sehen, ob dein Ansatz für mich funktioniert. Scheint es nicht, zumindest auf meinem Macbook (Firefox 11). Oder sehe ich nur diese Lags nach einiger Zeit? (Tick zeigt> 600 oder> 700 für einige Zeit). – Dominik

+0

könnte ein Problem bei der Implementierung sein. aber im Grunde ist die Idee immer noch gültig. Sie können sich nicht auf die Timing-Funktionen des Browsers verlassen. sie sind nicht genau und du ** wirst ** Abweichung sehen. Sie möchten stattdessen eine konstante Schleife im Hintergrund ausführen, die das tatsächliche Datum und die tatsächliche Uhrzeit anzeigt, und anhand dieser bestimmen, ob eine Sekunde vergangen ist. – rlemon

+0

aye, du hast Recht, danke für deine Antwort bis jetzt. Ich denke, ich mache weiter mit deiner Lösung und erstelle eine Java-App oder etwas für Leute, die "mehr" wollen;) Vielen Dank. Zumindest hast du Recht, es ist ein Implementierungsproblem und ich denke, ich kann nicht viel mehr darüber machen. – Dominik