- From: Brian Birtles <bbirtles@mozilla.com>
- Date: Wed, 29 Aug 2012 12:16:50 +0900
- To: "public-fx@w3.org" <public-fx@w3.org>
Web Animations minutes, 28 / 29 August 2012
Etherpad: https://etherpad.mozilla.org/ep/pad/view/ro.7clGoF1me6H/latest
Present: Tab Atkins, Dmitry Baranovskiy, Shane Stephens, Brian Birtles
Agenda:
1. Status update
2. Constructors
3. Multiple intervals, reversing etc.
4. Sequence containers and media controllers
5. Pausing outside the animation interval
6. Other issues
1. STATUS UPDATE
================
Brian: fixed some timing stuff, added timing functions, worked on respec
(Constructors, NamedConstructors, default parameter values, union types)
Shane: Coded emulator Like A Baws. (http://github.com/shans/web-anim-js)
2. CONSTRUCTORS
===============
Issue from two meetings ago: https://etherpad.mozilla.org/IW8zT9yCin, item 7
Proposal:
new Anim(Element? elem, (AnimFunc or object) animFunc, (double or Timing
or TimingDict) timing, AnimGroup? parentGroup, optional double startTime)
new AnimGroup((double or Timing or TimingDict) timing, AnimGroup?
parentGroup, optional double startTime);
Changes:
- Split animation from timing
- Put animation first
- Allow specifying duration just by using a double
- Animation: either a AnimFunc object or a property bag of the form {
attr/prop: value, ... }
- Timing: either (a) a double or (b) a dictionary (TimingDict) where you
can specify several properties or (c) a shared Timing object
Regarding the anim parameter values, we want to be able to support the
following:
{ left: '100px' } ➙ KeyframesAnimFunc
{ left: '100px', top: '200px' } ➙ GroupedAnimFunc
And probably also this:
{left: ['0px', '25px', '100px']} ➙ KeyframesAnimFunc
We (might) like to support similar notation in the ctors for the
specific AnimFunc objects, e.g.
anim.animFunc = new KeyframesAnimFunc('left', ['0px' ... ]);
One possibility is to add a utility function to do this kind of mapping
that gets implicitly called from the Anim ctor when needed, e.g.:
anim.animFunc = AnimFunc.fromProperties(...);
> Proposal generally acceptable. Brian to work on speccing.
3. MULTIPLE INTERVALS, REVERSING ETC.
=====================================
Issue from last time: https://etherpad.mozilla.org/IFCnsPoRSr, item 4
Shane would like to try and implement the approach where we have
animations that don't add to other instances of the same template and
see how it feels. We’ll reconsider based on that feedback if this is a
suitable approach.
Discussion on reversing: currently reversing requires breaking the link
with the template because you need to change the playback rate and fill
mode. This shouldn't be—i.e. it should be possible to reverse something
without breaking the link to the template. Either add override playback
rate and override fill mode to the Anim instance or some special
reversing flag.
4. SEQUENCE CONTAINERS AND MEDIA CONTROLLERS
============================================
Pausing inside a sequence container is a bit weird. Currently I've
defined endTime so that, for example, if the item is paused, the endTime
is infinite. This gives you the behaviour where if you pause one child
the next one won't start until it is unpaused (since the next child's
start time is based on the previous child's endTime).
I'm pretty sure that's what you want since once you add media elements
to the equation if you pause or seek a video, you expect subsequent
children in the group to react to its new end time.
(For example, pause the video for 2 seconds and the endTime gets 2
seconds later. Skip forward 3 seconds in the video and the endTime
becomes 3 seconds earlier.)
But it's weird for a few reasons:
1) If you play a sequence container that contains a paused descendent in
reverse all you'll see is that first frame of the paused animation. You
won't get the behaviour where it plays the children in reverse sequence
and then pauses at the last frame of the paused child.
2) Suppose, while child B is playing, you pause it for 2 seconds then
resume. If you then seek back to the start of the container you'll get A
playing, then 2 seconds of nothing, then B playing. (Effectively, by
pausing the child, you've shifted its time by 2 seconds)
3) It's a little odd that endTime reacts to pausing/seeking but
startTime does not. Also endTime can come before startTime (due to
negative delays or seeking forwards).
I think there are a few possibilities here:
A) Add a facility to reset the timeDrift
Basically TimedItem.reset(). It does a seek to time 0 and clears the
timeDrift and locallyPaused state of all descendants.
This fixes (2) and is something you often want to do.
B) Auto-reset time drift
Basically A, but if you do a seek to a time before the beginning of the
animation interval you clear the timeDrift automatically.
This kind of matches my intuition of what should happen but it breaks
the idea that the model is stateless. That's a problem because
implementations have to be very careful to detect all circumstances when
the effective time is before the start of an animation interval with
non-zero timeDrift. It sounds like a real source of interop problems, or
worse, problems that only crop up in some implementations when the frame
rate is low (if they just check at sample time).
So I think the explicit call is better.
C) Slave sequence groups' pause state and seek time to their children
(or actually descendents)
There seem to be a lot of parallels between the way sequence groups and
media controllers work. You could just defer all pause requests to the
container. That doesn't let you run child A while child B is paused
however. Pausing child B would pause the group meaning child A won't run.
Seeking however, could work fairly intuitively. You'd convert the times
to group time and then apply the seek to the group. The
counter-intuitive bit is when A is playing and you seek B... you'd skip
A and start B. You also lose flexibility... you can't shift just one
child back / forward.
For this to work however, i.e. to solve (2), I think this has to apply
to all descendents. In effect, any animation with an ascendent sequence
group is slaved.
D) No seeking a descendent of a sequence group, pausing is slaved to the
group
That's how HTML5 media controllers work. You can't set currentTime if
you have a media controller. Pausing is slaved. With play(), if you have
a media controller you skip the seeking step.
For issue (1) above (the fact that you can't really play a sequence
group in reverse if it has a paused child) I think you just have to say,
"that's how the model works". To do otherwise would break down the
ability to randomly sample the model.
For issue (3) above (the fact that endTime reacts to pauses/seeks but
startTime doesn't, and also the fact that endTime can come before
startTime), we could possible rename endTime to animEnd.
Discussed the issue but also with reference to par groups that repeat:
• One proposal was to have a type of par group that cannot be iterated,
a “loose” group. For all other types of groups, pausing a descendant
pauses the group (i.e. pausing anywhere pauses everywhere).
- questions about whether exposing this kind of group is actually
useful or just confusing. An alternative would be to make the document
timeline such a “loose” group (in effect) but not allow creating such
groups elsewhere (i.e. just make it special behaviour defined on the
timeline).
- concern that if a group gets added at any point (e.g. a <svg> is
mapped to a par group) then suddenly you can’t independently pause
children — this may be reason to have loose groups other than just the
document timeline
- question: why would you do that? groups are for synchronising.
Don't use them unless you want synchronisation.
• Another proposal was to ignore child pause state when scheduling par
and seq groups. This results in some “weird” behaviour — e.g. sequences
getting out of order because pausing one item doesn’t result in the next
item failing to play. Of course you can always pause the sequence…
- also concern about whether this is fundamentally different to the
cascading nature of time in the model defined so far (but conversely,
why should pausing a child modify an explicitly set iterationDuration on
a parent?)
> This requires more thought but the "loose" group idea seems to hold
some promise. Not sure yet if they should be generally available or just
specified on the top-level (timeline) group.
5. PAUSING OUTSIDE THE ANIMATION INTERVAL
=========================================
A while ago we had a discussion about what happens if you pause a child
outside its animation interval. The expected behaviour in that case is
that it has no effect until the animation starts.
For example, I have
anim {
startTime: 5;
startDelay: 5;
}
At t=3s, I pause anim.
The expected behaviour we thought was that time continues to tick and
then at t=10s, the animation starts paused (i.e. the first frame appears
and doesn't move).
Presumably the same would happen in reverse.
Currently we don't do that. Pausing at t=3s, pauses at t=3s. If you
unpause it, you still have to wait 7s before the things starts.
Supporting the behaviour where times outside the animation interval
don't contribute to the pause is possible. I even wrote out the algorithm:
Inside the calculation for timeDrift:
If locallyPaused is false
... as before ...
If locallyPaused is true
Let anim start = startTime + timing.startDelay
If pause start < anim start
If effective parent time < anim start
return 0
Otherwise
return max(0, effective parent time - anim start)
Otherwise
Let anim end = anim start + animDuration + stored value of timeDrift
If pause start >= anim end
If effective parent time > anim end
return stored value of timeDrift
Otherwise,
return max(0, anim end - effective parent time)
Otherwise,
return effective parent time - startTime - pause start
Anyway, that's just there for posterity, but it introduces complexity
because if you're paused at t=3s in the previous example, and do a seek
to t=0s what do you expect?
If we want to make that take effect I think internally we'll need to
separate out pauseDrift and seekDrift (which basically equates to the
"stored value of timeDrift" above).
I just want to check if this is really the behaviour we want.
> After some discussion, we agree that if you pause during the delay
phase it should take effect. In essence, pause takes effect at the
earlier of two moments, the start time or the animation interval start.
This is needed both for CSS compatibility and because in our model the
delay is part of the animation.
6. ISSUES FOR NEXT TIME
=======================
* How to seek when currentTime is null
-- Brian and Shane discussed this --- basically divorce currentTime
from item time. We said currentTime always exists and can be set, but is
sometimes not live; if it's live then currentTime == itemTime. In a
sense, currentTime is the item time calculated using the "effective
parent time" as defined in the spec.
* Specified start times should not update when moving animations between
containers, but automatically calculated start times should. (However,
if the start time was specified with the intention of being a relative
amount from the parent's iteration time then it *should* update). We
(Shane and Brian) also discussed adding startTime as a parameter to add,
and always updating startTime.
* Sensible behaviour for changePlaybackRate(0)
-- If you call changePlaybackRate(0) mid-way through an animation
you expect it to pause. Currently it does not because a playback rate of
zero means an infinite duration which means you never get past the
starting point. You can work around this by adjusting the
iterationStart, or by just special-casing 0 to make it actually pause,
or you can just say "that's the model". What do you prefer?
* Integrating with video and audio... is this really going to work?
-- video and audio need a concept of direction but our timing
functions etc. mean all bets are off regarding the direction of the next
sample. And its not just enough to disallow certain timing features on
the video since these things can happen all the way up the tree. Maybe
we need some process where we approximate the effect... e.g. walk up the
tree, ignore timing functions, work out the direction, playbackRate etc.
and then apply those properties to the video itself (behind the scenes?)
Next meeting: 4 Sep 18:20 PDT / 5 Sep 11:20 AEST / 5 Sep 10:20 JST @
https://etherpad.mozilla.org/uDxc2Hwa8n
Past meetings: http://www.w3.org/Graphics/fx/wiki/Web_Animations/Meetings
Received on Wednesday, 29 August 2012 03:17:22 UTC