2012-12-18 11 views
7

Quindi sono stato un buon cittadino netto, utilizzando la funzione di rilevamento per vedere se il browser supporta requestAnimationFrame e ricade solo in una soluzione basata su setTimeout altrimenti (qualcosa intorno alle righe di Paul Irish's famous post).requestAnimationFrame sta passando i parametri imprevisti in IE10

var NOW = Date.now || function() { return new Date.getTime(); }; 
var reqAnimFrame = 
     window.requestAnimationFrame || 
     window.webkitRequestAnimationFrame || 
     /*      ... ||      */ 
     function (callback) { 
      setTimeout(function() { callback(NOW()); }, 1000/60); 
     }; 

var previousTime = NOW(); 
function animStep(time) { 
    var timePassed = time - previousTime; 
    myCharacter.move(myCharacter.speed * timePassed); 
    previousTime = time; 
    reqAnimationFrame(animStep); 
} 

// start the animation 
reqAnimationFrame(animStep); 

Questo ha funzionato benissimo fino a quando non è arrivato Internet Explorer 10. In IE10, il parametro time trasmesso non sembra avere nulla a che fare con l'ora corrente, rovinando il calcolo di timePassed.

Cosa sta succedendo?

+0

piuttosto sorprendentemente ... quella sarebbe stata la prima volta che * Internet Explorer * si discosta dalle specifiche. Sono scioccata! – jAndy

+0

@jAndy Beh, in questo caso, si potrebbe dire che sono in vantaggio rispetto agli altri browser in * seguendo * it. – balpha

+0

E questo è esattamente il punto: IE ha incasinato per anni e ora stanno cercando di essere bravi ragazzi seguendo rigorosamente gli standard. Spero che si compensi in futuro. – Sander

risposta

10

Tutti (per quanto ne so) altri browser che implementano requestAnimationFrame vanno dalla specifica nel (al momento della scrittura) corrente Working Draft:

Let tempo essere [il tempo di ridisegno] espresso come il numero di millisecondi dal 1970-01-01T00: 00: 00Z.

Rappresenta il tempo esattamente come fa il tuo NOW().

IE10 tuttavia goes dalle specifiche nella corrente Editor's Draft:

Let tempo essere il risultato di invocare l'now method of the Performance interface in questo contesto.

Il che significa in sostanza il numero di millisecondi in quanto il browser carica la pagina (che significa anche la misurazione è più precisa, dal momento che i rendimenti performance.now millisecondi frazionari).

E quindi quando si calcola timePassed per la prima volta in IE10, si ottiene qualcosa come 43 anni negativi.

Fortunatamente, poiché il valore passato alla callback requestAnimationFrame ha la stessa unità in entrambi i casi, solo un diverso punto di riferimento, è possibile regolarlo facilmente.

ci sono tre possibilità:

  1. Si può solo buttare via il primo passo di animazione, di utilizzarlo solo per impostare previousTime, ma non fare qualsiasi altra cosa.
  2. È possibile ignorare il parametro passato e utilizzare NOW() (o performance.now) ogni volta, avendo sempre lo stesso identico punto di riferimento.
  3. Oppure si potrebbe cambiare l'inizio dell'animazione a questo:

    // start the animation 
    reqAnimationFrame(function (t) { 
        previousTime = t - (NOW() - previousTime); 
        animStep(t); 
    ); 
    

    questo renderà il calcolo (compreso il primo) di timePassed correggere non importa quale spec il browser segue. E poiché cambia solo la prima invocazione, non si ha alcun sovraccarico aggiuntivo nel lungo periodo.