Bug 265280 - [web-animations] setting currentTime=0 when animation-play-state=paused, doesn't restart animation after unpausing it
Summary: [web-animations] setting currentTime=0 when animation-play-state=paused, does...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Animations (show other bugs)
Version: Safari 17
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Antoine Quint
URL:
Keywords: BrowserCompat, InRadar
Depends on:
Blocks:
 
Reported: 2023-11-23 03:22 PST by em_te
Modified: 2023-12-11 06:22 PST (History)
5 users (show)

See Also:


Attachments
test case showing animation doesn't startup again (2.30 KB, text/html)
2023-11-23 03:22 PST, em_te
no flags Details
a testcase to show the desired effect (test in different browsers) (1.93 KB, text/html)
2023-11-24 02:19 PST, em_te
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description em_te 2023-11-23 03:22:22 PST
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.
Comment 1 em_te 2023-11-24 02:19:58 PST
Created attachment 468747 [details]
a testcase to show the desired effect (test in different browsers)
Comment 2 Radar WebKit Bug Importer 2023-11-27 03:36:56 PST
<rdar://problem/118826588>
Comment 3 Antoine Quint 2023-11-27 03:50:05 PST
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.
Comment 4 Antoine Quint 2023-11-27 03:52:24 PST
This issue is visible back going back to Safari 15.6.1, so it's been around for a while.
Comment 5 Antoine Quint 2023-12-11 03:59:29 PST
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.
Comment 6 Antoine Quint 2023-12-11 04:11:43 PST
Pull request: https://github.com/WebKit/WebKit/pull/21625
Comment 7 Antoine Quint 2023-12-11 04:20:26 PST
Submitted web-platform-tests pull request: https://github.com/web-platform-tests/wpt/pull/43597
Comment 8 EWS 2023-12-11 06:22:18 PST
Committed 271872@main (494bf388fd77): <https://commits.webkit.org/271872@main>

Reviewed commits have been landed. Closing PR #21625 and removing active labels.