There's no animation time but even in our model, animation time is really an implementation detail. In terms of the API it's irrelevant. Maybe we should try to hide it a bit more. The time spaces diagram appears quite complicated.

Should we rename?

iteration time -> basic time (SMIL calls this simple time)

item time -> active time (SMIL calls this active time)

➙ iteration time is more descriptive than basic time

➙ item time is not great (Shane: but still better than active time! Doug: you lie!)

How about local time?

➙ We'll give local time a try

➙ decided that the walls of local time should be painted red.

Shane, Steve: If we have a time window then we could have timeWindow.activeTime instead of animation time

➙ rename animation interval to active interval.

5. FEEDBACK FROM ROB ARNOLD

===========================

(Brian)

“I think it would be helpful to have examples to use examples for individual features (ex: seeking; I haven’t seen a need for that yet) and indicate what areas the API is intended to be used for (games, rich content, ui?)”

➙ Yes. We should put this in a different document (a primer). We will also increase the number of examples in the specification, but these will be for the purpose of illuminating how the specification works rather than justifying the decisions made in the specification.

“I am sadly quite well aware that CSSOM for Transitions/Animations is painful so having a good API there which addresses mutation (O(n²) to remove all keyframes of an animation in WebKit) and triggering (no awkward forced synchronous style calc) would be helpful.”

This ties into Shane's desire to expose web animations objects as CSS/SVG manipulators.

"One thing that I do think is important but not addressed in the spec is concurrency (I assume that this is what you meant by hardware accelerated animations). In particular, asynchronous animations are highly useful in covering up main thread lag due to events or implementations beyond the author's control. This is key on mobile where performance expectations are high due to a direct manipulation UI but processing power is weak. As a motivating example, consider trying to implement a feed of mixed content (say, Facebook's newsfeed) with native quality scrolling. Things like garbage collection, image decoding, style/layout from new content being inserted and time mysteriously unaccounted for (thanks Chrome!) disrupt the framerate during/transitioning into fling scrolling (which can use CSS animations for better physics / dependable scroll position events). The current and proposed APIs seem to assume some sort of synchronous execution between the JS and on screen animation; for this reason I like asynchronous events so that the animation thread isn't stalled by content."

I (Brian) followed this up and Rob provided the following clarification: "I think there are some implicit assumptions in the API such as the relation between the start of an animation and when you tell it to start; with asynchronous animations, you'll need to account for a delay (due to vsync, IPC overhead, etc...) and the page may want to take that into account when computing its UI."

Some discussion on synchronicity of events and the possible use of observers.

> Brian to continue speccing events without observers.

> Shane to show events model (once specced) to observers guys and see what they think.

This could also be about the delay between calling start() and when the animation first updates. This would cause a jump.

We might add a feature in a future version for “start this animation asap but whatever you do, start from the beginning”

→ startASAP()?

→ base it off a trigger?

“I do like that you can compute the animation in JS with your own internal structure and then have the browser query that instead of shoving it into the CSSOM (creating a lot of garbage via string allocation).”

I asked, “I just want to check I've understood this part. Are you referring to CustomAnimFunc? If that's the case, then the user-supplied function just applies the effect itself. It doesn't return anything to the browser.”

To which Rob responded: “Oh, I thought that it was to allow JS to specify the animation curve so that the browser can asynchronously render it. This is an example of where I mean that the spec does not seem to permit an asynchronous (multithreaded) implementation.”

“Oh, and if we could get instrumentation on how well the animation was played back (frame level timing would be sufficient) then that would really help our testing I suspect.”

Rob later helped with some ideas about how to get this data when animations are offloaded to the GPU, “I suspect that it's not too tricky to get the data; exposing it to script may be hard. There is a GL extension (even available on some mobile devices) called GL_timer_query which lets you time the GPU pipeline. DirectX has had a similar API for a while.”

➙ Maybe a future version but some concern about all vendors being willing to expose this information

6. NULL ANIMATION FUNCTION

==========================

