- From: Brian Birtles <bbirtles@mozilla.com>
- Date: Thu, 02 May 2013 10:12:09 +0900
- To: "public-fx@w3.org" <public-fx@w3.org>
Web Animations minutes, 1 / 2 May 2013 Etherpad: https://etherpad.mozilla.org/ep/pad/view/ro.Ym0Dvh3bo6f/latest Present: Doug, Dmitry, Shane, Brian Agenda: 1. Status update 2. Keyframe shortcuts 3. Extending timing functions 4. Representing timing parameters 5. Starting animations now-ish 1. STATUS UPDATE ================ Brian: - Finishing off timing events, esp. the non-normative dispatch algorithms - Keyframe animation effect changes - allow targetting multiple properties - allow per-value composition mode - remove timing functions from key frames - redoing the IDL Shane: - Some blink implementation work 2. KEYFRAME SHORTCUTS ===================== (Brian) I've reworked the keyframes part as described in the status update and also updated the IDL to match. Using the dictionaries as-is, you end up with a syntax like this: [ { values: [ { property: 'left', value: '50px', composite: 'replace' }, { property: 'top', value: '50px', composite: 'replace' } ], offset: 0 }, { values: [ { property: 'left', value: '100px', composite: 'replace' }, { property: 'top', value: '100px', composite: 'replace' } ], offset: 1 } ] Using default values for 'composite' and 'offset' you can get it down to: [ { values: [ { property: 'left', value: '50px' }, { property: 'top', value: '50px' } ] }, { values: [ { property: 'left', value: '100px' }, { property: 'top', value: '100px' } ] } ] For animating a single property only it becomes: [ { values: [ { property: 'left', value: '50px' } ] }, { values: [ { property: 'left', value: '100px' } ] } ] And for the simplest case, to-animation, it becomes: [ { values: [ { property: 'left', value: '50px' } ] } ] The last two are very common and there are a *lot* of braces and commas involved for a simple effect. So I started investigating shortcuts and came up with two basic options: Option 1, in the KeyframeAnimationEffect ctor / setFrames / Element.animate support the following shortcuts: { left: '50px' } { left: [ '50px', '100px' ] } e.g. elem.animate({ left: '50px' }, 3); Notes: * Only one argument is supported (this avoids the precision issues that arise when trying to line up the offsets of parallel arrays) * This only applies at the top-level. Basically we test if the argument is an array or an object and process differently. i.e. you can do: keyframeEffect.setFrames({ left: '50px' }) or, keyframeEffect.setFrames([ { values: [ { property: 'left', value: '50px' } ] } ]); Option 2 consists of two parts. Firstly, (a) introduce the following as a short-cut for a Keyframe dictionary (i.e. a single frame) so it can be used anywhere a Keyframe dictionary can be used: { left: '50px' } Doing that means setFrames becomes: keyframeEffect.setFrames([ { left: '50px' } ]) Two-valued animation becomes: keyframeEffect.setFrames([ { left: '50px' }, { left: '100px' } ]); For the single-keyframe case the extra array [] braces seem unnecessary and would be particularly noticeable with Element.animate since it would become: Element.animate([ { left: '50px' } ], 3); Which is frustrating for something you do a lot. So, as a second step (b), introduce an additional shortcut to these methods that accepts a single object or an array. This would let you do: keyframeEffect.setFrames({ left: '50px' }) Also, since there's no array shortcut (unlike Option 1), we can safely allow multiple properties. This makes the following possible: keyframeEffect.setFrames([{ left: '50px', top: '50px' }, { left: '100px', top: '100px' }]); In essence what we're doing is introducing a type KeyframeShortcut which, as with Option 1, you can't represent in WebIDL due to limitations regarding iterating object properties. That's fine since we can add ECMAScript-specific prose to describe how to achieve this in a safe way. Then we do as follows: typedef (Keyframe or KeyframeShortcut) KeyframeOrShortcut; typedef (KeyframeOrShortcut or sequence<KeyframeOrShortcut>) KeyframeParameters; e.g. void setFrames(KeyframeParameters frames); We can distinguish a Keyframe object from a KeyframeShortcut object by testing for the presence of a 'values' property. Regarding the offset property, we could either: (a) 'offset' maps to a CSS property called 'offset'--if you want to specify the offset you have to use the full syntax. (b) 'offset' maps to the keyframe positional offset. If an 'offset' CSS property is ever introduced, either: - you won't be able to animate it using the shortcut - we'll introduce some other name especially for it, e.g. 'cssOffset' (c) Rename the offset member of the KeyFrame dictionary now to avoid risk of a later clash, e.g. 'keyframeOffset' I kind of gravitate towards (b) since it makes the following possible: elem.animate([{ left: '50px' }, { left: '100px', offset: 0.7 }]); This seems like a fairly natural syntax and the likelihood of an 'offset' property being introduced seems somewhat low? (we have lots of xxx-offset properties but no bare 'offset'). Note that to set a per-value composite operation you have to use the full syntax. e.g. keyframeEffect.setFrames( [ { values: [ { property: 'left', value: '50px', composite: 'add' } ] }, { values: [ { property: 'left', value: '0' } ] } ] ); That's pretty verbose but this is probably an advanced use case. The main situation where you would want to mix composite modes is to-animation which can be handled using the shortcuts. Overall I think Option 2 is preferable to Option 1 since it doesn't deviate as far from the canonical representation. The API remains frame-based; it doesn't provide a pseudo-property-based mode. That's a win from an understandability point of view: authors aren't switching between two modes of thinking. Furthermore, Option 1 suffers from the inconsistency of supporting a short-hand syntax for single-property animations but not for multiple-property animations. That's likely to surprise authors and is also inconvenient. The cost is verbosity for the case where you want to do this: left: 50, 150, 80, 300, 200, .... Since it becomes: elem.animate([{ left: '50px' }, { left: '150px' }, { left: '80px' }, { left: '300px' }, { left: '200px' }, ...]); I think for now it's trivial to write a utility function to generate that list. If *everyone* is doing this we can investigate other shortcuts later--perhaps even another type of AnimationEffect that is property-based (i.e. one property only and takes a list of values). For version 1 we ship the animation effect that matches CSS most closely. ➙ Assuming we can make/alter key frame animation effects from the API, Option 2 seems best. ➙ With regards to the offset property, we prefer option (b) Shane: I'm happy to go with this frame-based approach because it matches the status quo. I would like to provide feedback that as a developer a property-based approach is easier for me to deal with. However it is worth noting that a polyfill converting property-based definitions to keyframe-based definitions is reasonably trivial. Brian: And now for something completely different: another alternative is to not allow creating animation effects from the API at all in v1. Rather, you point to either a CSS animation name or an SVG animation element and it gets its animation function from there. Shane: This would mean being stuck with CSS animation syntax for complex DOM animations that aren't SVG animations. Doug: One disadvantage with this approach is that it makes doing dynamically generated animations really hard. ➙ Based on experience with Raphaël and a quick survey of whether people are actually generating animation effects dynamically, we think the ability to create animation effects from the API is necessary after all. 3. EXTENDING TIMING FUNCTIONS ============================= Recap: Google Sydney team to look at tweaking approach/syntax to reduce cognitive load, make more readable etc. ACTION: Sydney team to actually do this Other related actions while we're at it: ACTION: Steve to write design doc for media integration ACTION: Shane to turn Steve's design doc into spec prose ACTION: Doug to write spec prose for path effects ACTION: Shane to write prose for sections 22 and 23 ACTION: Sydney team to review Events ACTION: Sydney team to review sections 17 – 21 4. REPRESENTING TIMING PARAMETERS ================================== Issue: Dictionary only? Timing interface? Duration member? (see: http://lists.w3.org/Archives/Public/public-fx/2013AprJun/0063.html) Shane: I talked to Elliot about this. He was pretty convincing that we should have a TimingDictionary and a Timing interface, and that doing iterationDuration.string / iterationDuration.seconds (or whatever) is not a great idea. Reasons: - Promoting duration etc. to interfaces may be costly from an implementation point of view - Verbosity: iterationDuration.sec is longer than iterationDuration (Brian's counter-point: specified.iterationDuration is longer than iterationDuration.string; Shane: but iterationDuration is more likely to be used than specified.iterationDuration) - Duplicating the Timing interface members as a dictionary is no problem. That's what dictionaries are for. Shane's additional reason: hiding the layout computation away behind a 'unit conversion' seems to be mixing things up. Brian: SVG already does that. Shane: but CSS doesn't, and CSS is much more widely used. Brian has reservations that the TimingDictionary / Timing approach might be confusing because of the separation between specified and computed timing that this approach implies. Not sure it's necessary to introduce this concept. Shane feels that this will be familiar to users of CSS. ➙ Go with Timing / TimingDictionary for now, introduce an issue into the specification that details the .string/.sec approach to get wider feedback. 5. STARTING ANIMATIONS NOW-ISH ============================== Summary: To support CSS properly, it's nice to be able to have a start-when-ready (this is so that the compositor can slip start-time until the next available vsync, after painting a new layer, etc. etc.). We'll need to implement something like this. Should we expose it? Some discussion about whether play or playNow should be the default (e.g. play / playNow or play / playSoon)? ➙ Leave it out of the FPWD but consider introducing it shortly afterwards. Add an issue so we don't forget. Next meeting: Thurs May 9 18:00 PDT / Fri 10 May 11:00 AEST / Fri 10 May 10:00 JST @ https://etherpad.mozilla.org/NIDeLZFzCR Past meetings: http://www.w3.org/Graphics/fx/wiki/Web_Animations/Meetings
Received on Thursday, 2 May 2013 01:12:39 UTC