2017-01-24 10 views
6

Moim celem jest stworzenie pętli animacji à la requestAnimationFrame tak, że mogę zrobić coś takiego:Jak mogę użyć RxJS do wygenerowania pętli requestAnimationFrame?

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

Próbowałem ten kod jako podstawowego badania:

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.

Spodziewałem się, że zarejestruję liczby od 0 do około 60 (ponieważ jest to częstotliwość odświeżania mojego monitora) przez 1 sekundę. Zamiast tego szybko rejestruje liczby (znacznie szybciej niż requestAnimationFrame), zaczyna powodować opóźnienie strony, a na koniec przepełnia stos około 10000 i kilka sekund później.

Dlaczego harmonogram programu animationFrame zachowuje się w ten sposób i jaki jest prawidłowy sposób uruchomienia pętli animacji z RxJS?

Odpowiedz

6

Dzieje się tak, ponieważ domyślne zachowanie Observable.of ma natychmiast nastąpić.

Aby to zmienić, należy określić Scheduler Dzwoniąc Observable.of:

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>

Albo more simply wymienić operatorów of i repeat z:

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

Jakoś brakowało mi, że prawdopodobnie dlatego, że kiedy po raz pierwszy wpadł na problem ja nie używałem 'of', ale coś, zachowywał się inaczej. Nagle jest o wiele jaśniejszy. Dzięki! –

2

W ten sposób używam reque stAnimationFrame z rxjs. Widziałem wielu programistów używających 0 zamiast animationFrame.now(). O wiele lepiej jest spędzać czas, ponieważ często potrzebujesz tego w animacjach.

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>

Powiązane problemy