(Brian)

Does it make sense to allow Animation.animationFunction to be null-able?

On a UA that doesn't support '-moz-transform' the algorithm there will mean createFromProperties returns null. I think this is correct behaviour and there's an example in the spec of where the null behaviour can be useful.

But then, what is 'new Animation' supposed to do?

a) Just set animationFunction to null?

b) Throw an exception saying its bad input?

c) Make some sort of generic function to fill in its place?

I don't think (c) is really great since I can't think of a suitable function for that unless you make a KeyframesAnimationFunction with a blank property and no frames?

(b) warns you about the error but it will commonly mean that for a given browser that the author hasn't tested the content with that doesn't support said property, everything grinds to a halt. Whereas with (a) it continues, it just does nothing.

The downside of (a) is that there's no visible warning and every time you access Animation.animationFunction you need to check if it's null or not. That said, Animation.animationFunction is already of type (AnimationFunction or CustomAnimationFunction) so you probably should be checking the type there anyway.

So my vote is (a) unless someone can suggest a good function for (c).

Note that making an animation function with '-moz-transform' as the property EVEN on UAs that don't support it isn't an option due to the way we process that property bag in order to avoid indeterminancy (it's complicated).

I think we need to clearly specify three things regarding liveness and scripting:

If I change any of the values (e.g. the duration), do all the other timing values immediately update? (e.g. end time)

Brian: suggest yes

Shane: polyfill does

Does the target property(ies) update? e.g. does the computed style of the height I'm animating instantly update? (i.e. do we do a synchronous sample in effect) or does it lazily update? (i.e. if I query it I'll get the updated value but I won't see any change in rendering otherwise)

Brian: suggest no update until current script block completes

Shane: "until the script block finishes". Never mind, this is good enough.

In a given script block is it possible for a clock tick to occur? (i.e. can the value I get back for the currentTime of the global clock at the start of a script execution block differ from the one I get back at the end of the script execution block)

Brian: suggest no

Shane: there's a specific hack in the polyfill to implement no here :-)

Authors are going to trip up on this and curse, "Who wrote this crazy spec!?!"

It would be ok if we had this pattern throughout the API and then authors could learn it once and deal with it. But we don't.

Also, we have the following situation:

As described in the previous point, in order to align with HTMLMediaElement, we possibly want a playbackRate that is stative and one that's not? And possibly a defaultPlaybackRate?

For reversing we currently change the playbackRate and fillMode. This is not great since it means (with current template behaviour) you can't reverse an animation without breaking the link to the template.

Templates aside, it seems like you should be able to reverse an animation without changing its serialised state. i.e. it should be a runtime control. This might be solved by adding a locallyReversed member as proposed above, but it's somewhat confusing to have three orthogonal attributes controlling direction (playbackRate, direction, locallyReversed).

Setting the non-default version to null reverts to the calculated value

When serialising, you'd typically serialise just the default values. The others should be considered run-time controls

Make 'duration' writeable

Problem: interface bloat (heaps of members in TimedItem)

Problem: not quite the same as HTMLMediaElement. If you set defaultPlaybackRate in HTMLMediateElement it has no immediate effect but here it would (unless playbackRate was overriden)

Problem: Using 'null' to reset stuff is a little hacky? There's also a little bit of magic involved since you can't tell just from inspecting the object whether the non-default values are overridden or are calculated from the default values (unless of course the values differ)

C) Similar to above, but basically rename Anim.timing to Anim.default giving

Anim.duration

Anim.default.duration

Anim.playbackRate

Anim.default.playbackRate

etc.

Basically copy those members from the Timing interface that could be useful to override on a run-time basis to the TimedItem interface

Setting Anim.default.duration overrides the template but setting it to null reverts to the template value

e.g. (2), if we go with D above

