[web-anim] Web animations minutes, 11 February 2013

Web animations minutes, 11 February 2013

Etherpad: https://etherpad.mozilla.org/ep/pad/view/ro.FLTLgdsuj5z/latest
Present: Shane, Brian, Dmitry, Silvia, Douglas

1. Review agenda for the week
2. Play control
3. Media integration
4. Play control revisited
5. Spec process / which specs to publish


Draft list of topics:
1. Play Control (Monday, 1st - until lunch)
2. Timing (sharing, templating, separate object etc.) (Tuesday morning)
3. Effect templating (Tuesday afternoon)
4. Groups (Wednesday)
5. Media Integration (Monday afternoon, Friday morning)
6. Autoplay behaviour (Wednesday)
7. Spec finalization and cleanup (Wednesday)
   - motion path
   - CSS integration
   - color interpolation
   - prioritization
8. Next F2F

Wednesday 11:30am offsite


Summary of current thinking regarding play control.

There are basically two options:

1) Have a PlayController object that is associated with the root of each 
tree in the timegraph (basically the interface between the 
DocumentTimeSource and a TimedItem in the current model).

2) Have play()/pause()/currentTime etc. on each item in the timegraph. 
Their behaviour varies depending on if they are at the root of the 
timegraph or not in the same was as HTMLMediaElement:

   viz. setting currentTime throws an exception
         setting playbackRate is ignored
         calling pause() is defined to pause just the element
         calling play() brings the element up to speed with the controller

There seems to be a preference for (1) so we have discussed the 
specifics of how this might work:

Issue 1: Naming.

Clock might be a more suitable name than PlayController.

Issue 2: What happens when you get the ‘clock’ for a nested item?

var a = document.createAnimation(...);
var c = a.getClock();
var b = new ParGroup([a]);
c.pause(); // What happens here??

① c is a ClockProxy object that tracks the clock associated with ‘a’ 
regardless of any reparenting. In effect, it walks up the tree from ‘a’ 
and finds the clock at the root and calls ‘pause’ on it. As a result 
a.getClock() !== b.getClock() even though the actual clock is the same.
② c throws an exception as it is no longer a clock associated with any 
TimedItem (it gets disocciated when a is attached to b).
③ c is still a valid clock, so pause() doesn't throw an exception; 
however c is not attached to anything any more so calling pause() has no 
effect. Shane calls this “failing silently”. Brian calls this 
“succeeding but no-one cares”.

General preference is for ①.

Issue 3: What is the behaviour of start(), particularly when called on a 
child item?

Scenario (i): Calling start() on a child item

var a = document.createAnimation(...);
var b = new ParGroup([a, d]);
a.start(); // what happens here?

• remove a from c, start a
• fail silently / ignore the developer
• throw an Exception
• start C
• start C @ A
• consensus start

We liked consensus start particularly because it mimicks the intended 
behaviour of HTML MediaController here and it’s consistent between child 
items and root items. Both mean, “start when everyone attached to this 
clock is ready to go (and parents delegate for children)”.

Scenario (ii): Calling start() with a time value on a child item

var a = document.createAnimation(...);
var b = new ParGroup([a, d]);
a.start(4); // what happens here?

The 4 in this case is relative to the document time source. We think.
This also applies to b.start(4).

In this case, the child is saying, “I’ll be ready from document time 4”. 
Once all children are ready then it starts.

Scenario (iii): Calling start twice

var a = document.createAnimation(...);

In this case the second call to start updates the start time and the 
behaviour from there falls out of the model.

start() in the first case, simply sets the start time of the clock to 
the current document time.

Revisiting this model. Some concerns include:
• start() seems to do two things. It is actually just setting the start 
time of the clock, but since the default is the current document time, 
it has the effect of kick-starting the clock. People will think of it as 
actually starting playback (i.e. clock.play()).
• It’s yet to be seen if we actually can move start time to the clock or 
whether this would produce undesirable results for the animation sandwich.
• start() as a convenience method (on TimedItem) needs justification (on 
the Clock you have an attribute “start”, so don’t need a start() method).
• What happens if you call play() when a clock does not have a startTime?


Dependencies between the media timeline and the animation timeline:

Three cases to consider:
* Slaving animations to media controllers
* Slaving media to Web Animations timing groups
* Slaving media controllers to Web Animations timing groups

a) Slaving animations to media controllers:
This could be done possibly by replacing the clock with the media 
controller. Other approaches possible too.
Use case: Having animations play in sync with video
Not sure we need to support this

b) Slaving media to Web Animations timing groups
This seems like the more useful arrangement.
Would need to define how media works in this case. Possibly we could add 
a wrapper for HTMLMediaElement that implements the TimedItem interface.
Would need to define:
- Three states of media elements (solo, slaved, wrapped) and how 
switching between them works (including mapping to syntax)
- How the wrapper works, including:
   - buffering behaviour on timing groups.
   - effect of timing functions (easing functions) applied to a parent 
of a media element (suggestion that it be an optional requirement to 
apply this to video)

c) Slaving media controllers to Web Animations timing groups
If there are things that MediaControllers can do which ParGroups can’t, 
this might be an attractive possibility to support.

