Re: [csswg-drafts] [web-animations-1] Make animations become idle when they have an inactive timeline

This is quite confusing. I tried making animations preserve their current time as the hold time but it's complicated by the fact that pause state is represented by the lack of a start time, and when an animation doesn't have a timeline, you can really only set either the start time or the hold time meaningfully.

For example, suppose we have:

```js
const anim = elem.animate(...);
await anim.ready;
```

At this point `anim` has a `startTime` relative to `elem.ownerDocument.timeline`.

Now if we clear the timeline...

```js
anim.timeline = null;
```

What we're suggesting in this issue is that `anim`'s hold time is set such that it keeps its current time. However, we have an invariant in the model that says that if an animation doesn't have an active timeline it can only have _either_ a resolved hold time _or_ a resolved start time since otherwise once you attach another timeline we don't know which one to honor.

That means that we'd need to clear the `startTime` giving us:

```js
console.log(anim.currentTime); // Some number like 52.12...
console.log(anim.startTime); // null
console.log(anim.playState); // paused
```

Now, what should happen if we re-attach a timeline?

```js
anim.timeline = new DocumentTimeline();
console.log(anim.playState); // running? paused?
```

Whether it is running or paused will depend on whether or not we resolve a new `startTime` based on the hold time. Presumably we _do_ want to do that.

That begs the question, however, what should happen if we do the following?

```js
anim.pause();
anim.timeline = null;
anim.timeline = new DocumentTimeline();
```

Assuming we resolve a new `startTime` as suggested above, suddenly `anim` would start playing just because we attached a new timeline which is a little odd. (And we'd need to be careful to make the behavior consistent between whether we set `null` first or not.)

We currently avoid this by saying that the hold time is cleared when we change timelines. That way the paused state is preserved (through the resolved-ness of the `startTime` which is _not_ updated).

A few options that come to mind here if we _do_ want to preserve the current time:

* Just say that setting a timeline is equivalent to playing. Get used to it.
* Drop the invariant about only being able to set `startTime` or hold time on an animation without an active timeline and say that when we re-attach a timeline, if the hold time is set we recalculate the `startTime` from it (i.e. hold time has priority over `startTime`).

That last option is fairly attractive. It does mean, however, that you can end up with pretty useless `startTime` values for an animation without an active timeline (in many cases we'd just be preserving it to represent paused-ness).

Furthermore, such animations will report themselves as running. i.e.

```js
const anim = elem.animate(...);
anim.timeline = null;
console.log(anim.playState); // running
```

But maybe that's ok? In a sense it tells you what the animation will do when you do attach a timeline. Furthermore, in an academic sense, maybe you could say the animation actually _is_ running, it's just that it is following the infinitely slow null timeline hence why it doesn't progress.

That last point might make even more sense if we later make a distinction between monotonic timelines and infinite timelines (see #2075) where in the latter the `startTime` is possibly ignored. In that case, the null timeline would simply be an instance of an infinite timeline where the `startTime` is ignored. (Although I'm not sure how we'll indicate paused-ness in that world -- presumably we still want to be able to pause scroll-driven timelines? Maybe they will have a `startTime` that is either zero or `null` depending on if they're running or not?)

-- 
GitHub Notification of comment by birtles
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/2066#issuecomment-392666675 using your GitHub account

Received on Tuesday, 29 May 2018 06:30:01 UTC