[web-animations] Making AnimationPlayer.finished return a Promise

Hi,

There's interest[1] in promisifying AnimationPlayers. Also, a few 
related issues have emerged regarding this interface:

  * It's not constructable
  * AnimationTimeline.play() is doing too many things
  * AnimationPlayer.startTime should be initially unresolved so
    that timing begins from when the first frame is rendered.

Here's a strawman proposal trying to address some of these issues.

   [Constructor (AnimationTimeline timeline,
                 optional AnimationNode? source = null)]
   interface AnimationPlayer {
     // Showing changed parts only
              attribute unrestricted double startTime;
     readonly attribute Promise finished;
     readonly attribute AnimationPlayerState playState;
     // Drop readonly attribute boolean paused;
     Promise play();
     Promise reverse();
     // Drop onfinish and finish events
   };

   enum AnimationPlayerState {
     // Either (a) play() has not been called and startTime is NaN
     //     or (b) no timeline or timeline has NaN time
     "idle",
     // play() has been called but we are waiting for the animation
     // to actually start so we can resolve startTime (currently NaN)
     "pending",
     "playing",
     "paused",
     "finished"
   };

   interface AnimationTimeline {
     // Drop play() method
   };

Notes:
* Drop finished events altogether
* Promise is resolved under same circumstances when finished event
   would have fired.
* If we reverse etc. and start playing again I think we create a new
   Promise?
* cancel() would now need to set startTime to NaN and playState back
   to "idle". Not sure if it should still clear "source".
* To start a player paused,
     player.play();
     player.pause();
* We use NaN instead of null to represent unresolved times since there
   was concern that "null + 4 === 4" while "NaN + 4 === NaN" helping
   the author discover errors more quickly.
* The playState member helps distinguish between "created, play() not
   called" and "created, play() called but yet to actually start" which
   otherwise are indistinguishable.

For constructor:
* startTime gets set to NaN. Have to call play()/reverse()/set
   manually to resolve.
* If we want to allow startTime as a parameter to the ctor, then
   it starts to seem like we want a dictionary argument?

In the general case, syntax looks like:

   var player =
     new AnimationPlayer(document.timeline,
                         new Animation(elem, { left: 100 }, 200);
   player.play();

Where as it used to be:

   document.timeline.play(new Animation(elem, { left: 100 }, 200);

Note that we still have the shortcut:

   elem.animate({ left: 100 }, 200);

It's only when you use groups, motion paths, or other parameters not 
available with the shortcut that you'd fall back to the long version.

We could possibly keep the shortcut on AnimationTimeline and rename it, 
e.g.:

   document.timeline.playAnimation(
     new Animation(elem, { left: 100 }, 200);

However, that still creates and plays an AnimationPlayer at once and I 
think we were told that's bad?

Best regards,

Brian

[1] e.g. see 
https://github.com/w3ctag/spec-reviews/blob/master/2013/10/Web%20Animations.md#request-a-finished-promise-for-animationplayer

Received on Friday, 4 July 2014 04:02:08 UTC