Anim.duration is calculated from the default duration passed in (even though this isn't publicly visible) and it is calculated from Anim.template.timing.duration

Setting Anim.duration overrides everything. Setting it to null reverts to the template value. No way to override Anim.duration in a way that is serialized unless we simply serialize the runtime state.

In the case of F, not much changes actually.

Update: I'm thinking of making TimedItem not include all this information and just putting in on Animation, ParGroup and SeqGroup. This is probably cleaner from an architectural point of view (i.e. just have a concept of things that occur at a given time and then extend that to things that interpolate over that time), makes more sense for audio/video items and media controllers, and isolates this functionality a bit more nicely.

Shane: Unfortunately it also reduces the similarity of Animations to Par/SeqGroups which is currently a nice feature of the model.

TimedItem is just

startTime

endTime

duration

currentTime (possibly inherited from TimeSource/Timeline?)

parentTimeline

cancel()

startDelay?

This opens up two broad possibilities:

Make an interface/interfaces to encapsulate all this:

e.g. TimingControl?

Includes everything below

Note that Core Animation includes a MediaTiming which basically includes all this

e.g. Several interfaces: RepeatableTiming, ScalableTiming

SpeedControl??

playbackRate

changePlaybackRate()

PauseControl

paused

locallyPaused

pause()

play()

timeDrift (Need in TimedItem?)

RepeatControl

iterationCount

iterationStart

iterationTime

currentIteration (read-only)

FillControl

fillMode

DirectionControl

direction

reverse()

ScaleControl

timingFunction

In light of the questions above about Animation.timing.duration vs Animation.duration here we would

Remove the Timing interface

Keep TimingDictionary and apply the members directly

Basically do D initially (but maybe without the 'null' behaviour?) and add F in future if it's needed.

We could probably include SpeedControl.playbackRate & SpeedControl.defaultPlaybackRate

For duration I think we'd just have the one on TimedItem. It always reports its calculated value but you can override it.

Later if we really need the ability to tell if it has been overridden or reset it to the default value we'll add extra resetToDef

Make a member: AnimationTiming

Basically, everything hangs off

I definitely prefer the interface approach above, but would like to reduce the number of interfaces somewhat.

Let's see:

Video: SpeedControl, PauseControl, SimpleRepeatControl?, FillControl?

ParGroup: All of them

SeqGroup: All of them

MediaController: SpeedControl, PauseControl

Animation: All of them

A simple property set: None (FillControl assumed)

-- this could be represented as a property applied for a range of time where the end time is infinite

A property applied for a range of time: None (FillControl assumed)

* Does SpeedControl imply DirectionControl? So should we just conflate them?

* Do we need SimpleRepeatControl? Or just add loop directly to those

* Does video need FillControl? Probably not

Combining SpeedControl and DirectionControl we have:

SpeedControl

PauseControl

RepeatControl

FillControl

ScaleControl

Five items. Maybe that's ok? It breaks up the spec and allows us to address how each part works bit by bit?

Or TimingControl

Includes SpeedControl, PauseControl, startDelay

+

RepeatControl

FillControl (Not sure about this one. Just put it in TimingControl and ignore it for MediaControllers?)

ScaleControl

Shane: My strong sense is that this is going in the wrong direction. It's increasing the number of IDL interfaces we define (and hence increasing the complexity of the specification), while removing functionality. I suggest we go with option A or C and keep what feels from an implementation perspective a very solid set of relationships.

> Brian to come up with a different proposal and remove this one from future minutes.

10. THE CHOPPING BLOCK

======================

(Brian)

What can we drop from v1 to make things simpler and faster to ship?

My (Brian's) suggestions:

Templates

Lots of complexity here. I think if we make animations easily cloneable and add convenience methods that take a DOMNodeList/sequence and generate the necessary animations we'd get 80% of the convenience. For controlling multiple running animations we have groups that cover some of the cases.

The main argument for keeping templates that I can see is because implementations are going to have to implement something like templates anyway in order to manage changes to animations generated by markup so why not formalise this behaviour from the start?

Shane: I have some feedback from web developers too - the "immediate" effect of Animation objects is strange to them but the ability to create Templated animations ameliorates this significantly.

Brian: Is this about animations playing as soon as you create them?

Doug, Steve and Shane had a bit of a discussion on what to do with templates:

Brian: Looks good. I think we need to work out how defaults should work first, then consider how template-like behaviour would fit in.

Merging

It's great but I'm not sure if it's necessary for currently pressing use cases. We should still work on it to make sure when we do go to add it the architecture doesn't explode.

Shane: We've agreed it's necessary to make "to" animations clean. I'm still in favor of including it because it doesn't add very much complexity at all, and the merge behavior still needs to be specified regardless.

➙ Shane to add diagrams.

➙ Need to talk about grouping and parameterized merge in more detail in a future meeting.

Sharing of Timing objects

Really, how often will this be done?

Shane: if we don't allow timing objects to be shared, then *that* is when we have to start specifying stuff. They share naturally.

Brian: In section 7 I'm proposing removing them for other reasons.

Shane: I think section 7 has moved to section 9. Section 9 is crazytown; but regardless of what it is called, there *will be* an object or objects with default values that are accessible from script. It is more natural to allow these to be shared than not. Having said that, the templating stuff that we were looking at before might in fact imply these should not be sharable anyway.

TimingFuncCallback

This adds a lot of complexity (just see the massive TODO there) and if we have SmoothTimingFunc then I think we can cover most cases.

2012-11-29[Brian]: I already removed this feature

Shane: I support this

TimedItem.animDuration

Easy to calculate, but necessary?

Shane: probably not. Also tiny. Defer removal unless we have to?

TimedItem.locallyPaused

Again, simple, but necessary? Would pause(), play() and unpause() be enough? (We currently don't have unpause but MediaControllers do. The difference is basically that it wouldn't auto-rewind.)

Shane: this falls out *SO CLEANLY* in code! I'd be reluctant to remove.

Brian: It doesn't mean you remove the code, just that you hide it from view.

Maybe mark at risk?

11. GroupedAnimationEffect

======================

(Brian)

Genuine question, is it needed or should it be merged with KeyframeAnimationEffect?

What is it used for that couldn't be achieved by making KeyframeAnimationEffect support targetting multiple properties like you can do in CSS?

Of course, you could re-use timing to apply to a PathAnimationEffect and KeyframeAnimationEffect, but do you do that often enough that you couldn't just set up a group for that?

I guess doing so would be contingent on being able to represent that arrangement in SVG? Or maybe not since changes to Animations don't reflect back to SVG.

Shane: I'm not fussed either way. We do have a request to support a group constructor that has keyframe offset as the primary key (rather than property) - it would be natural to put this on a group; but less so on a keyframes object directly I think.

Shane: Also it's important to keep in mind that groups were initially included for the purpose of grouping operations inside the compositor. I've got some proposals that would stop this from happening - we should at least review those before committing to removing groups.

Also, I'd like to make KeyframeAnimationEffect a bit more friendly to use by allowing operations such as:

effect.frames.add(0.3, 'left', '100px');

// Overwrites the frame at 0.3 if there is one

Currently, you need to do:

effect.frames.add({ property: 'left', offset: 0.3, value: '100px' });

It might even be worth supporting:

var frame = effect.frames['0.3'];

Returns the last frame with offset 0.3 if there is one. If there is none, does the interpolation and returns a new frame?

Shane: Is this sort of thing something we should defer until v2? It would sit cleanly on top of a more primitive API (and could be polyfilled very nicely in the short term).

> Leave this for now (but make an annotation that these may be possible future improvements)

12. OVERRIDE STYLESHEETS

========================

How are we going here? What was the issue even?

Shane: The issue is that Animations and Transitions in CSS inject into different places in the stylesheet stack. It doesn't actually matter too much though - time sources basically make this problem go away because we can have a time source per injection point.

> We're looking good at the moment

13. ANIMATION STACK & KEYFRAME ANIMATIONS

=========================================

(Continuing actions from a previous meeting regarding merging and behaviour where no keyframe is defined)