- From: Kevin Brewster via GitHub <sysbot+gh@w3.org>
- Date: Fri, 15 Jan 2021 20:49:58 +0000
- To: public-css-archive@w3.org
_Thanks for taking the time to explain all that!_
_I'll create a separate proposal for `AnimationEffectEvent` next week and use this page to further discuss the potential merits of an `Animation.playing` promise._
> The Animation.ready promise fits into the "One-and-done operations" category, i.e. asynchronous operations.
Hmm. I interpreted this category as explicitly referring to methods that "return a promise", not properties, but perhaps that's a distinction without a difference.
Anyway, I think I found a better way to articulate what I want.
### Better Explanation of `Animation.played` Promise
I want to be informed when any of these three conditions happens (and I'm hoping all three are exactly equivalent but perhaps I'm misunderstanding something):
- **I want to be informed when an animation goes from playState `idle` to either playState `running` or `paused`**
- **I want to be informed when an animation's currentTime becomes not null**
- **I want to be informed when an animation has an active timeline**
In other words, I see three state categories:
- **`idle`**
- **`playing(Bool isRunning)`** (encompasses both `running` and `paused` playStates)
- **`finished`**
```
`played` promise resolved
| |
V
| ---- playing ----- |
[idle] | [running] / [paused] | [finished]
| ------------------- |
| [effect] |
| [effect] |
| [effect] |
```
The `playing` state category represents when the animation has an active timeline (not sure if this is 100% accurate).
I want to know when the animation has entered this `playing` state category. This would be a one-time event (i.e. would **not** happen with every `play()` or `pause()`.
By the way, I'm not sure `played` is even the best name for this, as it implies it's directly related to the play() method. Perhaps you can suggest a better name?
The only advantage of a promise over an event is so authors can still be informed if animation is auto-played.
In other words, if there was a `play` event instead of a promise, you could never be notified when using `element.animate()`.
Consider these three examples where the console should log "played" each time.
```javascript
let animation = new Animation(...);
animation.played.then( console.log("played") );
animation.play();
```
```javascript
let animation = new Animation(...)
animation.play();
animation.played.then( console.log("played") )
```
```javascript
let animation = element.animate()
animation.played.then( console.log("played") )
```
Obviously the third example is practically pointless, but I'm imagining a situation where animations are dynamically created, sometimes being played immediately and sometimes not, and we want a consistent way to be notified.
Next consider this example of a trivial "conditional sequence". In other words, when one animation finishes it may or may not trigger another animation. Imagine that I have a timeline UI shown on the page and whenever an animation enters the `playing` state category, I want to append a `DIV` to the timeline UI element to represent that animation.
There's certainly work-arounds (e.g. lifting `animation1.play()` to a separate function that can handle the extra DOM work as well as trigger the animation) but these work-arounds quickly become cumbersome as the code grows in complexity.
```javascript
let box = document.querySelector("#box");
let animation1 = new Animation(new KeyframeEffect(box,
[{ opacity: 1 }, { opacity: 0 }],
{ duration: 300, delay: 1000 }
))
animation1.played.then(_ => {
console.log("animation1 played")
// todo: add some kind of visual element to the timelineUI
});
animation1.finished.then(_ => {
console.log("animation1 finished")
});
let animation2 = new Animation(new KeyframeEffect(box,
[{ transform: "translateX(0)" }, { transform: "translateX(100px)" }],
{ duration: 600, delay: 100 }
))
animation2.played.then(_ => {
console.log("animation2 played")
// todo: add some kind of visual element to the timelineUI
});
animation2.finished.then(_ => {
console.log("animation2 finished")
});
let animation3 = new Animation(new KeyframeEffect(box,
[{ transform: "rotate(0)" }, { transform: "rotate(90deg)" }],
{ duration: 800, delay: 400 }
))
animation3.played.then(_ => {
console.log("animation3 played");
// todo: add some kind of visual element to the timelineUI
});
animation3.finished.then(_ => {
console.log("animation3 finished")
if(Math.random() > 0.5) {
animation1.play();
} else {
animation2.play();
}
});
// kick-off the first animation
animation3.play();
```
For a more concrete example, I'm currently creating a dynamic slideshow using animations. I'm creating all of my animations ahead of time and effectively doing a bunch of SequenceAnimations and GroupAnimatons but sometimes more complex (i.e. with conditions / different pathways for the sequence part). The spacebar and arrow keys trigger certain animation groups/sequences, and the exact sequence is not predetermined ahead of time.
It would greatly simplify my life to have custom code run whenever an animation is first played, so I can adjust the DOM as needed (or even just logging for debug purposes). Sometimes the actual effects have a significant delay so I don't want to synchronize with the effect - I'm strictly interested in when play() is actually called).
From a theoretical standpoint, clearly you can create `Animation` instances that aren't auto-played. I don't think it's too much of a stretch to imagine they occasionally might not be played immediately. I therefore think it's reasonable to offer some sort of mechanism signal the transition from `idle` to `running` / `paused`
--
GitHub Notification of comment by kevinbrewster
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/5871#issuecomment-761190539 using your GitHub account
--
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Friday, 15 January 2021 20:50:00 UTC