Skip to content

Commit e637b78

Browse files
trxcllntbenlesh
authored andcommitted
feat(scheduler): adds animationFrame scheduler.
1 parent a411673 commit e637b78

File tree

6 files changed

+85
-2
lines changed

6 files changed

+85
-2
lines changed

src/Rx.DOM.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,18 @@ import {ArgumentOutOfRangeError} from './util/ArgumentOutOfRangeError';
123123
import {ObjectUnsubscribedError} from './util/ObjectUnsubscribedError';
124124
import {asap} from './scheduler/asap';
125125
import {queue} from './scheduler/queue';
126+
import {animationFrame} from './scheduler/animationFrame';
126127
import {AsapScheduler} from './scheduler/AsapScheduler';
127128
import {QueueScheduler} from './scheduler/QueueScheduler';
129+
import {AnimationFrameScheduler} from './scheduler/AnimationFrameScheduler';
128130
import {rxSubscriber} from './symbol/rxSubscriber';
129131
/* tslint:enable:no-unused-variable */
130132

131133
/* tslint:disable:no-var-keyword */
132134
var Scheduler = {
133135
asap,
134-
queue
136+
queue,
137+
animationFrame
135138
};
136139

137140
var Symbol = {

src/scheduler/AnimationFrameAction.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {Action} from './Action';
2+
import {FutureAction} from './FutureAction';
3+
import {AnimationFrame} from '../util/AnimationFrame';
4+
5+
export class AnimationFrameAction<T> extends FutureAction<T> {
6+
7+
_schedule(state?: any, delay: number = 0): Action {
8+
if (delay > 0) {
9+
return super._schedule(state, delay);
10+
}
11+
this.delay = delay;
12+
this.state = state;
13+
const {scheduler} = this;
14+
scheduler.actions.push(this);
15+
if (!scheduler.scheduledId) {
16+
scheduler.scheduledId = AnimationFrame.requestAnimationFrame(() => {
17+
scheduler.scheduledId = null;
18+
scheduler.flush();
19+
});
20+
}
21+
return this;
22+
}
23+
24+
_unsubscribe(): void {
25+
26+
const {scheduler} = this;
27+
const {scheduledId, actions} = scheduler;
28+
29+
super._unsubscribe();
30+
31+
if (actions.length === 0) {
32+
scheduler.active = false;
33+
if (scheduledId != null) {
34+
scheduler.scheduledId = null;
35+
AnimationFrame.cancelAnimationFrame(scheduledId);
36+
}
37+
}
38+
}
39+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {Action} from './Action';
2+
import {Subscription} from '../Subscription';
3+
import {QueueScheduler} from './QueueScheduler';
4+
import {AnimationFrameAction} from './AnimationFrameAction';
5+
6+
export class AnimationFrameScheduler extends QueueScheduler {
7+
scheduleNow<T>(work: (x?: any) => Subscription, state?: any): Action {
8+
return new AnimationFrameAction(this, work).schedule(state);
9+
}
10+
}

src/scheduler/AsapScheduler.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {Subscription} from '../Subscription';
44
import {QueueScheduler} from './QueueScheduler';
55

66
export class AsapScheduler extends QueueScheduler {
7-
public scheduledId: number = null;
87
scheduleNow<T>(work: (x?: any) => Subscription, state?: any): Action {
98
return new AsapAction(this, work).schedule(state);
109
}

src/scheduler/animationFrame.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import {AnimationFrameScheduler} from './AnimationFrameScheduler';
2+
3+
export const animationFrame = new AnimationFrameScheduler();

src/util/AnimationFrame.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { root } from './root';
2+
3+
export class RequestAnimationFrameDefinition {
4+
cancelAnimationFrame: (handle: number) => void;
5+
requestAnimationFrame: (cb: () => void) => number;
6+
constructor(root: any) {
7+
if (root.requestAnimationFrame) {
8+
this.cancelAnimationFrame = root.cancelAnimationFrame;
9+
this.requestAnimationFrame = root.requestAnimationFrame;
10+
} else if (root.mozRequestAnimationFrame) {
11+
this.cancelAnimationFrame = root.mozCancelAnimationFrame;
12+
this.requestAnimationFrame = root.mozRequestAnimationFrame;
13+
} else if (root.webkitRequestAnimationFrame) {
14+
this.cancelAnimationFrame = root.webkitCancelAnimationFrame;
15+
this.requestAnimationFrame = root.webkitRequestAnimationFrame;
16+
} else if (root.msRequestAnimationFrame) {
17+
this.cancelAnimationFrame = root.msCancelAnimationFrame;
18+
this.requestAnimationFrame = root.msRequestAnimationFrame;
19+
} else if (root.oRequestAnimationFrame) {
20+
this.cancelAnimationFrame = root.oCancelAnimationFrame;
21+
this.requestAnimationFrame = root.oRequestAnimationFrame;
22+
} else {
23+
this.cancelAnimationFrame = root.clearTimeout;
24+
this.requestAnimationFrame = function(cb) { return root.setTimeout(cb, 1000 / 60); };
25+
}
26+
}
27+
}
28+
29+
export const AnimationFrame = new RequestAnimationFrameDefinition(root);

0 commit comments

Comments
 (0)