Platform/Layout/Web Animations: Difference between revisions
Line 106: | Line 106: | ||
Google don't like the long list of numbers. So they have proposed chaining timing functions like so: | Google don't like the long list of numbers. So they have proposed chaining timing functions like so: | ||
We had another think about how best to represent chained timing functions and | We had another think about how best to represent chained timing functions and | ||
still prefer the idea of splitting the input time fraction into ranges, and | |||
specifying a timing function to cover that range. | |||
"ease-in 0.4 0.4, cubic-bezier(1, 0, 1, 0) 0.7 0.7, ease-out" | "ease-in 0.4 0.4, cubic-bezier(1, 0, 1, 0) 0.7 0.7, ease-out" | ||
Line 114: | Line 116: | ||
- It allows chaining of arbitrary types of timing function | - It allows chaining of arbitrary types of timing function | ||
- It allows specification of discontinuous timing functions | - It allows specification of discontinuous timing functions | ||
- Each timing function can be parameterised independently of the range it spans. For example, in the above, the arguments to cubic-bezier() specify the shape of the curve, which is unchanged if the size or position of its range is changed. | - Each timing function can be parameterised independently of the range it | ||
spans. For example, in the above, the arguments to cubic-bezier() specify the | |||
shape of the curve, which is unchanged if the size or position of its range | |||
is changed. | |||
- It matches the keySplines / keyTimes feature of SVG exactly | - It matches the keySplines / keyTimes feature of SVG exactly | ||
To simplify the common-case of chained beziers where c1 continuity is required, we propose adding a 'smooth' option. Specifying this option means that the direction of the vector representing the starting control point of the bezier is ignored, and only its magnitude is used. Instead its direction is set to be equal to that of the tangent at the end of the previous segment (ie the negative of the vector representing the end control point in the case of a bezier). If the smooth option is specified on the first segement, a direction of (1, 0) (i.e. horizontal) is used. For example ... | To simplify the common-case of chained beziers where c1 continuity is required, | ||
we propose adding a 'smooth' option. Specifying this option means that the | |||
direction of the vector representing the starting control point of the bezier | |||
is ignored, and only its magnitude is used. Instead its direction is set to be | |||
equal to that of the tangent at the end of the previous segment (ie the | |||
negative of the vector representing the end control point in the case of | |||
a bezier). If the smooth option is specified on the first segement, a direction | |||
of (1, 0) (i.e. horizontal) is used. For example ... | |||
"ease-in 0.4 0.4, smooth cubic-bezier(1, 0, 1, 0) 0.7 0.7, smooth cubic-bezier(0, 1, 0, 1)" | "ease-in 0.4 0.4, smooth cubic-bezier(1, 0, 1, 0) 0.7 0.7, smooth cubic-bezier(0, 1, 0, 1)" | ||
Here the direction of the start control point of the first bezier is ignored, and set to match the end of the ease-in segment. Similarly, the direction of the start control point of the second bezier is ignored, and set to match the end control point of the first bezier. | Here the direction of the start control point of the first bezier is ignored, | ||
and set to match the end of the ease-in segment. Similarly, the direction of | |||
the start control point of the second bezier is ignored, and set to match the | |||
end control point of the first bezier. | |||
As a further simplification, we propose that if the coordinates specifying the end of the range are ommitted for some segment, the ranges of any underspecified segments are set so as to evenly distribute the available space (both in x and y). For example ... | As a further simplification, we propose that if the coordinates specifying the | ||
end of the range are ommitted for some segment, the ranges of any | |||
underspecified segments are set so as to evenly distribute the available space | |||
(both in x and y). For example ... | |||
"ease-in 0.2 0.2, ease-in, ease-in" | |||
is equivalent to ... | is equivalent to ... | ||
Line 131: | Line 149: | ||
"ease-in 0.2 0.2, ease-in 0.6 0.6, ease-in" | "ease-in 0.2 0.2, ease-in 0.6 0.6, ease-in" | ||
Furthermore, if only one such coordinate is omitted, it is used for both the x and y components. For example ... | Furthermore, if only one such coordinate is omitted, it is used for both the | ||
x and y components. For example ... | |||
"ease-in 0.2, ease-in, ease-in" | |||
is equivalent to ... | is equivalent to ... | ||
"ease-in 0.2 0.2, ease-in 0.6 0.6, ease-in" | |||
I'm a bit concerned about the complexity of the numbers after the timing function. It's not obvious what they are and it's an additional concept, "rendering the timing function into a window". However, we need something like this not only for bounce effects but also because we removed timing functions from key frames. | I'm a bit concerned about the complexity of the numbers after the timing function. It's not obvious what they are and it's an additional concept, "rendering the timing function into a window". However, we need something like this not only for bounce effects but also because we removed timing functions from key frames. |
Revision as of 07:08, 17 May 2013
Overview
Feature comparison between CSS, SVG, and Web Animations
We could also add "Synchronizing with media" to Web Animations but I (Brian) have some uncertainty about if that will make it into v1.
Simplified class diagram of API
Some things have been simplified:
- Event classes etc. not shown
- Data types not shown
- Keyframe related dictionaries not show
- Timing dictionary not shown
- Enums not shown
- Extensions to Document, Element not shown
Spec issues
Issue 1: Timing interface
Currently we have this kind of arrangement:
interface TimedItem : EventTarget { // Specified timing readonly attribute Timing specified; // Calculated timing readonly attribute double startTime; readonly attribute unrestricted double iterationDuration; readonly attribute unrestricted double activeDuration; readonly attribute unrestricted double endTime; };
interface Timing { attribute double startDelay; attribute FillMode fillMode; attribute double iterationStart; attribute unrestricted double iterationCount; attribute (unrestricted double or DOMString) iterationDuration; attribute (unrestricted double or DOMString) activeDuration; attribute double playbackRate; attribute PlaybackDirection direction; attribute DOMString? timingFunction; };
Why do we have iterationDuration
(and activeDuration
) twice? Because iterationDuration
can be "auto" which is especially useful for timing groups where it means "stretch to fit the children". At the same time it's useful to be able to query the current computed value.
So you have:
anim.specified.iterationDuration = "auto"; var actual = anim.iterationDuration;
I'm a bit concerned about setting and getting in different places. Not sure if the 'specified' is weird.
One alternative:
interface TimedItem : EventTarget { // Timing attribute double startDelay; attribute FillMode fillMode; attribute Duration iterationDuration; attribute Duration activeDuration; attribute double playbackRate; // ... // Scheduled time readonly attribute double startTime; readonly attribute unrestricted double endTime; }; interface Duration { double sec; DOMString string; }
Usage:
var specifiedDur = anim.iterationDuration.string; // "auto" var computedDur = anim.iterationDuration.sec; // 5 // Update duration to 3s anim.iterationDuration.sec = 3; // anim.iterationDuration.string -> "3s" // Update duration to 3s (alt.) anim.iterationDuration.string = "3s"; // anim.iterationDuration.sec -> 3 // Reset to auto anim.iterationDuration.string = "auto"; // anim.iterationDuration.sec -> 5
Google have expressed a (fairly strong) preference for keeping specified and computed timing separate.
Thoughts? Suggestions?
Issue 2: Timing function list syntax
You can't do bounce functions in either CSS or SVG. These are really popular; most animations APIs have heaps of timing functions like this.
I wanted to extend cubic-bezier functions to take a series numbers that define additional cubic bezier segments. The idea was to be a common-denominator so authoring tools could convert complex curves to this format. Then, in a future version we'd add syntax for generating spring functions etc.
Google don't like the long list of numbers. So they have proposed chaining timing functions like so:
We had another think about how best to represent chained timing functions and still prefer the idea of splitting the input time fraction into ranges, and specifying a timing function to cover that range. "ease-in 0.4 0.4, cubic-bezier(1, 0, 1, 0) 0.7 0.7, ease-out" This has several nice properties ... - It allows chaining of arbitrary types of timing function - It allows specification of discontinuous timing functions - Each timing function can be parameterised independently of the range it spans. For example, in the above, the arguments to cubic-bezier() specify the shape of the curve, which is unchanged if the size or position of its range is changed. - It matches the keySplines / keyTimes feature of SVG exactly To simplify the common-case of chained beziers where c1 continuity is required, we propose adding a 'smooth' option. Specifying this option means that the direction of the vector representing the starting control point of the bezier is ignored, and only its magnitude is used. Instead its direction is set to be equal to that of the tangent at the end of the previous segment (ie the negative of the vector representing the end control point in the case of a bezier). If the smooth option is specified on the first segement, a direction of (1, 0) (i.e. horizontal) is used. For example ... "ease-in 0.4 0.4, smooth cubic-bezier(1, 0, 1, 0) 0.7 0.7, smooth cubic-bezier(0, 1, 0, 1)" Here the direction of the start control point of the first bezier is ignored, and set to match the end of the ease-in segment. Similarly, the direction of the start control point of the second bezier is ignored, and set to match the end control point of the first bezier. As a further simplification, we propose that if the coordinates specifying the end of the range are ommitted for some segment, the ranges of any underspecified segments are set so as to evenly distribute the available space (both in x and y). For example ... "ease-in 0.2 0.2, ease-in, ease-in" is equivalent to ... "ease-in 0.2 0.2, ease-in 0.6 0.6, ease-in" Furthermore, if only one such coordinate is omitted, it is used for both the x and y components. For example ... "ease-in 0.2, ease-in, ease-in" is equivalent to ... "ease-in 0.2 0.2, ease-in 0.6 0.6, ease-in"
I'm a bit concerned about the complexity of the numbers after the timing function. It's not obvious what they are and it's an additional concept, "rendering the timing function into a window". However, we need something like this not only for bounce effects but also because we removed timing functions from key frames.
Issue 3: play() and playNow()
CSS doesn't really define when animations start. That can be problematic but it can also be helpful: e.g. allows delaying animation to compensate for vsync etc.
Proposal:
interface Timeline { Player playNow(optional TimedItem? source = null); Future play(optional TimedItem? source = null); ... }
playNow
creates a new Player
with a startTime
set to the current time of the <a>Timeline</a>.
play
creates a new Player
whose startTime
is initially null
. The UA starts it at the earliest possible time ensuring that it begins from the first frame. When it is started, the startTime
is filled in and the Future is resolved (passing in the Player
as the argument).
Issue 4: Out of range keyframe offsets
Issue 5: The KeyframeShortcut type
Implementation
Large pieces:
- Script API
- Rework CSS in terms of same base objects
- Rework SVG in terms of same base objects