1 | import { queueMacrotask } from '../utils/macrotask-scheduler';
|
2 | import { FPSCallback } from '../fps-meter/fps-native';
|
3 | import { getTimeInFrameBase } from './animation-native';
|
4 | import { Trace } from '../trace';
|
5 | let animationId = 0;
|
6 | let currentFrameAnimationCallbacks = {};
|
7 | let currentFrameScheduled = false;
|
8 | let nextFrameAnimationCallbacks = {};
|
9 | let shouldStop = true;
|
10 | let inAnimationFrame = false;
|
11 | let fpsCallback;
|
12 | let lastFrameTime = 0;
|
13 | function getNewId() {
|
14 | return animationId++;
|
15 | }
|
16 | function ensureNative() {
|
17 | if (fpsCallback) {
|
18 | return;
|
19 | }
|
20 | fpsCallback = new FPSCallback(doFrame);
|
21 | }
|
22 | function 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 | }
|
37 | function doCurrentFrame() {
|
38 |
|
39 |
|
40 | if (!fpsCallback || !fpsCallback.running) {
|
41 | lastFrameTime = getTimeInFrameBase();
|
42 | }
|
43 | currentFrameScheduled = false;
|
44 | const thisFrameCbs = currentFrameAnimationCallbacks;
|
45 | currentFrameAnimationCallbacks = {};
|
46 | callAnimationCallbacks(thisFrameCbs, lastFrameTime);
|
47 | }
|
48 | function doFrame(currentTimeMillis) {
|
49 | lastFrameTime = currentTimeMillis;
|
50 | shouldStop = true;
|
51 | const thisFrameCbs = nextFrameAnimationCallbacks;
|
52 | nextFrameAnimationCallbacks = {};
|
53 | callAnimationCallbacks(thisFrameCbs, lastFrameTime);
|
54 | if (shouldStop) {
|
55 | fpsCallback.stop();
|
56 | }
|
57 | }
|
58 | function ensureCurrentFrameScheduled() {
|
59 | if (!currentFrameScheduled) {
|
60 | currentFrameScheduled = true;
|
61 | queueMacrotask(doCurrentFrame);
|
62 | }
|
63 | }
|
64 | export 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 | }
|
77 | export function cancelAnimationFrame(id) {
|
78 | delete currentFrameAnimationCallbacks[id];
|
79 | delete nextFrameAnimationCallbacks[id];
|
80 | }
|
81 |
|
\ | No newline at end of file |