- From: Brian Birtles <bbirtles@mozilla.com>
- Date: Wed, 08 Aug 2012 14:38:46 +0900
- To: "public-fx@w3.org" <public-fx@w3.org>
Web Animations minutes, 7 / 8 Aug 2012 Etherpad: https://etherpad.mozilla.org/ep/pad/view/ro.eiMsLaB5x-p/latest Present: Dmitry Baranovskiy, Alex Danilo, Shane Stephens, Brian Birtles Agenda: 1. Renaming Anim/AnimInstance 2. What time do you pass to seek()? 3. Liveness 4. Template classes 5. Removing the Timing interface 0. STATUS UPDATE Dmitry checked in Enum support to respec.js. Works great. Brian working on start(), stop(), reverse(), changeSpeed(), pausing etc. One month out from SVGOpen. Current work items: 1. Specification (Brian / Dmitry to provide support) Shane to address TODOs in "Primitive animation operations" section 2!. Presentation (Alex) (3). SVG Integration spec 4. Emulator (Shane and hopefully Dmitry) Shane to send Dmitry current state, so he can get familiar with the code. (5). CSS Integration spec 1. RENAMING Anim/AnimInstance Now that we have the global Animate function, script does not need to refer to the Anim interface directly as often. Can we rename as follows? s/Anim/AnimProto/ s/AnimInstance/Anim/ AnimTemplate may be better than AnimProto to avoid confusion with Anim.__proto__ and AnimPrototype > We will rename Anim -> AnimTemplate, AnimInstance -> Anim 2. WHAT TIME DO YOU PASS TO SEEK()? Suppose I have this animation: anim { delay: 3s; from: 100px; to: 200px; dur: 5s; } (Forget the syntax, this is some CSS-SVG neutral ground syntax I just made up) 3s after the document loads it begins animating from 100px to 200px. It finishes 8s after the document loads. Later I call anim.seek(3). What is the result? a) 100px b) 160px c) something else? Answers: Alex and Brian: (b) Shane: (a) or global time Dmitry: (a) or (b) Currently the answer as spec'ced is (a). If (b) is more intuitive then I need to revise how seek() works. The up-shot is we can probably get rid of the whole concept of item time which is probably confusing to most people. What if you repeat the experiment, assuming that the animation was not triggered until after 30s (i.e. has a start time of 30s)? > Discussion about whether delay should be considered an intrinsic or extrinsic part of an item's timeline. General consensus that the model is currently angled towards it being intrinsic (e.g. the sandwich model sorts by start time and delay allows items to be shifted in their "effect" but still sorted by the sandwich model). Some disagreement wrt. "Active" being only when an item is filling or animating - i.e. an item can be in delay but not "Active" if there's no fill. > Resolved that it's intrinsic. i.e. seek(3) includes delay > Brian to look at rephrasing section talking about "Active" animations 3. LIVENESS Some proposals to consider: PROPOSAL A: Explicit delinking (from François REMY) Similar to existing but don't automatically break liveness. Rather, if a change is made to a linked instance (live instance) throw an exception and require an explicit call to makeIndependent (delink?) in order to make the change. Shane: I like this for its brittleness - if you do something unexpected we make sure you know about it up-front. PROPOSAL B: Everything is individually overridable except the AnimationFunction which requires explicit delinking Originally when we tried to approach liveness we did what you'd expect, i.e. var template = new AnimTemplate; template.timing.speed = 3; var anim = template.animate(...); ? template.timing.speed // 3 ? anim.timing.speed // 3 anim.timing.speed = 4; ? template.timing.speed // 3 ? anim.timing.speed // 4 template.timing.speed = 5; ? template.timing.speed // 5 ? anim.timing.speed // 4 But we ran into two problems: i) How to reset each of these properties? ii) Following this scheme through to all the different types of AnimFunction (including those to be added in the future, and script-defined ones) and supporting this property-by-property tracking on each of their sub-properties seemed like a real pain. With regard to (i), I've defined TimedItem.animationDuration so that you can override the computed value. You can reset it by just assiging it to undefined or null (currently I've gone for undefined, but we can change it to null). I spoke to Cameron McCormack (WedIDL spec editor) and he says that's fine. For (ii) we could say we do property-by-property overriding for the timing properties (i.e. everything on TimedItem and Timing), but treat the func property specially, i.e. if you try to change the copy attached to the instance it will throw an exception and you need to call clone (or something similar) before you can change it. Unlike A, this lets you make small tweaks to the timing without losing liveness of the rest. Shane: This works OK but do we have a strong use-case for tweaking the timing without losing liveness? If not, then maybe this is too complex. PROPOSAL C: No liveness Just drop liveness altogether. SVG and CSS do the bookkeeping of copying property changes across. (Brian: This does raise some questions though. Will SVG and CSS just blindly overwrite the values on the instances? If not, you basically run into the same problems outlined at the start of proposal B.) Shane: I don't like this mainly because liveness will be useful to advanced script users too, so we'd be replacing 1 painful mechanism with 3 painful mechanisms that mostly do the same thing. Note that if we go with C, we could introduce A (or even B) in a later version. Alex and Dmitry: favour doing C for now, introducing A later Dmitry: This is probably dependent on what we decide to do with the Timing interface. Shane: Objections: - practically, this is already needed for SVG/CSS integration and authors will also sometimes want this feature (liveness), so we should support it - philosophically, if we're having such a hard time getting it right, why just shift the burden to SVG/CSS? > We'll come back to this in light of what we decide regard to Template classes at the Timing interface 4. TEMPLATE CLASSES This is related to liveness but orthogonal to most proposals. The question is, do we need template classes? One alternative we could have is to have Anim objects that have no target / startTime / parent, very lonely individuals, but nevertheless welcome. In a sense, these are the templates. To create an "instance" you clone an Anim object and give it a target / startTime / parent along the way. Anim objects might have 'defaultTarget' and 'defaultParent' properties to simplify cloning. i.e. anim.animate(4). Liveness could still be achieved by having clones refer back to their source. What this gives us is: * A lot less interfaces to specify. It's simpler because you don't have to match up these parallel hierarchies. * We could possibly also get rid of the Timing interface since the main reason it has been split out is to share the definitions between template and instance Some downsides are: * Confusing to have some Anim objects that work as templates and some that are actual animations * In future it's probably useful to overload just the templates. e.g. for the SVG integration, define a special SVGAnimTemplate that does all the complicated work of managing syncbase timing etc. and then just spawns these very simple vanilla Anim objects at the appropriate times. Shane: This has some intriguing possibilities. I would modify it slightly to exclude *just* the target, and allow the "template" versions to be inserted into timelines like "normal" ones. These would then act essentially as spacers. This removes the first downside, and means that every Anim object is both a template and potentially an animation. In fact, untargetted Anim objects can even be parented by the global group, as this is a "par" group. The second downside doesn't really seem like a downside to me :) Basically the mechanism is roughly the same, and we're only having a bit of trouble thinking about it because we started down the other path already. Brian: Concerned about having all these dummy animations in the tree that are simply there to be cloned. It's confusing when you walk the tree and half of the "animations" are not actually doing any animation. > Need to flesh out the details to see if this is workable: Kicking ground for the idea: https://etherpad.mozilla.org/07VpfyGtdw 5. REMOVING THE Timing INTERFACE I (Brian) find the Timing interface a little confusing. For example, you have: anim.timing.startDelay BUT anim.startTime There's good reason for it--the delay is a property of the template, the start time is related to the specific instantiation--but I think authors will find it confusing. What do you think? There are two reasons for the existence of the Timing interface: * Share definitions between AnimTemplate and Anim * To allow separation of specified and computed values i.e. we have anim.timing.iterationDuration -- the specified duration, can be null meaning 'intrinsic duration' (e.g. for groups, videos etc.) but we also have anim.iterationDuration -- the calculated duration I (Brian) was thinking about collapsing Timing into TimedItem/TimedTemplate. This would give you: interface TimedItem { // Previous Timing interface attribute float startDelay; attribute unrestricted float? iterationDuration; attribute unrestricted float iterationCount; attribute float iterationStart; attribute float speed; attribute PlaybackDirection direction; attribute TimingFunction timingFunction; attribute FillMode fill; // Existing TimedItem interface readonly attribute float? animationTime; attribute unrestricted float animationDuration; readonly attribute float? iterationTime; readonly attribute unrestricted float iterationDuration; readonly attribute unsigned long? currentIteration; attribute float startTime; readonly attribute unrestricted float endTime; readonly attribute AnimGroupInstance parentGroup; readonly attribute float timeDrift; void start (optional float timeFromNow = 0); void stop (optional float timeFromNow = 0); void pause (); void unpause (); bool getPauseState (); bool isPaused (); void seek (unsigned long itemTime); void changeSpeed (float speed); void reverse (); void cancel (); }; and: interface TimedTemplate { // Previous Timing interface attribute float startDelay; attribute unrestricted float? iterationDuration; attribute unrestricted float iterationCount; attribute float iterationStart; attribute float speed; attribute PlaybackDirection direction; attribute TimingFunction timingFunction; attribute FillMode fill; // Existiing TimedTemplate interface TimedItem animate (Element target, optional float startTime); ... }; For the two versions of iterationDuration you could either have: specifiedIterationDuration computedIterationDuration (or something a bit shorter) Or just do like I've done with animationDuration. i.e. you can override it, otherwise it reflects the intrinsic iteration duration. That doesn't work so well, however, if we want the specified duration to take on values like "20%" etc. Regarding the definitions, you'd define it once (probably in TimedTemplate since it appears first) and then just refer to those definitions from TimedItem. Which do you prefer? Shane: I must admit I actually like the separation of specification and computed values, which is what we have at the moment. If we roll these in together, maybe prefixing the computed versions with "computed" could be good? I don't think we'd also need a "specified" prefix. Dmitry: Proposal to keep timing properties as properties, but convert all dynamic properties into methods. TimedItem.animationTime → TimedItem.animationTime() [or TimedItem.getAnimationTime()] This way it’s more clear that the value is not static and could be potentially expensive to get. If we decide to make them writable we could always allow the method to accept value or add setAnimationTime() (which is obviously uglier). This will remove confusion: anim.timing.startDelay anim.startTime or anim.startDelay anim.startTime() Next meeting: 9 Aug 18:00 PDT / 10 Aug 11:00 AEST / 10 Aug 10:00 JST @ https://etherpad.mozilla.org/CVoYIc2pWz
Received on Wednesday, 8 August 2012 05:39:18 UTC