Server Notice:

hide

Public Pad Latest text of pad bfJdTefySR Saved Aug 7, 2012

 
Meeting 25
7 Aug 18:20 PDT / 8 Aug 11:20 AEST / 8 Aug 10:20 JST
 
Agenda:
 
1. Renaming Anim/AnimInstance
2. What time do you pass to seek()?
3. Liveness
4. Template classes
5. Removing the Timing interface
6. Tidying up the Timing/TimedItem interface
7. Pause behaviour
8. Suggestions from public-fx, www-style
9. TODO
 
0. Status update
 
Dmitry checked in Enum support to respec.js. Works great.
Brian working on start(), stop(), reverse(), changeSpeed(), pausing etc.
Other updates?
 
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
 
I prefer AnimTemplate
 
> 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?
 
Don't read on until you've answered the question! I want to find out what is intuitive.
 
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.
 
I had picked (a), sorry :(
I think it’s confusing either way. a and b both sounds right, depending on the point of view.
 
Hmm, ok. What if you repeat the experiment, assuming that the animation was not triggered until after 30s (i.e. has a start time of 30s)?
Doesn’t change anything. The question is how you look at delay: as a part of animation or not. Both points of view are acceptable.
 
Yeah, I was more thinking about Shane's answer. I wonder if he would still pick (a) if the animation started later.
 
If I have:
 
<seq>
  <animate delay='3s' length='5s'/>
  <animate length='4s'/> // when does this start?
</seq>
 
> 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.
 
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.
 
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.
 
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.
 
(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.)
 
Other proposals?
 
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.
 
> 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 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 was thinking about collapsing Timing into TimedItem/TimedTemplate.
 
This would give you:
 
interface TimedItem {
    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;
 
    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 {
 
    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;
 
    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?
 
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.
 
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()
 
>>>> ONLY GOT THIS FAR, WILL CONTINUE WITH THE REMAINDER NEXT MEETING <<<<<
 
6. Tidying up the Timing/TimedItem interface
 
Whether we merge these interface or not, it seems like some renaming is in order
 
We have:
 
interface Timing {
    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;
    Timing clone ();
};
 
and:
 
interface TimedItem {
    readonly attribute Timing             timing;
    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 ();
};
 
Note that one of the key concepts is:
 
* iteration time and iteration duration -- the time within/for one iteration
* animation time and animation duration -- the time within/for the whole interval including (potentially) many iterations
 
Do you find this naming confusing?
 
Nope.
 
Some suggestions:
 
animationTime -> currentTime
animationDuration -> repeatedDuration
iterationDuration -> duration (matches CSS and SVG, but could be confusing?)
 
What do you think?
 
I think these are worse. repeatedDuration (as compared to duration) doesn't convey the sense of "overall" or "the sum of the intervals" in the same way as animationDuration (as compared to iterationDuration) does.
 
Also, how about the following:
 
iterationStart -> iterStart
iterationCount -> iterCount (repeatCount?)
iterationTime -> iterTime
currentIteration -> currentIter
duration -> dur
repeatedDuration -> repeatDur
timingFunction -> timingFunc
 
NOOOO! "iter" can validly be "iterator", whereas "iteration" is unambiguous.
 
"dur" and "timingFunc" are OK.
 
Any thoughts?
 
7. Pause behaviour
 
If you pause an animation 25% of the way through, then extend the startDelay, do you expect the paused animation to jump to, e.g. 10% of the way through? Or stay fixed at 25%?
 
8. Suggestions from public-fx, www-style
 
* François REMY in particular has been very helpful in discussing integration with media.
Some suggestions:
  - Liveness (point 3 above) proposal A
  - Factor out a common TimeSource interface that MediaElements could implement as well as TimedItem. I haven't really looked into it too much.
     - Renaming some of our properties to line up with MediaElements would help here (e.g. speed -> playbackRate)
     - Also possibly reworking timelineStart to follow the autoplay mechanism
  - Rather than making the effects timeline not seekable, make it a property of all groups that they can be seekable / not-seekable.
  - I would prefer if the “animate” and “animateLive” functions were called “createInstance(s)” and “createLinkedInstance(s)”
  - Rename “animate*WithParent(el,group)” in to “create*Instance(s)InGroup(el,group)”
   - There are some comments about sorting within the global animation stack that I suggested Shane could follow up on
 
* Julien Dorra has proposed a :time pseudo class originally for lining things up with media items but is probably more generally applicable
 
e.g.
div.welcome:time(3000) {
   display: none;
 
(Probably want to use seconds instead of milliseconds however)
 
I suggest the time could be interpreted based on the time space of the target element. e.g. if the div was a child of a <par> group the 3000 would be taken as being in the time space of the <par> group.
 
That would be one avenue for putting CSS animations inside time containers?
 
e.g.
 
<par>
   <div class="welcome">
</par>
 
div.welcome:time(3) {
    animation: ...
}
 
?
 
Not sure how that works for <seq> containers however where the start time is ignored.
 
If you define <video> etc. as establishing their own time space (i.e. make them "animation groups", so to speak) then you can sync with video.
 
You can also do this:
 
<video id="video"> 
  <animate begin="3s" dur="2s" attributeName="filter" ...></animate> 
</video>
 
* There was also a suggestions somewhere about making the result of animate(document.querySelectorAll(".zombie")) live--i.e. as new elements get added with that class, spawning animations to them.
 
9. TODO
 
Some of the larger pieces still left before September
 
* Incorporate changes from today's meeting (Brian)
   -- renaming, removing liveness? removing item time?
* Write up effects vs animation timelines (Brian)
* Write up global Animate / Animate.effect functions (Brian)
* Add duration: time | auto | % (Brian)
* Pseudo element superclass (Brian)
* Add TimedItem.resetDrift(optional deep = false) (Brian)
* Add description of timing model (Brian)
* Lots of other renaming etc. (Brian)
* TimingFunction interface
* Constructors, especially for groups (Brian)
* AnimFunction.pace -- drop this for now?
* Script-based AnimFunctions
* Various TODOs under 10. Primitive animation operations
* MediaGroup intergration
* Events
* SVGOpen presentation / demo
 
Clearly you need to hand off some drafting to other people. Anything I can take off your hands?