W3C home > Mailing lists > Public > public-fx@w3.org > October to December 2015

[web-animations] Fixing getAnimations()

From: Brian Birtles <bbirtles@mozilla.com>
Date: Thu, 26 Nov 2015 11:39:07 +0900
To: "public-fx@w3.org" <public-fx@w3.org>
Cc: "www-style@w3.org" <www-style@w3.org>
Message-ID: <565670CB.8000704@mozilla.com>
Hi,

Web Animations defines Animatable.getAnimations() (where Animatable is 
implemented by Element and a forthcoming PseudoElement interface) and I 
think we've agreed to add Document.getAnimations() as well.[1]

I've found two problems with the first method which I'm going to call 
Element.getAnimations() for now since PseudoElement doesn't exist yet.


PROBLEM 1. Element.getAnimations() doesn't work on a subtree

Recently I was working on a presentation where I wanted to use script to 
restart all the animations in a particular slide, represented by a 
<section> element.

What I really wanted to do was something like:

   section.getAnimations().forEach(anim => anim.currentTime = 0);

However, Element.getAnimations() doesn't return animations from its 
descendants (unlike querySelectorAll, getElementById, etc.).

To further complicate things, Document.getAnimations() *does* return 
animations from its desendants (or will, once it is specced).


PROBLEM 2. getAnimations() relies too much on the order in which 
animations are returned

Whenever you see code using getAnimations(), it almost always looks like 
this:

   var anim = elem.getAnimations()[0];

That's really brittle. If some style is added that causes a transition 
to fire on elem, you may end up getting the wrong result.

Of course, you can go through all the animations returned from 
getAnimations() and test their animationName/transitionProperty 
attributes and make sure you get the right object, but most people won't 
bother.


PROPOSAL: Add some options to getAnimations()

At a minimum, I think we need:

* transitionProperty - used to filter by 'transitionProperty' which is
   only set on CSS transitions

* animationName - used to filter by 'animationName' which is only set on
   CSS animations

* id - used to filter by 'id' which may be set on script-generated
   animations

* subtree - true means to fetch animations from descendents too (based
   on the Mutation Observer API)

It's not obvious to me what the default value of subtree should be. I'd 
say 'false' except that would prevent using the same options object on 
Document.getAnimations(). Perhaps true? Given that most people will use 
this on leaf nodes anyway, maybe that would be ok?

It's also not clear if we should only inspect the transitionProperty on 
CSSTransition objects, or if script-generated objects that define their 
own transitionProperty should be considered too. I guess they should. 
Likewise for animationName and CSS Animations.

Some usage patterns are bogus, e.g. passing subtree:false to 
Document.getAnimations() or specifying both transitionProperty and 
animationName (except in rare cases where script added these 
properties), but maybe that's ok.

Example usage:

   // Get the animation I just added
   elem.style.animation = 'move 3s';
   var anim = elem.getAnimations({ animationName: 'move' })[0];

   // Get all transform transitions in this section
   section.classList.add('move-in');
   var transitions =
     section.getAnimations({ transitionProperty: 'transform' });

As you can see in the first example, we still have the '[0]' thing 
there. It's more safe now since we're only dealing with CSS Animations 
named 'move', but you could still get the wrong result and it's also a 
bit of an eyesore and pain to type.

I wonder if it's worth following the querySelector/querySelectorAll 
pattern and having a pair of functions: getAnimation/getAnimations?

In the singular, if there were multiple matches on the same element 
you'd return the one with the highest composite order[2] since that's 
most likely to be the one that you want. If you had multiple matches 
within a subtree, I'm not sure: tree order or composite order.

Possible future extensions:

* Parameters to get only CSS transition or only CSS animations?
* Parameters to get all animations that affect certain properties? e.g.
   all animations that affect either the 'opacity' property or
   'visibility' property.

These can be easily implemented using Array.filter() so there's no 
urgency for these.

What do you think?

Brian


[1] https://lists.w3.org/Archives/Public/public-fx/2015JulSep/0073.html
[2] http://w3c.github.io/web-animations/#the-effect-stack
Received on Thursday, 26 November 2015 02:39:48 UTC

This archive was generated by hypermail 2.3.1 : Thursday, 26 November 2015 02:39:49 UTC