Server Notice:


Public Pad Latest text of pad EVy6CdvEjT Saved Feb 12, 2013

Meeting 44:
Web animations minutes, 12 February 2013
1. Play control re-revisited
2. Timing (sharing, templating, separate object, etc.)
3. Effect Templating
Two categories of issues remain:
the four clock issues
getCurrentAnimations what does it return?
As for :
1. What should we call the clock?
Brian & Dmitry like Clocks, but:
  - Shane doesnt like clock.reverse()
  - Steve doesnt like the confusion between Clock and TimeSource
  - Doug notes that the timing of Clock isnt provided by the Clock.
Shane's preferred option:
IDL interface is called PlayController. Referenced from a TimedItem via timedItem.controller.
  - Dmitry thinks this is too much typing
  - Brian thinks controller is too generic
Dmitry wants Manager
  - Brian thinks that Manager is a sign youve gone the wrong way somewhere in your API.
Other considerations
type: Player, timedItem.player.
Matches DVD Player quite well.
Seems to be a reasonable level of acceptance of this, but maybe not just Player.
We need a name for the tree thing which is played by the Player.
Suggestions so far: Bundle, Set, Timeline, Timegraph, Assembly, Storyboard, Script, Story, Composition, Agglomerate, Bunch, Conglomerate, Commune, Coop, Cartel, Family, Scene, Stage
Well use Scene as a placeholder for now. That gives us ScenePlayer as the interface name for the item formerly known as Clock/PlayController.
2. How should we get ?
options are getScenePlayer / getPlayer, or attach / start / insert. Semantically, attach creates the ScenePlayer whereas with the getPlayer approach the ScenePlayer is created when the TimedItem is.
Advantages of creating-up-front
player is never undefined
Its clear what happens when getPlayer is called on a child (you get the root player)
Advantages of creating-on-demand
dont need an extra start-time state. In-play === ScenePlayer exists.
separates building up of the scene from playback control
Avoids need for proxy players (although could avoid this in other ways)
Proxy pattern may be confusing.
What do most authors expect in the following situation:
  var player = anim.getPlayer(); 
Suggestion that it may be more intuitive to have getPlayer() just return the actual ScenePlayer and not a proxy.
Approach 1:
var anim = document.createAnimation(...);
anim.getPlayer(); // Returns a ScenePlayer(Proxy)
anim.getPlayer().currentTime; // null
anim.getPlayer().startTime; // null, read-only
anim.getPlayer().start(); // Sets startTime to the current time of the time source (clears time drift)
anim.getPlayer().startAt(4); // Sets startTime to 4 (and clears time drift)
anim.getPlayer().startTime == 4
anim.getPlayer().stop(); // Clears the startTime (sets to null)
  timeDrift; // Might drop this
Approach 2:
var anim = document.createAnimation(...);
anim.getPlayer(); // Returns null
anim.attach(4); // Returns ScenePlayer?
anim.getPlayer().currentTime; // 0
anim.getPlayer().startTime; // 4
How do you seek before attaching?
could at least do anim.attach().pause().currentTime = 4;
or say, too bad
Compromise proposal: Approach 2 s/attach/start/g
var anim = document.createAnimation(...);
anim.getPlayer(); // is null
anim.start(); // returns a ScenePlayer, starts the animation NOW
var p = anim.getPlayer();
anim.stop(); // deletes the ScenePlayer. Animation ceases to have any effect
p.pause(); // What does this do? throw AreYouStupidException
Starting at t=4s:
anim.start().startTime = 4;
alternatively: anim.startAt(4);
Starting in 2s:
anim.start().startTime += 2 // This ++
anim.startAt(document.timeline.currentTime + 2); </struckthrough>
anim.start().startTime = document.timeline.currentTime + 2
We could leave out startAt for now, and add it later
Start on a child:
starts just that child, removes from parent, parent relayout
throws an exception
clones and starts child
Probably the first option here is more obvious, i.e. reparenting
Stop on a child:
stops just that child, removes from parent, parent relayout
throws an exception
clones and starts child
Again, probably the first optionreparenting
Is getPlayer() a proxy or real player:
var player = anim.getPlayer();
... (eg. stop())
player... // can throw null pointer exception - it's not always a proxy
Probably should return the real player since it can sometimes be null. If it were a proxy, it should never be null.
Lonely player (player with no TimedItem):
var p = anim.start();
p.pause(); // Does what?
p.currentTime; // Returns what?
Plays as normal but without observable effects
Calling start twice:
var p1 = anim.start();
var p2 = anim.start();
do nothing: p1 === p2
restart: p1 !== p2
Restarting is more consistent with the behaviour when calling child.start();
Start seeked by 4 seconds
anim.start().startTime -=4
[ In this case currentTime will be 4 and timeDrift will be 0 ]
anim.start().currentTime = 4
[ In this case startTime will not change, but timeDrift will be 4 ]
new ParGroup([anim], { startDelay: -4 }).start();
[ In this case the first 4 seconds of the scene will be clipped ]
(All of these work. Hooray!)
Approach 3:
Both startTime and currentTime are writable. currentTime is automagically updated in response to startTime, but not the other way around.
var a = document.createScenePlayer()
a.startTime == ?;; // foo will be stopped.
a.unpause() / resume()
var a = document.createScenePlayer(foo);
a.timedItem = null; // Should be mutable if exposed, but no need to expose
a.cancel() THIS ONE
Starting now:
var a = document.createScenePlayer();
// a.startTime = null
// a.currentTime = null;
// a.startTime = document.timeline.currentTime
// a.currentTime = 0
if play returns the player:
var a = document.createScenePlayer().play(foo);
Starting at t=4s:
var a = document.createScenePlayer();;
a.startTime = 4;
Starting in 2s:
var a = document.createScenePlayer();;
a.startTime += 2;
Play on a child:
plays just that child, removes from parent, parent relayout
Is getPlayer() a proxy or real player:
as in approach 2, getPlayer can return null, proxy won't work
A lonely player:
// a.startTime = null
// a.currentTime = null
// <previously-played-scene>.getPlayer() = null
currentTime and startTime are null. Can always reuse by calling play(..) again.
Calling play on a player twice:
ie [Note that we might not expose timeditem]
with the same timed item - restarts the scene (startTime = now, currentTime = 0)
equivalant player.startTime = now();  // player.currentTime is updated in response
Start seeked by 4 seconds:
document.createScenePlayer().play(new ParGroup([anim], { startDelay: -4 }))
document.createScenePlayer().play(foo).currentTime = 4
document.createScenePlayer().play(foo).startTime -= 4
Calling play with a toplevel item that is already playing
plays the item, makes old player lonely (this is called the nostalgia operation)
Unpausing:; // whoops!
player.cancel(); (startTime = null, currentTime = null, timedItem.getPlayer() = null)
Initial comparison between approach 2 and approach 3 for simply creating an animation and starting it:
Approach 2:
var anim = document.createAnimation(...);
Approach 3:
var anim = new Animation(...);
var player = document.createScenePlayer();;
Main weakness with approach 2 is the behaviour of start() on children
Main weakness with approach 3 is the verbosity?
Suggestions to make 3 nicer:
Allow createPlayer() to take anim as an arg and automatically play it? Or just chain the function calls?
That gives:
var anim = new Animation(...);
var player = document.createPlayer().play(anim);
var player = document.createPlayer(anim);  // ctor with side-effects?
What about:
  var player =;
As a short cut for document.createPlayer().play(anim) ?
  var player =;
For tomorrow:
What do we do with document.getCurrentAnimations()?
Next meeting: Tues 13 Feb 9:00 AEDST @ Google Sydney