61 lines
No EOL
1.7 KiB
JavaScript
61 lines
No EOL
1.7 KiB
JavaScript
'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;
|
|
});
|
|
} |