After animations section is done I'll merge back to trunk.
Doug: Met with users/designers. Built some demos, will share if I can. Some polyfill work.
Steve: Updating polyfill to match decisions from face-to-face
2. DICTIONARY AS A LIVE OBJECT
While doing the refactoring that has dictionary as a member of TimedItem I noticed that WebIDL has some restrictions in this area:
Dictionaries are always passed by value. In language bindings where a dictionary is represented by an object of some kind, passing a dictionary to a platform object will not result in a reference to the dictionary being kept by that object. Similarly, any dictionary returned from a platform object will be a copy and modifications made to it will not be visible to the platform object.
I might be reading it wrong, but it sounds like they're not live.
Shane: I guess we should talk to Cameron about whether we can still do specified with a dictionary object and specify additional semantics? Or alternatively we'd need to provide another interface that matches TimedItem but isn't a Dictionary.
Doug: I had assumed we were just providing an interface that behavied much like the regular dictionary.
Brian: Yeah, I'd like to avoid that. As I recall, one of the reasons why this approach was acceptable to some (I'm thinking of Mike in particular and myself too) was that we already have the TimingDictionary defined. Maybe it's ok but it makes me uncomfortable to add in an extra interface nearly identical to TimingDictionary just for that. If we're doing that, it might be worthwhile considering if we should split off the computed timing into a separate interface instead. Oh no, it's that whole can of worms again... :(
Unfortunately Cameron's on a big trip at the moment. I'll ping Boris Zbarsky and ask.
> Skip for this week and revisit when everyone is present and we've had more time to think about it
3. PAUSE BEHAVIOUR
Brian: We currently have defined the behaviour for pausing such that pausing before the start time (or actually, before the start of the animation in the case where it has a negative delay) does not delay the start of the animation but just causes it to start paused.
I think this was to line up with what is defined/proposed for CSS.
Now that play control happens on an entirely different object, I wonder if this really makes sense.
It seems awkward to introduce coupling between the Player and TimedItem for this purpose.
I think it may also be counter-intuitive.
I'd like to get rid of it. What do you think?
Steve: I'm happy to get rid of it and let pause mean pause.
Steve: Somewhat related to this, I think we should revisit the behaviour when assigining to Player.startTime. The spec states that the drift should be reset to zero, but I think this could be unintuitive, especially as drift isn't exposed through the API. If instead we leave the drift untouched, then ...
player.startTime += delta;
will cause the animation to always jump backwards by delta, which I think is what you'd expect. If you really want to reset the drift to zero, you can just do ...
Shane: I think a simple model relating the three is better than trying to meet author expectations, so I support both of these :)
Brian: Sounds ok. I was a bit unsure what to do about startTime. I think NOT resetting it though can be counter-intuitive when using absolute values?
Steve: The thing that swings it for me is that we don't expose the time drift so if you want to make changes that preserve the drift, you can't if setting startTime resets the drift. With the alternative arrangement where setting startTime doesn't reset the drift, if you DO want to reset the drift you can do it like so:
Brian: Ok, I'll make startTime not reset the drift for now.
Steve: Happy to change back if users complain!
Discussed some alternatives here:
One would be to have:
- startTime - updated when you change currentTime
- triggeredTime - the original time when the thing was played for the purposes of animation sandwich ordering (may or may not be exposed)
- currentTime - as now
i.e. no time drift. Seeking/pausing implemented in terms of adjusting startTime
Clear relationship between currentTime and startTime (no magic hidden drift) but is it weird that setting currentTime sets startTime?
Another is to make currentTime read-only and you seek by setting startTime.
Or make startTime read-only and assigning to currentTime updates startTime.
These last two are simpler, as you only have one writable param, so you avoid the trickiness above.
> Needs more thought. We'll stick with what we have for now (including making startTime NOT reset the drift) and if we get lots of confusion regarding the drift, we'll revisit then.
3. PLAYBACK RATE
We decided to put playbackRate on the Player--or at least the version that does the compensatory seek so that doing, e.g.
player.playbackRate = 2;
This leads to two questions:
1) Do we still need TimedItem.playbackRate?
It might still be useful to, e.g. speed up part of a tree
But is it useful enough to warrant inclusion in v1?
Shane: Yes, I think we need it to match some SVG semantics don't we? Can't you have playbackRate for sub-animations?
We also need to have playbackRate for media elements so I think keeping it throughout the model makes sense.
Doug: I've used it. It's very useful. Much of building animations is tweaking timing. Being able to easily tweak the duration of subtrees is valuable.
2) If we do allow it, what would, e.g.
map to? Player.playbackRate? Or TimedItem.playbackRate?
I think it should map to TimedItem.playbackRate and let Player.playbackRate be for *run-time* control. Not static definition.
Doug: Agree that it should be on TimedItem, otherwise the behaviour would be different if it were in a group.
Likewise, how about:
I think it would be bad to say, "The playbackRate is ignored if the element is not the root timing element". That's just confusing.
Shane: Definitely confusing.
Note that player.playbackRate = -1 doesn't start at the end of the playback content and go backwards like it used to since Players shouldn't care about the length of their content. That also means that calling reverse() on a player whose content has finished and is filling, no longer causes it to immediately run backwards. We could hack in extra wording for that however? It might be acceptable for reverse() to look into its playback content since it's a one time operation.
Shane: Maybe we need two versions of reverse() eventually? I dunno - having reverse keep the current play point static is simpler, but letting reverse seek to the end of the content is more useful.
Brian: TimedItem.playbackRate *does* start at the end (but then so does direction="reverse") but there is no longer any TimedItem.reverse since the reverse behaviour relies on run-time playback control (i.e. maintaining your position).
Brian really wants reverse() to seek because he thinks this is a very common effect (e.g. SVGOpen 2012 demo).
Steve raises the points:
- is it necessary for v1?
- shouldn't calling reverse() twice be a no-op?
- adding this suggests we need a start() or similar that does the opposite
Doug: Is this really playBackwards() instead of reverse() ?
- What happens if the source has an infinite duration?
- reverse reverses from the current position UNLESS the source has finished in which case it jumps to the end. So if it has infinite duration, we just reverse from the current position since it never finishes.
What this doesn't allow you to do is, if you have an infinitely repeating animation and want it to start going backwards and go backwards infinitely, that won't work.
Discussed the fact that players currently act independently of their source content. So it's nice if we don't have to reach into the source content for this.
However, Brian feels that the use case (reversing either from current point or end) is common (e.g. CSS transitions' behaviour, out SVGOpen demo etc.) and we should work out how to address this.
Also discussed whether players should stop when their content does like a video player does.
> We'll sit on this issue for a bit. Doug will ask others what they'd expect.
5. CANCELLING A PLAYER
Brian: Should it reset the time drift? And what about other properties?
Shane: Yes it should definitely reset the time drift. I think startTime should remain as it is and currentTime reset to 0.
Discussed, why do we even need cancel()? All it does it set source to null. It's not needed for events (that's orthogonal). It really just makes the code easier to read.
For the use cases we have in mind for this, you're probably not going to want to re-use the player.
And if you want to re-use the player, presumably that's to re-use some state, so we shouldn't mess with it on cancel(). If you don't want that state, just create a new player.
> We'll drop cancel() for now at least. It's just syntactic sugar. The smaller the better.
Brian: Do we need player.reset()? Or resetDrift()? To reset these things?
6. API for sampling the value of an effect.
Similar to how you can call TimingFunction.scaleTime.
Some concern that if future AnimationEffects require additional inputs we'll have trouble updating that part of the API.
> Defer for now. Will continue to find use cases for this.
7. Is it 'add' or 'accumulate' ?
Need to ask Shane.
Also, how do we handle accumulating animations? i.e. repeating animations that build on themselves?
8. timeline.play instead of timeline.createPlayer
We had proposed having:
as a shortcut for
Does that address the feedback?
- If we had document.timeline.play() then that would be enough
- createPlayer() doesn't make it obvious that it plays something
- Brian: although apparently this is becoming idiomatic
- play() doesn't make it obvious that you get back a player
- Brian: although document.play(item).pause() seems reasonable to me
- document.play() doesn't make the relationship with the document timeline obvious?
> Let's go with document.timeline.play(item) for now.