blob: e71d933be1a8e494f4cd556184e974c8635b5d28 [file] [log] [blame]
<!DOCTYPE html>
<meta charset=utf-8>
<title>Setting the playback rate of an animation that is using a ScrollTimeline</title>
<link rel="help" href="https://drafts.csswg.org/web-animations/#setting-the-playback-rate-of-an-animation">
<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);
const scroller = animation.timeline.scrollSource;
// this forces a layout which results in an active timeline
scroller.scrollTop = 0;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.playbackRate = 0.5;
animation.play();
assert_equals(animation.currentTime, 0,
'Zero current time is not affected by playbackRate change.');
}, 'Zero current time is not affected by playbackRate set while the ' +
'animation is in idle state.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
// this forces a layout which results in an active timeline
scroller.scrollTop = 0;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
animation.playbackRate = 0.5;
assert_equals(animation.currentTime, 0,
'Zero current time is not affected by playbackRate change.');
}, 'Zero current time is not affected by playbackRate set while the ' +
'animation is in play-pending state.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
const timeRange = animation.timeline.timeRange;
scroller.scrollTop = 0.2 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.playbackRate = 0.5;
animation.play();
await animation.ready;
assert_equals(animation.currentTime, 0.2 * timeRange * 0.5,
'Initial current time is scaled by playbackRate change.');
}, 'Initial current time is scaled by playbackRate set while ' +
'scroll-linked animation is in running state.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
const timeRange = animation.timeline.timeRange;
const playbackRate = 2;
scroller.scrollTop = 0.2 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
// Set playback rate while the animation is playing.
animation.playbackRate = playbackRate;
assert_times_equal(animation.currentTime, 0.2 * timeRange,
'The current time should stay unaffected by setting playback rate.');
}, 'The current time is not affected by playbackRate set while the ' +
'scroll-linked animation is in play state.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
const timeRange = animation.timeline.timeRange;
// Set playback rate while the animation is in 'idle' state.
animation.playbackRate = 2;
animation.play();
await animation.ready;
scroller.scrollTop = 0.2 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
assert_times_equal(animation.currentTime, 0.2 * timeRange * 2,
'The current time should increase two times faster than timeline time.');
}, 'The playback rate set before scroll-linked animation started playing ' +
'affects the rate of progress of the current time');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
animation.play();
await animation.ready;
animation.playbackRate = 2;
scroller.scrollTop = 0.25 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
assert_times_equal(
animation.currentTime,
animation.timeline.currentTime * animation.playbackRate,
'The current time should increase two times faster than timeline time'
);
}, 'The playback rate affects the rate of progress of the current time' +
' when scrolling');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.25 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
animation.playbackRate = 2;
assert_equals(animation.playState, "running");
assert_true(animation.pending);
assert_times_equal(animation.currentTime, animation.timeline.currentTime);
}, 'Setting the playback rate while play-pending preserves the current time' +
' from scrollTimeline.');
test(t => {
const animation = createScrollLinkedAnimation(t);
animation.play();
animation.currentTime = 250;
animation.playbackRate = 2;
assert_equals(animation.playState, "running");
assert_true(animation.pending);
assert_times_equal(animation.currentTime, 250);
}, 'Setting the playback rate while play-pending preserves the set current' +
' time.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.25 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
animation.playbackRate = 2;
assert_times_equal(animation.currentTime, animation.timeline.currentTime);
}, 'Setting the playback rate while playing preserves the current time' +
' from scrollTimeline.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
/* Wait for animation frame is here for now to avoid a renderer crash
caused by crbug.com/1042924. Once that is fixed, these can be removed */
await waitForAnimationFrames(2);
animation.play();
animation.currentTime = 250;
await animation.ready;
animation.playbackRate = 2;
assert_times_equal(animation.currentTime, 250);
}, 'Setting the playback rate while playing preserves the set current time.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
const range = animation.timeline.timeRange;
animation.playbackRate = -1;
scroller.scrollTop = 0.3 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
const expectedCurrentTime = range - animation.timeline.currentTime;
assert_times_equal(animation.currentTime, expectedCurrentTime);
}, 'Negative initial playback rate should correctly modify initial current' +
' time.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.5 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
const startingTimelineTime = animation.timeline.currentTime;
const startingCurrentTime = animation.currentTime;
assert_times_equal(startingCurrentTime, startingTimelineTime);
animation.playbackRate = -1;
scroller.scrollTop = 0.8 * maxScroll;
await waitForNextFrame();
// -300 = 500 - 800
let timelineDiff = startingTimelineTime - animation.timeline.currentTime;
// 200 = 500 + (-300)
let expected = startingCurrentTime + timelineDiff;
assert_times_equal(animation.currentTime, expected);
scroller.scrollTop = 0.2 * maxScroll;
await waitForNextFrame();
// 300 = 500 - 200
timelineDiff = startingTimelineTime - animation.timeline.currentTime;
// 800 = 500 + 300
expected = startingCurrentTime + timelineDiff;
assert_times_equal(animation.currentTime, expected);
}, 'Reversing the playback rate while playing correctly impacts current' +
' time during future scrolls');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
const range = animation.timeline.timeRange;
animation.playbackRate = 0;
scroller.scrollTop = 0.3 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
assert_times_equal(animation.currentTime, 0);
}, 'Zero initial playback rate should correctly modify initial current' +
' time.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.2 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
assert_times_equal(animation.currentTime, 200);
animation.playbackRate = 0;
scroller.scrollTop = 0.5 * maxScroll;
await waitForNextFrame();
// Ensure that current time does not change.
assert_time_equals_literal(animation.timeline.currentTime, 500);
assert_time_equals_literal(animation.currentTime, 200);
}, 'Setting a zero playback rate while running preserves the current time');
</script>
</body>