[web-animations] Possible simplification of API

Hi,

There are a number of areas in the API I'm not comfortable with. In 
particular:

* getAnimationPlayers() is odd. When you want to get the animations 
running on an element, it would be much more natural to call 
elem.getAnimations().

* Recent discussion about renaming AnimationPlayer.source to 
AnimationPlayer.animation[1] is symptomatic of the fact we haven't got 
the naming right. The confusion seems to come from the fact that an 
AnimationPlayer doesn't play an animation; it plays an AnimationNode.

* Having Animation as a subclass of AnimationNode is weird.

* There are too many moving pieces. We have convenience methods to 
create the pieces in bulk but when you go to inspect them, it's 
surprising that a simple animation that interpolates a property is made 
up of a timeline, a player, an animation, an effect, and a set of 
keyframes. I'd like to simplify that chain a little.

* Within the spec and the API we go to great lengths to accommodate 
groups even though we don't plan to ship them in level 1. We *think* 
they're going to be really useful but we don't know for certain yet. I'd 
like to design an API that makes sense even in the absence of groups.

* We have an abstract AnimationEffect interface but only one concrete 
interface that inherits it and no plans to expand that set.

* It seems a little odd that the constructor for Animation also creates 
a KeyframeEffect because it creates coupling between Animation and a 
particular subclass of AnimationEffect. It's not terrible, but it's a 
little odd.


For these reasons I'm quite uneasy with the current API. However, I 
think we can fix all these problems with two simple changes. They are:

1) Combine KeyframeEffect and Animation (and drop the AnimationEffect 
interface)

2) Rename as follows:
      Animation/KeyframeEffect -> KeyframeEffect
      AnimationPlayer -> Animation
      AnimationGroup -> GroupEffect
      AnimationSequence -> SequenceEffect
      AnimationPlayer.source -> Animation.effect
      getAnimationPlayers() -> getAnimations()
      (Likewise, AnimationTiming -> EffectTiming etc.)


 From a developer useability point of view it would feel something like 
this:

e.g.(1) Get all the animations running on an element

   elem.getAnimations(); // Wow, much intuitive

e.g.(2) Animate an element

   elem.animate(); // Returns an Animation! Amazing!

e.g.(3) Create an animation the long way

   var anim = new Animation(
     new KeyframeEffect(elem, { opacity: 0 }, 2000),
     elem.ownerDocument.timeline);
   anim.play(); // Play an animation; makes sense! (cf. playing a player)

   NB: I'm specifically not using AnimationTimeline.play since there are 
outstanding issues about the naming of this and if it should even exist.

e.g.(4) Create a complex animation with groups

   var anim = new Animation(
     new GroupEffect([
       new KeyframeEffect({ ... }),
       new KeyframeEffect({ ... })
     ]),
     elem.ownerDocument.timeline);
   anim.play();

e.g.(5) Query the fractional progress of an animation (time fraction)

   var anim = elem.getAnimations()[0];
   alert(anim.effect.computedTiming.timeFraction);

   // Compare the current naming
   // var player = elem.getAnimationPlayers()[0];
   // alert(player.source.computedTiming.timeFraction);

e.g.(6) Look for an opacity animation

   elem.getAnimations().find(
     anim => anim.effect.getFrames().find(
       frame => frame.hasOwnProperty('opacity')
     )
   );

e.g.(7) Wait for all animations on an element to finish:

   Promise.all(elem.getAnimations().map(
     animation => animation.finished)).then( ... );

   If we wanted to bake something like this into the Animatable 
interface (so it includes animations added while waiting for others to 
finish), we could call it elem.animationsFinished while with the 
existing naming we'd have to call it elem.animationPlayersFinished.


On a slightly related note, I'm not entirely sure what to do with custom 
effects. I think the current arrangement where you can set *either* an 
animation effect or a custom effect (but not both) isn't ideal. Having 
an onsample callback instead might be better. This would allow you to 
use both at once (e.g. set up an animation, but then add an onsample 
callback in parallel to do some logging etc. without having to do all 
sorts of tree surgery to add in groups etc.). I think that should 
probably go on the AnimationEffect (nee Animation) interface.

Best regards,

Brian



[1] http://lists.w3.org/Archives/Public/public-fx/2015JanMar/0034.html

Received on Monday, 9 February 2015 07:10:38 UTC