It's *horrible* on mobile devices, in both Chrome and Firefox. There's no reason for it to be horrible at all, though. Triggers solve this problem; and if done right can be used to implement the existing trigger behaviour in SVG (i.e. they don't actually introduce much in the way of new functionality).
My proposal (in summary) is to add 2 trigger properties to the Timing object; one for control of the timing window (i.e. startDelay + duration), and one to control the transfer of non-timing events to time fraction ("scrolling through time").
Might be better to avoid having multi-valued startDelay / iteration and instead push control of iteration count up a level.
Discussed the possibility of adding a fixed delay to each iteration. This might be useful. If it is a common pattern we will consider adding this feature in the future. But for variable delays, we will try to add that at a level up (e.g. in the group or template).
➙ Shane to write up a proposal for triggers (after checking with Alex about how SVG works in this regard)
3. REVISITING THE ARCHITECTURE
There are a number of outstanding and significant issues regarding the architecture we've yet to solve including:
How can we make an API that is suitable for long-lived cartoon-like animations as well as one-shot simply animated effects? In particular, how can we spare the UA from having to hang on to those one-shot animations like it does for cartoons?
How can we preserve a forwards fill without requiring the UA to store the entire animation that generated it for eternity? Particularly given that most of the time for scripted animations you probably want a forwards fill. Our own limited experience confirms this.
(Initially we thought this would be possible by just substituting out the timing model, but the above example indicates you probably want some features of the timing model like sequencing and grouping even without the 'time' itself)
How can we make it so simple animations are easily offloaded to the GPU?
How can we make it all a bit simpler?
I (Brian) have the following very rough proposal:
Introduce a TimeSource interface. It could be called Clock or perhaps even Timeline.
It has a single method/attribute currentTime
Returns a float giving a time or null if the time source is not currently running
There is a global (per-document) DocumentTimeSource (DocumentClock?) that returns a monotonically increasing time starting at zero when it is started (depends on the autoplay / timelineStart properties defined elsewhere) and null until then.
This is a subtle but significant difference: the document time source is NOT a group.
That means most single-shot animations DON'T get added to a group
That means they aren't part of some timegraph and they can disappear when they finish without anyone noticing or caring
That means you can't just reverse all the animations in the document and I'm pretty sure that's desirable (because doing so makes it almost impossible to create a "normal" animation until you restore the world--if you want to reverse a lot of stuff, you should manage the scope yourself by adding them to a group).
If pausing all animations in the document proves useful then we add pause() to DocumentTimeSource but I suspect it's not useful.
Debugging tools can still call document.getActiveAnimations() to see what's playing
It might also be useful to add "newanimation"-type events to assist tools like this
Basically, you only add groups when you want groups
Shane: I think getActiveAnimations should be on the TimeSource, not the document. And the TimeSource should “own” the animations but only until they’ve finished playing.
AnimGroup would implement the TimeSource interface
As well as pointing to a parent time source
SVG would still have a ParAnimGroup corresponding to the <svg> element and all child animations would continue to be added there.
That group won't die because there's an owning reference from the SVGSVGElement.
As a result everything persists as usual and you can pause/reverse everything in the document
The Anim.parentGroup attribute would probably be renamed (clock? timeSource? timeParent?) and given type TimeSource. If you really want to walk up the tree you'd have to test if the parent thing was an AnimGroup or not.
At an implementation level, once an animation has finished, if no one else is referencing it, you could drop it.
If it has a forwards fill mode, you could store that final value and simply add it to the sandwich. (This is assuming no one else is referencing the animation.)
You can’t rewind the DocumentTimeSource (it’s monotonically increasing) so you'd only need to store the final value (frozen value) of the last animation that finished with a forwards fill.
Shane: Not quite true. Fill compositing means you need to store more. Also, how do you undo this if you've lost a reference to the animation?
Brian: See below, we need a way of clearing the effects of old animations. I'm suggesting you wouldn't be able to clear the result of a specific animation, but just all animations on a property. CSS Animations probably will need a way to remove just their result if the selector stops matching but that could be specific behaviour of the CSS bindings? CSS Transitions (doesn't fill via animation), SVG Animations (always alive since they are part of the <svg> element par group), and scripted animations should all be fine though.
It's safe to drop the old animations since there’s no way to get at them from the API anyway since document.getActiveAnimations() only returns the 'active' animations (we'll have to make sure that definition excludes filling animations)
We probably need to add a way of clearing the effects of old animations but that's all
It is possible to define custom TimeSources that correspond to, e.g. the position of the scrollbar, the mouse position etc.
This could either be done declaratively (like VRML), or by providing a callback
Shane: Our work in this area indicates that simply replacing time input with a position isn't enough. Specifically, you often want some kind of "momentum" that takes over an animation and guides it to one of a small number of states when it's not being scrolled.
Brian: Momentum would be nice.
I'm also going to try to demonstrate to you all that solutions requiring callbacks are not going to provide users with a smooth experience, especially not on mobile devices.
Brian: Agreed that declarative is preferable for smooth UI interactions. VRML 97 is pretty good prior art for a declarative approach: it lets you route different inputs to output so that, for example, you can tie the rotation of a door, to the position of the mouse that clicked it. It doesn't have momentum but still works pretty well.
A callback is probably useful for an entirely different range of use cases (e.g. an animation that is synchronised with progress events from fetching a network resource). As callbacks are tricky, this could be postponed to v2.
Sampling might work by
first identifying root time sources used in the doc,
getting a current time once,
if it hasn't changed since the previous sample,
skip all animations tied to that time source
sample the model using the cached current time
For simple animations whose parent is the document time source we can quickly identify them as candidates for hardware acceleration / async compositing since we know they don't depend on anything else and they aren't governed by time manipulations on a parent group.
Shane: offloadability to the GPU is not the specific optimisation target that WebKit has. We'll need to find a way of framing hardware acceleration so that it's general across all the browsers.
Brian: This is a very rough brain dump, but I think something of this ilk addresses the lifetime issues for both effects and cartoons, is simpler, is more amenable to hardware accel, and addresses the gesture use case.
Shane: Does this mean that you need to do something quite special (put everything into an open-ended par group and hold a reference to it) in order to see timeline information?
If that's the case, maybe we could go even further and make a specific timeline group type which you need to use to keep this kind of information?
Brian: Is the use case a debug view? If that's the case then I'm suggesting the combination of document.getActiveAnimations and events like “new animation” to cover it.
➙ General agreement about the TimeSource approach but Shane will provide a slightly different proposal whereby time sources other than the global clock can still be used within time containers.
> Re naming:
* Many like timeline
* But time source makes sense to others
* Luke suggests ClockSource
* Brian also suggests Clock (to match CSS: animation-clock)
> We'll wait for Shane's proposal before committing to naming
Brian: An alternative to all this is Core Animations adds a 'removeOnCompletion' flag that defaults to 'YES'. Not sure how that helps with fill modes though.
4. POLYFILL ADMINISTRIVIA
I propose all checkins to be prepared in branches (inside the project is fine) and reviewed by someone else (anyone else on the project is fine) before checkin.
➙ Dmitry to find out what w3c uses for purely scripted tests (as opposed to reftests)
➙ Shane to set up coverage tool
Brian: I think it's good to define the target browsers
e.g. Latest Chrome (desktop + Android), latest Firefox (desktop + Android), latest Opera desktop, Opera Mobile, IE8+, iOS 5+ Safari, latest Mac Safari
Brian: some data gathering re making IE8 or IE9 the baseline, according to StatCounter as of October 2012, worldwide IE 8 has 12.66% of the market (i.e. more than all versions of Safari and Opera combined) and declining only fairly gradually.