-
-
Notifications
You must be signed in to change notification settings - Fork 125
/
now.ts
77 lines (72 loc) · 2.18 KB
/
now.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import {fromResource, IResource} from "./from-resource";
const tickers:
{
[interval: string]: IResource<number>
}
= ({});
/**
* Returns the current date time as epoch number.
* The date time is read from an observable which is updated automatically after the given interval.
* So basically it treats time as an observable.
*
* The function takes an interval as parameter, which indicates how often `now()` will return a new value.
* If no interval is given, it will update each second. If "frame" is specified, it will update each time a
* `requestAnimationFrame` is available.
*
* Multiple clocks with the same interval will automatically be synchronized.
*
* @example
*
* const start = Date.now()
*
* autorun(() => {
* console.log("Seconds elapsed: ", (mobxUtils.now() - start) / 1000)
* })
*
*
* @export
* @param {(number | "frame")} [interval=1000] interval in milliseconds about how often the interval should update
* @returns
*/
export function now(interval: number | "frame" = 1000) {
if (!tickers[interval]) {
if (typeof interval === "number")
tickers[interval] = createIntervalTicker(interval);
else
tickers[interval] = createAnimationFrameTicker();
}
return tickers[interval].current();
}
function createIntervalTicker(interval: number): IResource<number> {
let subscriptionHandle: number;
return fromResource<number>(
sink => {
subscriptionHandle = setInterval(
() => sink(Date.now()),
interval
);
},
() => {
clearInterval(subscriptionHandle);
},
Date.now()
);
}
function createAnimationFrameTicker(): IResource<number> {
let subscriptionHandle: number;
const frameBasedTicker = fromResource<number>(
sink => {
function scheduleTick() {
window.requestAnimationFrame(() => {
sink(Date.now());
if (frameBasedTicker.isAlive())
scheduleTick();
});
}
scheduleTick();
},
() => { },
Date.now()
);
return frameBasedTicker;
}