Skip to content

Commit

Permalink
Update handling of changes to playback rate for a scroll-linked anima…
Browse files Browse the repository at this point in the history
…tion

* Preserve start time when updating playback rate for a scroll-linked
  animation.
* If changing playback rate for < 0 to >= 0 or vice versa, and start
  time is resolved:
  start time = effect end - start time.

Spec issue is here: w3c/csswg-drafts#2075

Bug: 1393060
Change-Id: I1afc5618decc8fdf245a230ae4af7de87ee8caf7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4060553
Reviewed-by: Robert Flack <[email protected]>
Commit-Queue: Kevin Ellis <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1078080}
  • Loading branch information
kevers-google authored and chromium-wpt-export-bot committed Dec 1, 2022
1 parent 74e7619 commit b8e1b9e
Showing 1 changed file with 56 additions and 26 deletions.
82 changes: 56 additions & 26 deletions scroll-animations/scroll-timelines/setting-playback-rate.html
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@
await animation.ready;
// Set playback rate while the animation is playing.
animation.playbackRate = playbackRate;
assert_percents_equal(animation.currentTime, 20,
'The current time should stay unaffected by setting playback rate.');
}, 'The current time is not affected by playbackRate set while the ' +
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 => {
Expand Down Expand Up @@ -148,9 +148,8 @@

assert_equals(animation.playState, "running");
assert_true(animation.pending);
assert_percents_equal(
animation.currentTime, animation.timeline.currentTime);
}, 'Setting the playback rate while play-pending preserves the current time' +
assert_percents_equal(animation.currentTime, 50);
}, 'Setting the playback rate while play-pending scales the current time' +
' from scrollTimeline.');

test(t => {
Expand All @@ -161,8 +160,8 @@

assert_equals(animation.playState, "running");
assert_true(animation.pending);
assert_percents_equal(animation.currentTime, 25);
}, 'Setting the playback rate while play-pending preserves the set current' +
assert_percents_equal(animation.currentTime, 50);
}, 'Setting the playback rate while play-pending scales the set current' +
' time.');

promise_test(async t => {
Expand All @@ -174,13 +173,13 @@
// current time.
await waitForNextFrame();
animation.play();
assert_percents_equal(animation.currentTime, 25);

await animation.ready;
animation.playbackRate = 2;

assert_percents_equal(
animation.currentTime, animation.timeline.currentTime);
}, 'Setting the playback rate while playing preserves the current time' +
assert_percents_equal(animation.currentTime, 50);
}, 'Setting the playback rate while playing scales the current time' +
' from scrollTimeline.');

promise_test(async t => {
Expand All @@ -196,8 +195,8 @@
await animation.ready;
animation.playbackRate = 2;

assert_percents_equal(animation.currentTime, 25);
}, 'Setting the playback rate while playing preserves the set current time.');
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);
Expand Down Expand Up @@ -229,27 +228,31 @@
await animation.ready;
const startingTimelineTime = animation.timeline.currentTime;
const startingCurrentTime = animation.currentTime;
assert_percents_equal(startingCurrentTime, startingTimelineTime);
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.currentTime, expected);

// 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.currentTime, expected);
// // 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');

Expand Down Expand Up @@ -287,7 +290,34 @@

// 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);
}, 'Setting a zero playback rate while running preserves the current time');
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>

0 comments on commit b8e1b9e

Please sign in to comment.