Discussed mapping to syntax. The arrangement elements in HTML has 
meaning with regards to layout, so it can be difficult to also arrange 
them with regards to timing.

One possibility is to put the animation elements in a separate section 
of the document or even a separate file. Media elements could be 
referred to using some sort of pointer element, e.g. <mediaRef 
href="#myVideo">. What happens if you <use> a <mediaRef>? It could be 
useful to have multiple <mediaRef> elements refer to the same media element,

      <mediaRef href="#productionCompanyLogo">
      <mediaRef href="#mainFeature">
      <mediaRef href="#productionCompanyLogo">

We could, perhaps, just define the behaviour when two <mediaRef> 
elements refer to the same media element and have overlapping intervals 
(e.g. first one wins, last one wins, etc.) This could be thought of as 
just another case of when we have animations that apply to the same 
element. Some things like merging would be different, but it should be 
mostly the same.

For HTML, the time dimension is something completely separate to the 
layout DOM of the page. Right now, the animation timeline could be 
defined in an SVG and the SVG can reference elements on the Web page to 
schedule parallel/sequential animation. In future, a new element in the 
<head> of a HTML page could be considered that would contain the 
specification of the time behaviour of (elements of) the Web page. The 
elements would be referenced from such a new element, similar to how 
<mediaRef> references video elements.

Buffering and blocking:

Buffering seems hard but we can probably build on top of HTML’s 
definitions with regards to ready state.

One proposal:

Have MediaRefItem as a wrapper for media elements inside the API. This 
allows media elements to appear more than once in the timing.

On the Clock have block/unblock behaviour. Each child (or just any 
element anywhere?) can say to the clock, “I’m blocking” or “I’ve 
finished blocking”. If the clock has one or more children (or things?) 
that are blocking then it effectively pauses.

This blocking/unblocking is internal to the model, i.e. it is not 
available in the API, at least not initially.

Children can opt-in to this. That is, a media ref item might decide not 
to tell the clock when it is buffering. In that case, it will just keep 
waiting for data and when it has enough data it will catch up to the 
time of the clock. It never falls out of sync. This might be an 
attribute, e.g. <mediaRef href="#video" freeSpirit>

SVG 1.2 has syncBehavior = "canSlip" | "locked" | "independent" | "default"

Shane’s suggestion: blockingBehaviour="sync" or blockingBehaviour="swim"

Silvia’s suggestion: blocking="parent" or "all" (bubbles) or "none"

We could possibly go without the version that slips initially. That is, 
all media refs will block the clock for the first version. In a 
subsequent version we could add an attribute that defaults to blocking 

Should we fire events on (un)blocking?

e.g. one event when the clock first blocks, and one when it unblocks

➙ Shane to do the spec text


Revisiting start()

Suggestion that maybe calling animate() also triggers the animation.

    elem.animate({ top: '100px' }, 3);

Doing so means you could possibly move start() to the clock or remove it 

One issue is about the initial state of the animation after creating. 
There is a difference between an animation created with a start time but 
paused, and an animation that is created but has no effect. This is 
because of backwards fill.

Steve feels strongly that definition of an animation hierarchy shouldn’t 
be mixed with play control — i.e. that an animation hierarchy should not 
have a clock by default, and that something like attach() should 
generate the clock and the start time.

Issues raised:

1. What should we call the clock?
A: Clock
B: AnimationController
(Note that mis-spelling clock can be quite embarrassing)
Brainstorming other ideas: Player? ClockController? TimeMaster? 
TimeLord? PlayController? AnimationPlayer? WibblyWobblyTimeyWimey? 
TimeController? Timeline?

2. How should we get ①?
A: anim.getClock()
B: anim.attach() [How do you get the clock after this point? Call 
attach() again? Also, need to define what this does on non-root items]

3. How do we control not-in-play-state vs in-play-state?
A: Clock.startTime is 'null' or not
B: Calling attach() puts it in play-state. TimedItem.detach() or 
“AnimationController.timedItem = null” puts it in not-in-play-state

4. How do we start or set start time?
A: Clock.startTime = 4 (or possibly anim.start(4) as a shortcut)
B: anim.attach(4) or AnimationController.startTime = 4

Also, need to revisit return value of getCurrentAnimations or if we want 
other methods there.


Reasons for splitting the spec into core model + API
• Non-scripted UAs (e.g. platform font engines that implement 
SVG-in-opentype) only need implement the model not the API
• Process: move model along faster without being gated on API issues

• Redundancy — e.g. ‘start time’ defined in the model, then in the API 
“the startTime attribute refers to the 'start time'”
• The model specification has no testable surface area
• More cross‐referencing / spec-jumping
• Process risk: may delay or prevent API from being implemented
• Reviewing the model in the absence of a review of the API may be 
detrimental (it limits the possibility of model changes that improve the 
API when it is reviewed)
• Over time the model and API may grow out of sync and this will become 
an increasing pain to manage.

Next meeting: Tues 12 Feb 9:00 AEDST @ Google Sydney

Past meetings: http://www.w3.org/Graphics/fx/wiki/Web_Animations/Meetings

Received on Monday, 11 February 2013 22:52:20 UTC