summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/scroll-animations/scroll-timelines/setting-playback-rate.html
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/scroll-animations/scroll-timelines/setting-playback-rate.html')
-rw-r--r--testing/web-platform/tests/scroll-animations/scroll-timelines/setting-playback-rate.html323
1 files changed, 323 insertions, 0 deletions
diff --git a/testing/web-platform/tests/scroll-animations/scroll-timelines/setting-playback-rate.html b/testing/web-platform/tests/scroll-animations/scroll-timelines/setting-playback-rate.html
new file mode 100644
index 0000000000..4d6fecae05
--- /dev/null
+++ b/testing/web-platform/tests/scroll-animations/scroll-timelines/setting-playback-rate.html
@@ -0,0 +1,323 @@
+<!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.source;
+ // 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_percents_equal(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.source;
+ // 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_percents_equal(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.source;
+ 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.playbackRate = 0.5;
+ animation.play();
+ await animation.ready;
+ assert_percents_equal(animation.currentTime, 10,
+ '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.source;
+ const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+ 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_percents_equal(animation.currentTime, 40,
+ 'The current time is scaled by the playback rate.');
+ }, 'The current time is scaled by playbackRate set while the ' +
+ 'scroll-linked animation is in play state.');
+
+ promise_test(async t => {
+ const animation = createScrollLinkedAnimation(t);
+ const scroller = animation.timeline.source;
+ const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+
+ // 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_percents_equal(animation.currentTime, 40,
+ '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.source;
+ 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_percents_equal(
+ animation.currentTime,
+ animation.timeline.currentTime.value * 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.source;
+ 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_percents_equal(animation.currentTime, 50);
+ }, 'Setting the playback rate while play-pending scales the current time' +
+ ' from scrollTimeline.');
+
+ test(t => {
+ const animation = createScrollLinkedAnimation(t);
+ animation.play();
+ animation.currentTime = CSSNumericValue.parse("25%");
+ animation.playbackRate = 2;
+
+ assert_equals(animation.playState, "running");
+ assert_true(animation.pending);
+ assert_percents_equal(animation.currentTime, 50);
+ }, 'Setting the playback rate while play-pending scales the set current' +
+ ' time.');
+
+ promise_test(async t => {
+ const animation = createScrollLinkedAnimation(t);
+ const scroller = animation.timeline.source;
+ 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();
+ assert_percents_equal(animation.currentTime, 25);
+
+ await animation.ready;
+ animation.playbackRate = 2;
+
+ assert_percents_equal(animation.currentTime, 50);
+ }, 'Setting the playback rate while playing scales 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 = CSSNumericValue.parse("25%");
+ await animation.ready;
+ animation.playbackRate = 2;
+
+ assert_percents_equal(animation.currentTime, 50);
+ }, 'Setting the playback rate while playing scales the set current time.');
+
+ promise_test(async t => {
+ const animation = createScrollLinkedAnimation(t);
+ const scroller = animation.timeline.source;
+ const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+ 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 = 100 - animation.timeline.currentTime.value;
+ assert_percents_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.source;
+ 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_percents_equal(startingCurrentTime, 50);
+ assert_percents_equal(startingTimelineTime, 50);
+
+ animation.playbackRate = -1;
+
+ scroller.scrollTop = 0.8 * maxScroll;
+ await waitForNextFrame();
+ // -300 = 500 - 800
+
+ // let timelineDiff =
+ // startingTimelineTime.value - animation.timeline.currentTime.value;
+ // // 200 = 500 + (-300)
+ // let expected = startingCurrentTime.value + timelineDiff;
+ assert_percents_equal(animation.timeline.currentTime, 80);
+ assert_percents_equal(animation.currentTime, 20);
+
+ scroller.scrollTop = 0.2 * maxScroll;
+ await waitForNextFrame();
+ // // 300 = 500 - 200
+ // timelineDiff =
+ // startingTimelineTime.value - animation.timeline.currentTime.value;
+ // // 800 = 500 + 300
+ // expected = startingCurrentTime.value + timelineDiff;
+ assert_percents_equal(animation.timeline.currentTime, 20);
+ assert_percents_equal(animation.currentTime, 80);
+ }, '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.source;
+ const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+ 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_percents_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.source;
+ 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_percents_equal(animation.currentTime, 20);
+ animation.playbackRate = 0;
+ scroller.scrollTop = 0.5 * maxScroll;
+ await waitForNextFrame();
+
+ // Ensure that current time does not change.
+ assert_percents_equal(animation.timeline.currentTime, 50);
+ assert_percents_equal(animation.currentTime, 0);
+ }, 'Setting a zero playback rate while running preserves the start time');
+
+
+promise_test(async t => {
+ const animation = createScrollLinkedAnimation(t);
+ const scroller = animation.timeline.source;
+ 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_percents_equal(animation.timeline.currentTime, 20);
+ assert_percents_equal(animation.currentTime, 20);
+ animation.startTime = animation.currentTime;
+ // timeline current time [0%, 100%] --> animation current time [-20%, 80%].
+ assert_percents_equal(animation.currentTime, 0);
+
+ animation.playbackRate = -1;
+ // timeline current time [0%, 100%] --> animation current time [80%, -20%].
+ // timeline @ 20% --> animation current time @ (20% - 80%) * (-1) = 60%.
+ assert_percents_equal(animation.timeline.currentTime, 20);
+ assert_percents_equal(animation.currentTime, 60);
+ }, 'Reversing an animation with non-boundary aligned start time ' +
+ 'symmetrically adjusts the start time');
+
+</script>
+</body>