w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.38k stars 641 forks source link

[web-animations-2] Add web-animation animation events equivalent to css-animations and css-transitions. #8544

Open flackr opened 1 year ago

flackr commented 1 year ago

css-animations-2 4.1. Event dispatch defines animationstart, animationend and animationcancel events which fire anytime the effect phase changes. css-transitions-2 5.1 Event dispatch defines transitionstart, transitionend and transitioncancel for the equivalent changes in phase.

web-animations-1 4.18.2. Animation playback events only defines finish, cancel and remove events.

I propose that we add start and end web-animations events corresponding to the animationstart/transitionstart and animationend/transitionend cases (e.g. corresponding to phase changes).

See the following demo (in a browser supporting scroll linked animations, e.g. chrome canary with experimental web platform features turned on) for a demo of the current state: https://jsbin.com/xuwebet/edit?css,js,output

@birtles WDYT?

birtles commented 1 year ago

Yes, I agree. finish and end are different. We should preserve the current behavior where:

That suggests an end event, separate to the finish event, would be needed if we want Web Animations to have an event matching CSS animations/transitions behavior.

Just to check though, why do we need an end event for Web Animations?

We've so far avoided adding start/end events to Web Animations because they're tied to animation effects and in a world with group effects, it begs the question of, "Do we dispatch these events for all effects in the effect tree or just the root one?".

If it's the former, perhaps they should be effect events, whose event target is an animation effect? And what should be dispatched when a parent effect causes a child effect to repeat etc.?

If it's the latter, do we need to introduce "start" and "end" concepts to animations, increasing coupling between animations and their root effect's delay properties?

flackr commented 1 year ago

That suggests an end event, separate to the finish event, would be needed if we want Web Animations to have an event matching CSS animations/transitions behavior.

Just to check though, why do we need an end event for Web Animations?

When using a non-monotonically increasing timeline you can go from active to the before phase even when playbackRate > 0. This is not considered finished, so that event is not fired. The css-animations end event is fired because it only looks at the change in phase. So we need an end event so that developers can observe this change. This is exemplified in my linked demo when you enable scroll linked animations.

We've so far avoided adding start/end events to Web Animations because they're tied to animation effects and in a world with group effects, it begs the question of, "Do we dispatch these events for all effects in the effect tree or just the root one?".

If it's the former, perhaps they should be effect events, whose event target is an animation effect? And what should be dispatched when a parent effect causes a child effect to repeat etc.?

If it's the latter, do we need to introduce "start" and "end" concepts to animations, increasing coupling between animations and their root effect's delay properties?

I suppose we could add these events to the effect instead. Then the developer can directly observe each effect. Alternately, the event itself could include the effect.

Repeated effects would just follow the same logic as the css-animations-2 dispatch table, right? Any issues with this? Wouldn't we have to do this for group effects constructed via css too?

birtles commented 1 year ago

When using a non-monotonically increasing timeline you can go from active to the before phase even when playbackRate > 0. This is not considered finished, so that event is not fired. The css-animations end event is fired because it only looks at the change in phase. So we need an end event so that developers can observe this change. This is exemplified in my linked demo when you enable scroll linked animations.

Thanks, I'm just curious about the use cases. I can imagine the event being useful, I was just wondering if there are specific use cases we've come across that need this.

I suppose we could add these events to the effect instead. Then the developer can directly observe each effect. Alternately, the event itself could include the effect.

Repeated effects would just follow the same logic as the css-animations-2 dispatch table, right? Any issues with this? Wouldn't we have to do this for group effects constructed via css too?

Yes, I'm just wondering if it's weird that, for example, if a parent group repeats causing a child to finish, then start again, that there are no events dispatched.

If we're ok with this, then I think it's fine. As you mention, unless we add further steps to handle groups in the CSS animations event dispatch definitions, this is the situation we'll arrive at there anyway.

It's a good question, however, as to whether these events should be dispatched at effects or animations (but with an effect member).

It looks like we could define the event such that it has an event path that flows from an effect to its animation (via any parent effects, once introduced) by overriding the get the parent definition for animation effects. That probably makes the most logical sense, but we should get advice before going ahead with that.

fantasai commented 1 year ago

if a parent group repeats causing a child to finish, then start again, that there are no events dispatched

CSS Animations has an animationiteration event which fires between iterations. The animationend event only fires after all of the iterations.

It's a good question, however, as to whether these events should be dispatched at effects or animations (but with an effect member).

I think you may want both abilities, as I'm sure some developers are interested in whether the whole set of animations (whatever those animations happen to be) has ended.

birtles commented 1 year ago

CSS Animations has an animationiteration event which fires between iterations. The animationend event only fires after all of the iterations.

Yes, but if the parent iterates, the child will also effectively iterate despite having an iteration count of 1. As a result, the child animation will finish and start again but, depending on the length of the parent group and frame rate, we will either see an animationend followed by an animationstart or no events at all.

I think you may want both abilities, as I'm sure some developers are interested in whether the whole set of animations (whatever those animations happen to be) has ended.

The strawman proposal was that we could dispatch events at effects such that they bubble up to the animation so you can listen at either point.

Doing that would mean that once you have nested effects, however, if you're listening at the animation level and were only interested in when the root effect had ended, you'd need to filter our events from child effects. That's a pretty similar situation to where we are today with CSS animation/transition events, however, where you need to be careful to ignore events from child elements and unrelated animations/transitions.