w3c / csswg-drafts

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

[web-animations-2] Should there be events on target elements to detect started web animations? #9011

Open flackr opened 1 year ago

flackr commented 1 year ago

While there are bubbling events for started css animations (e.g. animationstart) and css transitions (e.g. transitionstart) there are no events to observe when web animations have been started. An author would have to track when they start web animations internally.

Should we have events for web-animations which fire at the effect target? If so, would they be the same names / set of events as the css animation events (animationstart, animationend, animationiteration, animationcancel)?

If we do want to add these events, there are many complicated scenarios to work out, e.g. imagine the author wants to observe all animations:

document.body.addEventListener('animationstart', (evt) => {
  console.log(evt);
});

Animations can be started before the target is attached.

let elem = document.createElement('div');
elem.animate(keyframes, options); // animation started, but elem is not attached so the above listener wouldn't see it.
document.body.appendChild(elem);

The target can be changed after the animation is started

let anim = new Animation(keyframes, options);
anim.play(); // animation started, but has no target to dispatch events to
anim.target = document.body;
flackr commented 1 year ago

@birtles I suspect you likely have thoughts about this.

birtles commented 1 year ago

Thanks for mentioning me. My main concern, as always, is "how does it work with groups?".

I guess we'd dispatch start/end events any time a leaf KeyframeEffect went to/from the active phase? Similarly, any time an active-phase KeyframeEffect changed target element? (Would we dispatch a cancel event on the old target element?)

For iteration events, a group effect can iterate without having a target element so we wouldn't dispatch anything in that case. As a result, if we exposed iteration events at all, there would be a difference in the events reported when the parent group iterates (no iteration events) vs when the child iterates.

If we were to introduce *run events, they would likely dispatch every time a parent iterates. I wonder if that makes sense.

So I think it's do-able but there might be a few oddities to think through.

At a more high-level, I wonder if exposing events about effects is a good idea or not. The API currently focuses on animations as the main unit we return (specifically the getAnimations() functions). Should we try to stick to reporting about animations?

One downside of reporting on effects is that they're less useful for grasping timing relationships, especially in the context of groups, but maybe there are use cases where that's fine?

Another idea is an animation observer interface. Internally the Firefox DevTools uses an animation observer API modelled on the MutationObserver API that reports each time an animation is added/removed regardless of whether it is active or not. I imagine Chrome uses something similar? Depending on the use cases, it might be more useful to standardize something like that instead, or as well?

ydaniv commented 1 year ago

I've also seen this confusing developers expecting DOM events to simply trigger.

It's also very important for libraries and/or large systems where events may be tracked in a generic way, separate from the mechanism that's in charge of doing the animations.

I guess we'd dispatch start/end events any time a leaf KeyframeEffect went to/from the active phase?

That would be great.

Should we try to stick to reporting about animations?

I'd say definitely yes. The only thing that may be interesting is perhaps on the timeline-level, but IMHO events on group animations should also cover most of these.

Another idea is an animation observer interface.

If I'm not mistaken, the main motivation of moving from events to observers was mostly about solving implementation issues with events. Do we have any of these here? Or is there any other benefit to moving to an observer (perf, API)? One good reason I can think of is that this can be easily detected by authors to know whether DOM events are triggered in response to web animations.

birtles commented 1 year ago

One of the main advantages of the observer interface is it also lets you know when animations are changed (e.g. have their playback rate updated, are paused etc.) which unlocks a few extra use cases. Sticking with events is simpler, however.