2017-01-24 2 views
6

Mein Ziel ist es, eine Animationsschleife à la requestAnimationFrame zu schaffen, so dass ich etwas tun könnte:Wie kann ich mit RxJS eine requestAnimationFrame-Schleife generieren?

animationObservable.subscribe(() => 
{ 
    // drawing code here 
}); 

habe ich versucht, diesen Code als Basistest:

let x = 0; 

Rx.Observable 
    .of(0) 
    .repeat(Rx.Scheduler.animationFrame) 
    .takeUntil(Rx.Observable.timer(1000)) 
    .subscribe(() => console.log(x++)); 

Here is a JSFiddle but I'm not liable for any browser crashes from running this.

Ich erwartete, dass dies die Zahlen von 0 bis etwa 60 (weil das ist die Bildwiederholfrequenz meines Monitors) über 1 Sekunde protokolliert. Stattdessen protokolliert es schnell Zahlen (viel schneller als requestAnimationFrame würde), beginnt, die Seite zu verzögern, und schließlich den Stapel um 10000 und einige Sekunden später überläuft.

Warum verhält sich der animationFrame Scheduler so, und was ist der richtige Weg, um eine Animationsschleife mit RxJS auszuführen?

Antwort

6

Es ist, weil das Standardverhalten von Observable.of sofort emittieren soll.

dieses Verhalten ändern, können Sie die Scheduler angeben sollten, wenn Observable.of Aufruf:

let x = 0; 
 

 
Rx.Observable 
 
    .of(0, Rx.Scheduler.animationFrame) 
 
    .repeat() 
 
    .takeUntil(Rx.Observable.timer(1000)) 
 
    .subscribe(() => console.log(x++));
<script src="https://npmcdn.com/@reactivex/[email protected]/dist/global/Rx.min.js"></script>

Oder more simply, ersetzen Sie die of und repeat Betreiber mit:

Observable.interval(0, Rx.Scheduler.animationFrame) 
+0

Irgendwie habe ich verpasst, dass, wahrscheinlich, weil, wenn ich lief ich in das Problem zunächst nicht wurde mit 'von', sondern etwas, das anders verhalten. Plötzlich ist es viel klarer. Vielen Dank! –

2

So benutze ich reque stAnimationFrame mit rxjs. Ich habe viele Entwickler gesehen, die 0 anstelle von animationFrame.now() verwenden. Es ist viel besser, die Zeit zu vertreiben, weil Sie das oft in Animationen brauchen.

const { Observable, Scheduler } = Rx; 
 

 
const requestAnimationFrame$ = Observable 
 
    .defer(() => Observable 
 
    .of(Scheduler.animationFrame.now(), Scheduler.animationFrame) 
 
    .repeat() 
 
    .map(start => Scheduler.animationFrame.now() - start) 
 
); 
 

 
// Example usage 
 
const duration$ = duration => requestAnimationFrame$ 
 
    .map(time => time/duration) 
 
    .takeWhile(progress => progress < 1) 
 
    .concat([1]) 
 

 
duration$(60000) 
 
    .subscribe((i) => { 
 
    clockPointer.style.transform = `rotate(${i * 360}deg)`; 
 
    });
<script src="https://unpkg.com/@reactivex/[email protected]/dist/global/Rx.js"></script> 
 

 
<div style="border: 3px solid black; border-radius: 50%; width: 150px; height: 150px;"> 
 
    <div id="clockPointer" style="width: 2px; height: 50%; background: black; margin-left: 50%; padding-left: -1px; transform-origin: 50% 100%;"></div> 
 
</div>

Verwandte Themen