Skip to content

[scroll-animations][web-animations-2] rewinding a finished scroll-driven animation and playing it again #11270

Open
@graouts

Description

@graouts

I'm working on the WebKit implementation of Scroll-driven Animations and am having issues making the "Animation finish event is fired again after replaying from start" subtest of scroll-animations/scroll-timelines/updating-the-finished-state.html work. The goal of that test is to "scrub" a scroll-driven animation to its finished state and then reset it back to its 0% time to play again.

Here's a slightly reduced self-contained test with some logging to query the timeline and animation state in that case:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body style="height: 200vh">
<div></div>
<script>

(async function () {
    const timeline = new ScrollTimeline({ source: document.documentElement });
    const animation = document.querySelector("div").animate({ "marginLeft": "100px" }, { timeline });

    const log = msg => {
        console.log(`${msg}\ntimeline time = ${timeline.currentTime}, animation time = ${animation.currentTime}, animation start time = ${animation.startTime}`);
    };

    await animation.ready;
    log("1. After animation readiness");

    const maxScroll = timeline.source.scrollHeight - timeline.source.clientHeight;
    timeline.source.scrollTop = maxScroll;
    await new Promise(requestAnimationFrame);
    log("2. After scrolling to 100% and waiting one frame");

    timeline.source.scrollTop = 0;
    animation.play();
    log("3. After scrolling back to 0% and calling play()");

    await new Promise(requestAnimationFrame);
    log("4. After animation readiness");
})();

</script>  
</body>
</html>

Chrome Canary

1. After animation readiness
timeline time = 0%, animation time = 0%, animation start time = 0%

2. After scrolling to 100% and waiting one frame
timeline time = 100%, animation time = 100%, animation start time = 0%

3. After scrolling back to 0% and calling play()
timeline time = 100%, animation time = 100%, animation start time = null

4. After animation readiness
timeline time = 0%, animation time = 0%, animation start time = 0%

WebKit

1. After animation readiness
timeline time = 0%, animation time = 0%, animation start time = 0%

2. After scrolling to 100% and waiting one frame
timeline time = 100%, animation time = 100%, animation start time = 0%

3. After scrolling back to 0% and calling play()
timeline time = 100%, animation time = 100%, animation start time = null

4. After animation readiness
timeline time = 0%, animation time = 100%, animation start time = -100%

The logging is identical in Chrome Canary and WebKit up until we rewind the animation and play it again. The result of what happens in Chrome makes complete sense, but I'm reading the spec over and over and failing to see what should be happening to match the Chrome behavior.

The internal state as play() is called is as follows:

hold time = 100%
start time = unresolved

And then as the pending play task is performed:

ready time = 0%
start time = ready time - hold time (100%) = -100%
hold time = unresolved

Can someone read the spec in a way that yields a different result for the values seen during the performance of the pending play task?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions