Javascript - Controlul fps-urilor cu requestAnimationFrame Stack Overflow

Se pare că requestAnimationFrame este modalitatea de facto de a anima lucrurile acum. A funcționat destul de bine pentru mine în cea mai mare parte, dar acum încerc să fac niște animații pe pânză și mă întrebam: Există vreo modalitate de a mă asigura că rulează la un anumit fps? Înțeleg că scopul rAF-ului este pentru animații uniform și în mod constant și aș putea risca să-mi fac animația agitată, dar chiar acum pare să ruleze la viteze drastic diferite destul de arbitrar și mă întreb dacă există o modalitate de a combate că cumva.

Aș folosi setInterval, dar vreau optimizările oferite de rAF (mai ales oprirea automată când fila este focalizată).

În cazul în care cineva vrea să se uite la codul meu, este destul de mult:

În cazul în care Node.drawFlash () este doar un cod care determină raza pe baza unei variabile de contor și apoi desenează un cerc.

10 Răspunsuri 10

Cum să accelerați requestAnimationFrame la o anumită rată de cadre

Această metodă funcționează testând timpul scurs de la executarea ultimei bucle de cadre.

Codul dvs. de desen se execută numai când a trecut intervalul dvs. FPS specificat.

Prima parte a codului stabilește câteva variabile utilizate pentru a calcula timpul scurs.

Și acest cod este bucla reală RequestAnimationFrame care atrage FPS-ul specificat.

javascript

Actualizare 2016/6

Problema care limitează rata cadrelor este că ecranul are o rată de actualizare constantă, de obicei 60 FPS.

Dacă dorim 24 FPS, nu vom primi niciodată adevăratul 24 fps pe ecran, îl putem cronometra ca atare, dar nu îl putem afișa, deoarece monitorul poate afișa cadre sincronizate doar la 15 fps, 30 fps sau 60 fps (unele monitoare au și 120 fps ).

Cu toate acestea, în scopuri de sincronizare, putem calcula și actualiza când este posibil.

Puteți construi toată logica pentru controlul ratei de cadre încapsulând calcule și apeluri de apel într-un obiect:

Apoi adăugați un controler și un cod de configurare:

Utilizare

Devine foarte simplu - acum, tot ce trebuie să facem este să creăm o instanță prin setarea funcției de apel invers și a ratei de cadre dorite, astfel:

Apoi începeți (care ar putea fi comportamentul implicit dacă doriți):

Gata, toată logica este gestionată intern.

Vechi răspuns

Scopul principal al requestAnimationFrame este de a sincroniza actualizările cu rata de reîmprospătare a monitorului. Acest lucru vă va cere să animați la FPS-ul monitorului sau la un factor al acestuia (de exemplu, 60, 30, 15 FPS pentru o rată de reîmprospătare tipică @ 60 Hz).

Dacă doriți un FPS mai arbitrar, atunci nu are rost să folosiți rAF, deoarece rata cadrelor nu se va potrivi oricând cu frecvența de actualizare a monitorului (doar un cadru ici și colo), ceea ce pur și simplu nu vă poate oferi o animație lină (ca în cazul tuturor re-temporizărilor cadrelor ) și puteți utiliza în schimb setTimeout sau setInterval.

Aceasta este, de asemenea, o problemă bine cunoscută în industria video profesională atunci când doriți să redați un videoclip la un alt FPS, apoi dispozitivul care îl afișează se reîmprospătează. Au fost folosite multe tehnici, cum ar fi amestecarea cadrelor și reconstruirea cadrelor intermediare complexe bazate pe vectori de mișcare, dar cu pânza aceste tehnici nu sunt disponibile și rezultatul va fi întotdeauna video sacadat.

Motivul pentru care plasăm setTimeout mai întâi (și de ce unii plasează rAF primul când se folosește un poly-fill) este că acest lucru va fi mai precis, deoarece setTimeout va pune la coadă un eveniment imediat când începe bucla, astfel încât, indiferent de cât timp rămâne codul va fi utilizat (cu condiția să nu depășească intervalul de expirare) următorul apel va fi la intervalul pe care îl reprezintă (pentru rAF pur acest lucru nu este esențial deoarece rAF va încerca să sară pe următorul cadru în orice caz).