UNPKG

2.81 kBJavaScriptView Raw
1import { queueMacrotask } from '../utils/macrotask-scheduler';
2import { FPSCallback } from '../fps-meter/fps-native';
3import { getTimeInFrameBase } from './animation-native';
4import { Trace } from '../trace';
5let animationId = 0;
6let currentFrameAnimationCallbacks = {}; // requests that were scheduled in this frame and must be called ASAP
7let currentFrameScheduled = false;
8let nextFrameAnimationCallbacks = {}; // requests there were scheduled in another request and must be called in the next frame
9let shouldStop = true;
10let inAnimationFrame = false;
11let fpsCallback;
12let lastFrameTime = 0;
13function getNewId() {
14 return animationId++;
15}
16function ensureNative() {
17 if (fpsCallback) {
18 return;
19 }
20 fpsCallback = new FPSCallback(doFrame);
21}
22function callAnimationCallbacks(thisFrameCbs, frameTime) {
23 inAnimationFrame = true;
24 for (const animationId in thisFrameCbs) {
25 if (thisFrameCbs[animationId]) {
26 try {
27 thisFrameCbs[animationId](frameTime);
28 }
29 catch (err) {
30 const msg = err ? err.stack || err : err;
31 Trace.write(`Error in requestAnimationFrame: ${msg}`, Trace.categories.Error, Trace.messageType.error);
32 }
33 }
34 }
35 inAnimationFrame = false;
36}
37function doCurrentFrame() {
38 // if we're not getting accurate frame times
39 // set last frame time as the current time
40 if (!fpsCallback || !fpsCallback.running) {
41 lastFrameTime = getTimeInFrameBase();
42 }
43 currentFrameScheduled = false;
44 const thisFrameCbs = currentFrameAnimationCallbacks;
45 currentFrameAnimationCallbacks = {};
46 callAnimationCallbacks(thisFrameCbs, lastFrameTime);
47}
48function doFrame(currentTimeMillis) {
49 lastFrameTime = currentTimeMillis;
50 shouldStop = true;
51 const thisFrameCbs = nextFrameAnimationCallbacks;
52 nextFrameAnimationCallbacks = {};
53 callAnimationCallbacks(thisFrameCbs, lastFrameTime);
54 if (shouldStop) {
55 fpsCallback.stop(); // TODO: check performance without stopping to allow consistent frame times
56 }
57}
58function ensureCurrentFrameScheduled() {
59 if (!currentFrameScheduled) {
60 currentFrameScheduled = true;
61 queueMacrotask(doCurrentFrame);
62 }
63}
64export function requestAnimationFrame(cb) {
65 const animId = getNewId();
66 if (!inAnimationFrame) {
67 ensureCurrentFrameScheduled();
68 currentFrameAnimationCallbacks[animId] = zonedCallback(cb);
69 return animId;
70 }
71 ensureNative();
72 nextFrameAnimationCallbacks[animId] = zonedCallback(cb);
73 shouldStop = false;
74 fpsCallback.start();
75 return animId;
76}
77export function cancelAnimationFrame(id) {
78 delete currentFrameAnimationCallbacks[id];
79 delete nextFrameAnimationCallbacks[id];
80}
81//# sourceMappingURL=index.js.map
\No newline at end of file