Meeting 46
Web animations minutes, 14 February 2013
Present:
Agenda:
1. Timing
2. Pausing on pagehide / unload
3. getCurrentAnimations()
1. TIMING
========
Straw man proposal: http://www.w3.org/Graphics/fx/wiki/Web_Animations/Shared_Timing
Sidenote: list of most beautiful UI animations of 2012: http://beautifulpixels.com/iphone/best-of-2012-ui-animations/
Steve's getComputedTiming suggestion:
TimedItem
- timing
- duration
- playbackRate
- iterationCount
- ...
- getComputedTiming()
One suggestion:
anim.currentIteration
anim.endTime
anim.startDelay
anim.iterationStart
anim.iterationCount
anim.iterationDuration
anim.activeDuration
anim.fillMode
anim.playbackRate
anim.direction
anim.timingFunction
anim.useIntrinsicDuration()
anim.usePercentageDuration()
Another suggestion:
TimedItem:
double startDelay;
double iterationStart;
double iterationCount;
(double or DOMString) iterationDuration;
FillMode fillMode;
double playbackRate;
PlaybackDirection direction;
TimingFunction timingFunction;
ComputedTiming getComputedTiming();
Interface ComputedTiming
double startTime; // Need for seq children in particular
double endTime;
double currentIteration;
double activeDuration;
FillMode fillMode;
double playbackRate;
PlaybackDirection direction;
TimingFunction timingFunction;
Notes:
- ComputedTiming is different to the Timing dictionary since it provides some members you can't set in the Timing dictionary (such as the startTime) and because values in ComputedTiming are always resolved values (e.g. doubles) rather than allowing magic values
- activeDuration is not currently on TimedItem. It will be added there when we allow overriding it. This allows us to make its type (double or String) without breaking content (as might happen if it were double to begin with)
- FillMode is returned in ComputedTiming since we want to encourage people to read values from there in case we make FillMode a calculated/intrinsic value in the future. Likewise for playbackRate, direction, timingFunction.
- In future playbackRate may be overrideable, e.g. "10px/s"
- Feels like this is a bit heavy-handed when most of the members will be identical to those on TimedItem all the time.
However, WebIDL does not allow (double or DOMString) as a union type since double and DOMString are not distinguishable:
http://www.w3.org/TR/WebIDL/#dfn-distinguishable
(double or ExtendedDuration) duration
dictionary ExtendedDuration {
DurationType type;
DOMString spec;
};
enumeration DurationType {
"intrinsic",
"calc",
"percentage"
};
anim.iterationDuration = { type: "intrinsic" };
anim.iterationDuration = { type: "calc", spec: "calc(20% + 1)" };
anim.iterationDuration = 2;
Try again:
(double or ExtendedDuration) duration
dictionary ExtendedDuration {
DOMString dur;
};
anim.iterationDuration = { dur: "intrinsic" };
anim.iterationDuration = { dur: "calc(20% + 1s)" };
anim.iterationDuration = 2;
In SVG:
Alternatively just have:
any duration;
And describe handling that effectively does (DOMString or double). Is this possible?
This is what setTimeout() does.
After discussion with Cameron it appears that is has recently been decided that in WebIDL you can overload with primitives vs DOMStrings and so it may be that it is allowed in unions too
This approach has been accepted as a compromise we’re all happy with.
2. PAGE HIDE / UNLOAD BEHAVIOUR
==============================
Should animations pause when:
a) A link is clicked to navigate to another page? i.e. if you click back does it resume?
b) The page goes into a background tab
a) A link is clicked to navigate to another page.
What does video do?
In Firefox, if you navigate to another page and go back, the video resumes from where you left off.
In Webkit and Opera, the video starts from the beginning.
Most browsers have a bfcache / Page Cache / Fast Navigation Cache. Can we spec that if the page is cached it is paused? A MAY requirement?
b) The page goes into a background tab
General agreement that animations should NOT be paused in this case. If you actually want this behaviour, you can use onpagehide etc. to pause all the animations.
Discussed how on some mobile UAs javascript in background tabs can be suspended in order to save battery. Likewise, we might expect animations to be throttled so low they effectively get no samples.
In SVG there have been similar issues where an animation that has not been sampled for a long time (e.g. because the computer was asleep) produces a major performance hit when the computer wakes up and we try to "catch up" the animation including firing 1000s of events. This suggests the implementation should be allowed to pause animations in such circumstances.
We could add a wakeup / sync event later to indicate that animation time drifted from wallclock time.
3. getCurrentAnimations()
====================
Current?
Is presently defined to include all animations that are either running (in the active interval) or yet‐to‐run. The definition needs to be reworked to include animations that have finished but are in a group that is still running since these animations might run again (e.g. if it’s iterating).
getCurrentAnimations returns animations, but sometimes we want the set of active players
We could have getActivePlayers() and Player.getCurrentAnimations(optional element)
Use cases:
① As a web author, I want to extend an animation written in CSS, by adding a JavaScript animation effect
○ Element.getCurrentAnimations():sequence
② As a web author, I want to remove all animations targetting an element / fragment to serialize the static state of the content
○ Element.getCurrentAnimationPlayers()->cancel()
○ Is there a way to do this without killing other animations in the ‘scene’?
◊ foreach [ animation.effect = undefined ]
③ As a web author, I want to find the green glow animation on a button, and make it glow red since the deadline is approaching
○ Element.getCurrentAnimations():sequence, walk through and find the one with the right animation effect, change the effect
④ As a web author, I want to pause/cancel/change-playback-rate for all animations when some event occurs (eg. when I show a modal dialog)
○ Document.getCurrentAnimations():sequence *could* do this but a list of players would be much more suitable.
○ Do you actually want to pause transitions too?
○ How about Document.timeline.getCurrentPlayers()?
⑤ As a library/tool developer, I want to look up all the animations targetting an element so I can produce a debug view
○ Element.getCurrentAnimations():sequence, just iterate over and display
○ Element.getCurrentAnimationPlayers() if you want to look at the scenes.
⑥ As a web author, I have a running animation that scrolls the view, and I want to inspect the progress of the animation so I know where to add another graphic/animation such that it appears on screen.
○ Element.getCurrentAnimations() → find appropriate animation → getComputedTiming()
⑦ As a web author, I have a running animation and I want to create a new target element and apply a new animation to the new target that picks up where the previous animation left off.
○ Element.getCurrentAnimations() → do stuff
⑧ As a tool developer, I want to show a timeline of all animations in the document with the ability to inspect them.
○ Document.timeline.getPlayers()->timedItem
Proposal:
Document.timeline.getCurrentPlayers():sequence
Element.getCurrentAnimations():sequence
Element.getCurrentAnimationPlayers():sequence
Other ideas considered:
Document.timeline.getCurrentScenes():sequence
Player.getCurrentAnimations(optional Element):sequence
4. EFFECT TEMPLATING
====================
Agreed to model basic keyframe effect templating inside the CSS integration specification. This would involve keyframe effects being able to have parent effects, and the list of used keyframes being the union of the local and parent lists.
Doug presented an alternative in which incomplete CSS keyframe specifications lead to animations represented by par groups. Some concern was expressed about returning ParGroup objects when there are no par groups in the markup.
5. GroupedAnimationEffect
=====================
1. Drop GroupedAnimationEffect
2. Keep merge in operator enum
Brian was unsure about if we should expose merge at the API level or just provide special behaviour that basically does a merge when you have no zero keyframe animation much like SVG’s to-animation or like CSS to some extent. We think it's ok to expose merge for now and see how developers react. If it is problematic we can review how to approach this.
There is consensus on supporting merge within the model.
Shane briefly discussed potential future extensions to merge and grouping:
* parameterized merge with optional start and end values (in seconds or percentages)
* using either TimingGroups or named compositorGroups to group compositor stack entries together. There was some trouble with this so we need to think about it more. Specifically: Brian is uncomfortable using TimingGroups as compositor groups, and if we use named compositorGroups we need some way to specify the operator for the groups.