blob: ceb430b718b8438c933071b1dd24240ab13bf562 (
plain)
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
|
'use strict';
function registerPassthroughAnimator() {
return runInAnimationWorklet(`
registerAnimator('passthrough', class {
animate(currentTime, effect) {
effect.localTime = currentTime;
}
});
`);
}
function registerConstantLocalTimeAnimator(localTime) {
return runInAnimationWorklet(`
registerAnimator('constant_time', class {
animate(currentTime, effect) { effect.localTime = ${localTime}; }
});
`);
}
function runInAnimationWorklet(code) {
return CSS.animationWorklet.addModule(
URL.createObjectURL(new Blob([code], {type: 'text/javascript'}))
);
}
function approxEquals(actual, expected){
// precision in ms
const epsilon = 0.005;
const lowerBound = (expected - epsilon) < actual;
const upperBound = (expected + epsilon) > actual;
return lowerBound && upperBound;
}
function waitForAsyncAnimationFrames(count) {
// In Chrome, waiting for N+1 main thread frames guarantees that compositor has produced
// at least N frames.
// TODO(majidvp): re-evaluate this choice once other browsers have implemented
// AnimationWorklet.
return waitForAnimationFrames(count + 1);
}
async function waitForAnimationFrameWithCondition(condition) {
do {
await new Promise(window.requestAnimationFrame);
} while (!condition())
}
async function waitForDocumentTimelineAdvance() {
const timeAtStart = document.timeline.currentTime;
do {
await new Promise(window.requestAnimationFrame);
} while (timeAtStart === document.timeline.currentTime)
}
// Wait until animation's effect has a non-null localTime.
async function waitForNotNullLocalTime(animation) {
await waitForAnimationFrameWithCondition(_ => {
return animation.effect.getComputedTiming().localTime !== null;
});
}
|