|
1 | 1 | import { Observable } from '../../Observable';
|
2 |
| -import { Subscription } from '../../Subscription'; |
3 | 2 | import { TimestampProvider } from '../../types';
|
4 | 3 | import { performanceTimestampProvider } from '../../scheduler/performanceTimestampProvider';
|
5 | 4 | import { animationFrameProvider } from '../../scheduler/animationFrameProvider';
|
@@ -82,37 +81,47 @@ export function animationFrames(timestampProvider?: TimestampProvider) {
|
82 | 81 | * @param timestampProvider The timestamp provider to use to create the observable
|
83 | 82 | */
|
84 | 83 | function animationFramesFactory(timestampProvider?: TimestampProvider) {
|
85 |
| - const { schedule } = animationFrameProvider; |
86 | 84 | return new Observable<{ timestamp: number; elapsed: number }>((subscriber) => {
|
87 |
| - const subscription = new Subscription(); |
88 | 85 | // If no timestamp provider is specified, use performance.now() - as it
|
89 | 86 | // will return timestamps 'compatible' with those passed to the run
|
90 | 87 | // callback and won't be affected by NTP adjustments, etc.
|
91 | 88 | const provider = timestampProvider || performanceTimestampProvider;
|
| 89 | + |
92 | 90 | // Capture the start time upon subscription, as the run callback can remain
|
93 | 91 | // queued for a considerable period of time and the elapsed time should
|
94 | 92 | // represent the time elapsed since subscription - not the time since the
|
95 | 93 | // first rendered animation frame.
|
96 | 94 | const start = provider.now();
|
97 |
| - const run = (timestamp: DOMHighResTimeStamp | number) => { |
98 |
| - // Use the provider's timestamp to calculate the elapsed time. Note that |
99 |
| - // this means - if the caller hasn't passed a provider - that |
100 |
| - // performance.now() will be used instead of the timestamp that was |
101 |
| - // passed to the run callback. The reason for this is that the timestamp |
102 |
| - // passed to the callback can be earlier than the start time, as it |
103 |
| - // represents the time at which the browser decided it would render any |
104 |
| - // queued frames - and that time can be earlier the captured start time. |
105 |
| - const now = provider.now(); |
106 |
| - subscriber.next({ |
107 |
| - timestamp: timestampProvider ? now : timestamp, |
108 |
| - elapsed: now - start, |
109 |
| - }); |
| 95 | + |
| 96 | + let id = 0; |
| 97 | + const run = () => { |
110 | 98 | if (!subscriber.closed) {
|
111 |
| - subscription.add(schedule(run)); |
| 99 | + id = animationFrameProvider.requestAnimationFrame((timestamp: DOMHighResTimeStamp | number) => { |
| 100 | + id = 0; |
| 101 | + // Use the provider's timestamp to calculate the elapsed time. Note that |
| 102 | + // this means - if the caller hasn't passed a provider - that |
| 103 | + // performance.now() will be used instead of the timestamp that was |
| 104 | + // passed to the run callback. The reason for this is that the timestamp |
| 105 | + // passed to the callback can be earlier than the start time, as it |
| 106 | + // represents the time at which the browser decided it would render any |
| 107 | + // queued frames - and that time can be earlier the captured start time. |
| 108 | + const now = provider.now(); |
| 109 | + subscriber.next({ |
| 110 | + timestamp: timestampProvider ? now : timestamp, |
| 111 | + elapsed: now - start, |
| 112 | + }); |
| 113 | + run(); |
| 114 | + }); |
| 115 | + } |
| 116 | + }; |
| 117 | + |
| 118 | + run(); |
| 119 | + |
| 120 | + return () => { |
| 121 | + if (id) { |
| 122 | + animationFrameProvider.cancelAnimationFrame(id); |
112 | 123 | }
|
113 | 124 | };
|
114 |
| - subscription.add(schedule(run)); |
115 |
| - return subscription; |
116 | 125 | });
|
117 | 126 | }
|
118 | 127 |
|
|
0 commit comments