[web-animations] Should computedTiming return a live object?

(CC-ing public-webapps and www-style since I think this API needs more
eyes on it)

Hi,

Web Animations currently has the following API[1]:

  interface AnimationEffectReadOnly {
      readonly attribute AnimationEffectTimingReadOnly timing;
      readonly attribute ComputedTimingProperties      computedTiming;
  };

  interface AnimationEffectTimingReadOnly {
      readonly attribute double                             delay;
      readonly attribute unrestricted double                iterations;
      readonly attribute (unrestricted double or DOMString) duration;
      // etc.
  };

  dictionary AnimationEffectTimingProperties {
      double                             delay = 0.0;
      unrestricted double                iterations = 1.0;
      (unrestricted double or DOMString) duration = "auto";
      // etc.
  };

  dictionary ComputedTimingProperties : AnimationEffectTimingProperties {
      unrestricted double endTime;
      unrestricted double activeDuration;
      double?             localTime;
      // etc.
  };

Basically, in AnimationEffectReadOnly, 'timing' points to a live object
but 'computedTiming' points to a dictionary.

Now, attributes can't use dictionary types but this was added because we
were under the impression that this would become possible in the future
similar to the way arrays can now be used using FrozenArray.

However, having thought about this more and discussed with Cameron,
this is probably not a good API in a lot of ways. For a start, having
'timing' return a live object and 'computedTiming' return a snapshot is
odd.

I'd like to change this API, probably to one of the following (listed
roughly in order of preference). I wonder if anyone else has an opinion
on this?


OPTION 1. getComputedTiming()
-----------------------------

i.e. continue to return a dictionary but make it obvious it's not live.
Having 'timing' and 'getComputedTiming()' is a bit weird but the only
concrete subclass(es) of AnimationEffectReadOnly is
KeyframeEffect(ReadOnly) which has 'getFrames()' so this naming is
consistent.


OPTION 2. Replace ComputedTimingProperties with a live interface
----------------------------------------------------------------

i.e.

   interface ComputedTimingReadOnly : AnimationEffectReadOnly {
       readonly attribute unrestricted double  endTime;
       readonly attribute unrestricted double  activeDuration;
       readonly attribute double?              localTime;
       // etc.
   };

This is probably easier for authors since they can just type
'effect.computedTiming.localTime' instead of
'effect.getComputedTiming().localTime' but I think we're trying to keep
away from these kind of live objects that depend on others based on our
experience with the SVG API. (Once these interfaces get constructors you
end up having to implement an 'orphaned mode' and a 'tied to this other
object mode' and it's all quite messy.)


OPTION 3. getComputedTiming(), getTiming(), setTiming()
-------------------------------------------------------

If live objects are bad and inconsistency is bad, then maybe we should
rework the 'timing' member too and make it set and get dictionary
objects. The tricky part is when you want to update just a single timing
property. We'd probably need to either drop the dictionary defaults or
provide some means for doing 'effect.setTiming({ iterations: 2 })'.

Also, I think the fact that 'computed timing' is read-only while
'timing' is writeable justifies them being different (method vs
attribute).


There are other options too but the above the main ones I'm considering,
especially option 1.

If anyone has any suggestions, please let me know.

Best regards,

Brian

[1] 
http://w3c.github.io/web-animations/#the-animationeffectreadonly-interface

Received on Thursday, 1 October 2015 02:24:24 UTC