mirror of
https://github.com/servo/servo.git
synced 2025-10-09 13:09:25 +01:00
240 lines
8.3 KiB
HTML
240 lines
8.3 KiB
HTML
<!DOCTYPE html>
|
|
<meta charset=utf-8>
|
|
<title>Reversing an animation</title>
|
|
<link rel="help"
|
|
href="https://drafts.csswg.org/web-animations/#reversing-an-animation-section">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/web-animations/testcommon.js"></script>
|
|
<script src="testcommon.js"></script>
|
|
<style>
|
|
.scroller {
|
|
overflow: auto;
|
|
height: 100px;
|
|
width: 100px;
|
|
will-change: transform;
|
|
}
|
|
|
|
.contents {
|
|
height: 1000px;
|
|
width: 100%;
|
|
}
|
|
</style>
|
|
<body>
|
|
<script>
|
|
'use strict';
|
|
|
|
promise_test(async t => {
|
|
const animation = createScrollLinkedAnimation(t);
|
|
// Wait for new animation frame which allows the timeline to compute new
|
|
// current time.
|
|
await waitForNextFrame();
|
|
animation.play();
|
|
await animation.ready;
|
|
|
|
animation.currentTime = CSSNumericValue.parse("50%");
|
|
const previousPlaybackRate = animation.playbackRate;
|
|
animation.reverse();
|
|
assert_equals(animation.playbackRate, previousPlaybackRate,
|
|
'Playback rate should not have changed');
|
|
await animation.ready;
|
|
|
|
assert_equals(animation.playbackRate, -previousPlaybackRate,
|
|
'Playback rate should be inverted');
|
|
}, 'Reversing an animation inverts the playback rate');
|
|
|
|
promise_test(async t => {
|
|
const animation = createScrollLinkedAnimation(t);
|
|
// Wait for new animation frame which allows the timeline to compute new
|
|
// current time.
|
|
await waitForNextFrame();
|
|
animation.play();
|
|
animation.currentTime = CSSNumericValue.parse("50%");
|
|
animation.reverse();
|
|
|
|
assert_percents_equal(animation.currentTime, 50,
|
|
'The current time should not change it is in the ' +
|
|
'middle of the animation duration');
|
|
}, 'Reversing an animation maintains the same current time');
|
|
|
|
promise_test(async t => {
|
|
const animation = createScrollLinkedAnimation(t);
|
|
// Wait for new animation frame which allows the timeline to compute new
|
|
// current time.
|
|
await waitForNextFrame();
|
|
animation.play();
|
|
assert_true(animation.pending,
|
|
'The animation is pending before we call reverse');
|
|
|
|
animation.reverse();
|
|
|
|
assert_true(animation.pending,
|
|
'The animation is still pending after calling reverse');
|
|
}, 'Reversing an animation does not cause it to leave the pending state');
|
|
|
|
promise_test(async t => {
|
|
const animation = createScrollLinkedAnimation(t);
|
|
// Wait for new animation frame which allows the timeline to compute new
|
|
// current time.
|
|
await waitForNextFrame();
|
|
animation.play();
|
|
let readyResolved = false;
|
|
animation.ready.then(() => { readyResolved = true; });
|
|
|
|
animation.reverse();
|
|
|
|
await Promise.resolve();
|
|
assert_false(readyResolved,
|
|
'ready promise should not have been resolved yet');
|
|
}, 'Reversing an animation does not cause it to resolve the ready promise');
|
|
|
|
promise_test(async t => {
|
|
const animation = createScrollLinkedAnimation(t);
|
|
// Wait for new animation frame which allows the timeline to compute new
|
|
// current time.
|
|
await waitForNextFrame();
|
|
animation.play();
|
|
animation.currentTime = CSSNumericValue.parse("200%");
|
|
animation.reverse();
|
|
|
|
assert_percents_equal(animation.currentTime, 100,
|
|
'reverse() should start playing from the animation ' +
|
|
'effect end if the playbackRate > 0 and the ' +
|
|
'currentTime > effect end');
|
|
}, 'Reversing an animation when playbackRate > 0 and currentTime > effect ' +
|
|
'end should make it play from the end');
|
|
|
|
promise_test(async t => {
|
|
const animation = createScrollLinkedAnimation(t);
|
|
// Wait for new animation frame which allows the timeline to compute new
|
|
// current time.
|
|
await waitForNextFrame();
|
|
animation.play();
|
|
|
|
animation.currentTime = CSSNumericValue.parse("-200%");
|
|
animation.reverse();
|
|
|
|
assert_percents_equal(animation.currentTime, 100,
|
|
'reverse() should start playing from the animation ' +
|
|
'effect end if the playbackRate > 0 and the ' +
|
|
'currentTime < 0');
|
|
}, 'Reversing an animation when playbackRate > 0 and currentTime < 0 should ' +
|
|
'make it play from the end');
|
|
|
|
promise_test(async t => {
|
|
const animation = createScrollLinkedAnimation(t);
|
|
// Wait for new animation frame which allows the timeline to compute new
|
|
// current time.
|
|
await waitForNextFrame();
|
|
animation.play();
|
|
animation.playbackRate = -1;
|
|
animation.currentTime = CSSNumericValue.parse("-200%");
|
|
animation.reverse();
|
|
|
|
assert_percents_equal(animation.currentTime, 0,
|
|
'reverse() should start playing from the start of ' +
|
|
'animation time if the playbackRate < 0 and the ' +
|
|
'currentTime < 0');
|
|
}, 'Reversing an animation when playbackRate < 0 and currentTime < 0 should ' +
|
|
'make it play from the start');
|
|
|
|
promise_test(async t => {
|
|
const animation = createScrollLinkedAnimation(t);
|
|
// Wait for new animation frame which allows the timeline to compute new
|
|
// current time.
|
|
await waitForNextFrame();
|
|
animation.play();
|
|
animation.playbackRate = -1;
|
|
animation.currentTime = CSSNumericValue.parse("200%");
|
|
animation.reverse();
|
|
|
|
assert_percents_equal(animation.currentTime, 0,
|
|
'reverse() should start playing from the start of ' +
|
|
'animation time if the playbackRate < 0 and the ' +
|
|
'currentTime > effect end');
|
|
}, 'Reversing an animation when playbackRate < 0 and currentTime > effect ' +
|
|
'end should make it play from the start');
|
|
|
|
promise_test(async t => {
|
|
const animation = createScrollLinkedAnimation(t);
|
|
// Wait for new animation frame which allows the timeline to compute new
|
|
// current time.
|
|
await waitForNextFrame();
|
|
animation.play();
|
|
animation.playbackRate = 0;
|
|
animation.currentTime = CSSNumericValue.parse("50%");
|
|
animation.reverse();
|
|
|
|
await animation.ready;
|
|
assert_equals(animation.playbackRate, 0,
|
|
'reverse() should preserve playbackRate if the playbackRate == 0');
|
|
assert_percents_equal(animation.currentTime, 50,
|
|
'reverse() should not affect the currentTime if the playbackRate == 0');
|
|
}, 'Reversing when when playbackRate == 0 should preserve the current time ' +
|
|
'and playback rate');
|
|
|
|
promise_test(async t => {
|
|
const animation = createScrollLinkedAnimation(t);
|
|
// Wait for new animation frame which allows the timeline to compute new
|
|
// current time.
|
|
await waitForNextFrame();
|
|
assert_equals(animation.currentTime, null);
|
|
|
|
animation.reverse();
|
|
await animation.ready;
|
|
|
|
assert_percents_equal(animation.startTime, 100,
|
|
'animation.startTime should be at its effect end');
|
|
assert_percents_equal(animation.currentTime, 100,
|
|
'animation.currentTime should be at its effect end');
|
|
}, 'Reversing an idle animation from starts playing the animation');
|
|
|
|
promise_test(async t => {
|
|
const animation = createScrollLinkedAnimation(t);
|
|
const scroller = animation.timeline.source;
|
|
// Make the scroll timeline inactive.
|
|
scroller.style.overflow = 'visible';
|
|
scroller.scrollTop;
|
|
// Wait for new animation frame which allows the timeline to compute new
|
|
// current time.
|
|
await waitForNextFrame();
|
|
|
|
assert_throws_dom('InvalidStateError', () => { animation.reverse(); });
|
|
}, 'Reversing an animation without an active timeline throws an ' +
|
|
'InvalidStateError');
|
|
|
|
promise_test(async t => {
|
|
const animation = createScrollLinkedAnimation(t);
|
|
// Wait for new animation frame which allows the timeline to compute new
|
|
// current time.
|
|
await waitForNextFrame();
|
|
animation.play();
|
|
animation.currentTime = CSSNumericValue.parse("50%");
|
|
animation.pause();
|
|
|
|
await animation.ready;
|
|
|
|
animation.reverse();
|
|
await animation.ready;
|
|
|
|
assert_equals(animation.playState, 'running',
|
|
'Animation.playState should be "running" after reverse()');
|
|
}, 'Reversing an animation plays a pausing animation');
|
|
|
|
promise_test(async t => {
|
|
const animation = createScrollLinkedAnimation(t);
|
|
// Wait for new animation frame which allows the timeline to compute new
|
|
// current time.
|
|
await waitForNextFrame();
|
|
animation.play();
|
|
await animation.ready;
|
|
|
|
animation.updatePlaybackRate(2);
|
|
animation.reverse();
|
|
|
|
await animation.ready;
|
|
assert_equals(animation.playbackRate, -2);
|
|
}, 'Reversing should use the negative pending playback rate');
|
|
|
|
</script>
|
|
</body>
|