[web-animations] Rethinking document.timeline.getAnimations

Hi,

Summary:

* I think we should drop AnimationTimeline.getAnimations()
* I think we should add Document.getAnimations()

I've been working on implementing the Web Animations model in Gecko and
I've made a few observations:

1. document.timeline.getAnimations() is not really useful

    If you want to find all the animations running in a document it
    doesn't help because animations might be running on a different
    timeline.

    There's no way of getting all the timelines either so you really
    can't answer the question, "is this document at rest?" without
    iterating over all the elements in the document and calling
    getAnimations() on each of them. (And even then, that doesn't work
    for pseudo-elements).


2. Semantically, document.timeline.getAnimations() is weird

    Timelines are supposed to be dumb things that simply supply time
    values, probably one per frame. That's all. They don't manage
    animations. They're just like a ruler. As you move along you read off
    numbers.


3. Having document.timeline.getAnimations() makes extending timelines
    harder

    We've already talked many times about having different types of
    timelines that track, e.g. scroll position.

    More recently we've been talking about changing the playbackRate on
    timelines and how, in order to avoid changing the playbackRate for
    *all* animations (including transitions) content should be able to
    easily create new timelines and use them as a kind of simple grouping
    mechanism.

    So I think we're in the situation where we want custom timelines and
    soon. What's more, I think we'll want script-generated timelines soon
    so we can prototype new types of timelines (e.g. timelines tied to
    touch gestures etc.)

    That's a lot easier if timelines really are just sources of time
    values, not managers of animations. If they're managers of animations
    then presumably the browser will have to add magic behind the scenes
    so that each script-generated timeline doesn't *also* have to be
    responsible for maintaining its list of animations.



I'd like to fix this. At the same time I'd like to try and remove a bit
of magic. I'd like to make this setup a little more explainable so that
we could expose more parts of the animation system in future, if need
be. I'd also like to make sure this setup explains the lifetimes of 
animation objects.

Here's how I think, conceptually, the pieces should fit together:

* UAs maintain a map between all running and pending Animation objects
   and their timelines. This map is hidden, but could potentially be
   exposed later if needed.
* On each frame UAs enumerate the animations in this map to tick them.
* When we come to support script-generated timelines, we add an extra
   step where the UA first queries each timeline to get its frame time
   and then passes that cached time to the Animations in the subsequent
   step.
* With regards to lifetimes, any Animation that is running or pending is
   kept alive by this map.
   * Furthermore, target elements keep alive any *effects* targeting
     them.
   * *Effects* keep alive any animation they belong to.
   * As a result if you create an animation and let go of it, so long as
     it is targetting an element, it will be kept alive until it is
     neither "current" nor "in effect".
     - until it is finished, it will be kept alive by the timeline,
       unless it is paused, in which case the effect will keep it alive
     - once it finishes, if it fills forwards, the effect will keep it
       alive
   * This gives the expected behavior even for animations without an
     effect, or without a timeline and it does not expose when GC occurs.
* We could support script-generated Animations in the future by simply
   exposing the map.


In API terms I propose we do the following:

a. Drop AnimationTimeline.getAnimations()

b. Add Document.getAnimations()

Considerations: document.timeline.getAnimations() could be good, for
example, for generating a kind of timeline view but I think that's
a much less common case that wanting to see all the animations affecting
the current document.

If that became an important use case, we could simply expose the map
and allow fetching the animations by timeline.

Document.getAnimations() doesn't really have any relationship to the map
described above. It returns all animations *targetting* elements in the
document tree. As a result, there's no way of fetching an Animation
you set running with no target element. For that we'd need to expose
the map.

Any thoughts?

Brian

Received on Friday, 25 September 2015 07:30:54 UTC