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

Reply via email to