| Summary: | [web-animations] setting currentTime=0 when animation-play-state=paused, doesn't restart animation after unpausing it | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| Product: | WebKit | Reporter: | em_te | ||||||
| Component: | Animations | Assignee: | Antoine Quint <graouts> | ||||||
| Status: | RESOLVED FIXED | ||||||||
| Severity: | Normal | CC: | dino, graouts, graouts, karlcow, webkit-bug-importer | ||||||
| Priority: | P2 | Keywords: | BrowserCompat, InRadar | ||||||
| Version: | Safari 17 | ||||||||
| Hardware: | Unspecified | ||||||||
| OS: | Unspecified | ||||||||
| See Also: | https://github.com/web-platform-tests/wpt/pull/43597 | ||||||||
| Attachments: |
|
||||||||
Created attachment 468747 [details]
a testcase to show the desired effect (test in different browsers)
There appears to be two issues here:
1. calling `getAnimations()` on the `#outer` element returns an empty array while calling `getAnimations({ subtree: true })` on the same element returns the paused CSS Animation set on #outer.
2. setting `currentTime` to 0 prevents a CSS Animation from being resumed by removing the `animation-play-state` property.
This issue is visible back going back to Safari 15.6.1, so it's been around for a while. In the end it was a single root reason that caused both observed issue. We failed to return the animation through getAnimations({ subtree: false }) because the CSS Animation that was restarted using "animation-iteration-count: infinite" was not found in the associated target's effect stack. This is an easy fix in the end.
Pull request: https://github.com/WebKit/WebKit/pull/21625 Submitted web-platform-tests pull request: https://github.com/web-platform-tests/wpt/pull/43597 Committed 271872@main (494bf388fd77): <https://commits.webkit.org/271872@main> Reviewed commits have been landed. Closing PR #21625 and removing active labels. |
Created attachment 468739 [details] test case showing animation doesn't startup again I'm using IntersectionObserver to pause all animations in a DIV when out of view. I've reduced the problem to the test case attached. The test case uses simple buttons rather than the observer for minimalism. Setup: Using IntersectionObserver, I add or remove the class "paused" to an outer DIV when that DIV is in/out of viewport. .paused, .paused * { animation-play-state: paused; animation-iteration-count: infinite; /* this line forces non-infinite animations to animate again */ } In the IntersectionObserver callback, after adding the class "paused", I also try to "reset" all animations to zero with this code: div.getAnimations({ subtree: true}).forEach(n => n.currentTime = 0); By including the param "subtree", this should "reset" all descendants too. By setting animation.currentTime=0, technically, when I unpause the animations (by removing the "pause" class), all animations should run from the beginning (as opposed to continuing where they left off). Expectation: Setting the currentTime=0 should reset the animation to the initial state. Actual: On Chrome 119 and Firefox 119, this is behaving as desired. But on Safari 17.1, if I set the animation.currentTime=0, after "unpausing" the DIV, the animations don't run. Test Case description: In the test case there are 3 buttons: - Play: - Removes the "pause" class, which drops the "animation-play-state: paused" CSS property. - Pause + reset(getAnimations({subtree: true})): (This is the desired pause action.) - Adds the "pause" class. - Gets a list of all animations including those on its children - Sets currentTime=0 on all those animating objects. - Pause + reset(getAnimations(null)): (This is included for comparison only.) - Adds the "pause" class. - Gets a list of all animations on the DIV only. - Sets currentTime=0 on all those animating objects. Operating instructions: 1. Wait 2 seconds on launch for all the horizontal animations to finish. 2. Press the 1st "Pause". Then press "Play". It's won't work.