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