Web animations minutes, 11 / 12 April 2013
Etherpad: https://etherpad.mozilla.org/ep/pad/view/ro.NueVWJzPkD6/latest
Present: Steve, Shane, Brian
Agenda:
1. Status update
2. Extended timing stuff
3. Keyframes representation
4. Representing timing parameters
1. STATUS UPDATE
================
Brian: Struggling with events
Steve: blink
Shane:
- matrix interpolation in polyfill
- moving tests over to new test framework
- extended timing stuff
- some blink work
2. EXTENDED TIMING STUFF
======================
https://docs.google.com/document/d/1KjfY7ok3bmltAWOna7p0RzHnj49SRZVAQZhjO0wjS9s/edit#heading=h.v9ginwuoznmr
Discussion of extending cubic-bezier vs. chaining timing functions vs. NURBS.
We have two alternatives we are considering at the moment:
A) Extend cubic-bezier to accept more numbers, basically {4,10,16,22...}
These just define the intermediate control points of a chain of cubic bezier segments.
Analysis:
* Hard to read/tweak once you get past about one segment--pretty much impossible
* Changes to parsing/spec is simply the number of points
B) Allow timing functions to be chained together:
e.g. linear 0.2 0.2, ease 0.5 0.4, cubic-bezier(1, 0, 0, 1) 0.8 0.7, ease-in 1 1
The two numbers following each function specify the "window" into which the function is scaled. So the endpoints of the 'linear' function are 0,0->0.2,0.2, then 'ease' goes from 0.2,0.2->0.5,0.4 etc.
Analysis:
* Much easier to tweak, hand-author
* Allows combining discrete functions with smooth ones--although we may or may not allow this
* Requires more characters for a curve represented by many cubic bezier segments
(A) and (B) are not mutually exclusive. Question is which do we do? Or which do we do first?
Also, in either case we might later add syntax for automatically reflecting control points, e.g. smooth-bezier() or cubic-bezier(smooth, x, y) etc. similar to SVG's 'S' command.
Currently undecided. Brian leans towards (A) (with shortcuts added in a later level) since it seems like a smaller changed, Shane and Steve lean towards (B) because it is more readable/authorable.
3. KEYFRAMES REPRESENTATION
============================
There are three pending changes:
- Allow per-value composite modes
- Allow multiple target properties per key frames animation effect
- Removing interfaces and replacing with dictionaries
These three are blocked on working out how to represent the key frames:
(a) by-frame only,
(b) by-property only,
(c) by-frame with shortcuts to allow constructing them with property value arrays
(d) by-property with shortcuts to allow constructing them by frame
The by-frame approach has the advantage of matching what CSS does. It also *may* be more intuitive for animators--we're not sure.
The by-property approach has the advantage of being simpler to construct. It also matches SVG's behavior more closely. It also avoids the issue that arises when you have automatically spaced keyframes mixed with fixed offsets and whether or not two values appear in the keyframe depends on the precision with which the offsets are calculated/specified.
4. REPRESENTING TIMING PARAMETERS
==================================
Where are we up to with this?
Currently we have:
interface TimedItem : EventTarget {
// Specified timing
TimingDictionary getTiming ();
TimingDictionary setTiming (TimingDictionary timing);
// Calculated timing
readonly attribute double startTime;
readonly attribute unrestricted double iterationDuration;
readonly attribute unrestricted double activeDuration;
readonly attribute unrestricted double endTime;
};
* Re-uses the timing dictionary to keep the API surface area small
* Has the unfortunate side-effect that:
anim.setTiming({ iterationDuration: 3 })
clobbers all other timing. It's possible to work around this but clumsy.
Alternative A:
Introduce Timing interface.
* Duplication of parameters: a dictionary version and an interface version → increases API surface area, awkward to maintain / spec
Alternative B:
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
* Some duplication of parameters between the dictionary and TimedItem
* Setting and reading duration happens in same place
* Mimicks patterns proposed for CSS Lengths and SVGLength
* Easy to extend this to support percentage measures in the future (which is likely for duration properties)
* Not easy to apply this pattern to other parameters in the future (e.g. if we want to make playbackRate accept a string we'd have to introduce another attribute in order to use the same pattern)