Skip to content

Commit a4784a3

Browse files
committed
Merge pull request #124 from dstockwell/wrap-players
Wrap players in maxifill
2 parents cc287f9 + 2d58c4f commit a4784a3

10 files changed

+200
-188
lines changed

src/animation-constructor.js

+43-117
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,18 @@
4040
};
4141

4242
var pendingGroups = [];
43-
function addPendingGroup(group) {
43+
scope.awaitStartTime = function(groupPlayer) {
44+
if (!isNaN(groupPlayer.startTime) || !groupPlayer._isGroup)
45+
return;
4446
if (pendingGroups.length == 0) {
4547
requestAnimationFrame(updatePendingGroups);
4648
}
47-
pendingGroups.push(group);
48-
}
49+
pendingGroups.push(groupPlayer);
50+
};
4951
function updatePendingGroups() {
5052
var updated = false;
5153
while (pendingGroups.length) {
52-
pendingGroups.shift()();
54+
pendingGroups.shift()._updateChildren();
5355
updated = true;
5456
}
5557
return updated;
@@ -66,18 +68,44 @@
6668
},
6769
});
6870

71+
// TODO: Call into this less frequently.
72+
scope.Player.prototype._updateChildren = function() {
73+
if (isNaN(this.startTime) || !this.source || !this._isGroup)
74+
return;
75+
var offset = 0;
76+
for (var i = 0; i < this.source.children.length; i++) {
77+
var child = this.source.children[i];
78+
var childPlayer;
79+
80+
if (i >= this._childPlayers.length) {
81+
childPlayer = window.document.timeline.play(child);
82+
child.player = this.source.player;
83+
this._childPlayers.push(childPlayer);
84+
} else {
85+
childPlayer = this._childPlayers[i];
86+
}
87+
88+
if (childPlayer.startTime != this.startTime + offset) {
89+
childPlayer.startTime = this.startTime + offset;
90+
childPlayer._updateChildren();
91+
}
92+
93+
if (this.playbackRate == -1 && this.currentTime < offset && childPlayer.currentTime !== -1) {
94+
childPlayer.currentTime = -1;
95+
}
96+
97+
if (this.source instanceof window.AnimationSequence)
98+
offset += child.activeDuration;
99+
}
100+
};
101+
69102
window.document.timeline.play = function(source) {
103+
// TODO: Handle effect callback.
70104
if (source instanceof window.Animation) {
105+
// TODO: Handle null target.
71106
var player = source.target.animate(source._effect, source.timing);
72-
// TODO: make source setter call cancel.
73107
player.source = source;
74108
source.player = player;
75-
source._nativePlayer = player;
76-
var cancel = player.cancel;
77-
player.cancel = function() {
78-
player.source = null;
79-
cancel.call(this);
80-
};
81109
return player;
82110
}
83111
// FIXME: Move this code out of this module
@@ -89,122 +117,20 @@
89117
player._removePlayers();
90118
return;
91119
}
92-
if (isNaN(player._startTime))
120+
if (isNaN(player.startTime))
93121
return;
94122

95-
updateChildPlayers(player);
123+
player._updateChildren();
96124
};
97125

98-
function updateChildPlayers(updatingPlayer) {
99-
var offset = 0;
100-
101-
// TODO: Call into this less frequently.
102-
103-
for (var i = 0; i < updatingPlayer.source.children.length; i++) {
104-
var child = updatingPlayer.source.children[i];
105-
106-
if (i >= updatingPlayer._childPlayers.length) {
107-
var newPlayer = window.document.timeline.play(child);
108-
newPlayer.startTime = updatingPlayer.startTime + offset;
109-
child.player = updatingPlayer.source.player;
110-
updatingPlayer._childPlayers.push(newPlayer);
111-
if (!(child instanceof window.Animation))
112-
updateChildPlayers(newPlayer);
113-
}
114-
115-
var childPlayer = updatingPlayer._childPlayers[i];
116-
if (updatingPlayer.playbackRate == -1 && updatingPlayer.currentTime < offset && childPlayer.currentTime !== -1) {
117-
childPlayer.currentTime = -1;
118-
}
119-
120-
if (updatingPlayer.source instanceof window.AnimationSequence)
121-
offset += child.activeDuration;
122-
}
123-
};
124-
125-
addPendingGroup(function() {
126-
if (player.source)
127-
updateChildPlayers(player);
128-
});
129126

130127
// TODO: Use a single static element rather than one per group.
131128
var player = document.createElement('div').animate(ticker, source.timing);
132-
player._childPlayers = [];
133129
player.source = source;
134-
source._nativePlayer = player;
130+
player._isGroup = true;
135131
source.player = player;
136-
137-
player._removePlayers = function() {
138-
while (this._childPlayers.length)
139-
this._childPlayers.pop().cancel();
140-
};
141-
132+
scope.awaitStartTime(player);
142133
return player;
143134
}
144135
};
145-
146-
function isGroupPlayer(player) {
147-
return !!player._childPlayers;
148-
}
149-
150-
var playerProto = Object.getPrototypeOf(document.documentElement.animate([]));
151-
scope.hookMethod(playerProto, 'reverse', function() {
152-
if (isGroupPlayer(this)) {
153-
var offset = 0;
154-
this._childPlayers.forEach(function(child) {
155-
child.reverse();
156-
child.startTime = this.startTime + offset * this.playbackRate;
157-
child.currentTime = this.currentTime + offset * this.playbackRate;
158-
if (this.source instanceof window.AnimationSequence)
159-
offset += child.source.activeDuration;
160-
}.bind(this));
161-
}
162-
});
163-
164-
scope.hookMethod(playerProto, 'pause', function() {
165-
if (isGroupPlayer(this)) {
166-
this._childPlayers.forEach(function(child) {
167-
child.pause();
168-
});
169-
}
170-
});
171-
172-
scope.hookMethod(playerProto, 'play', function() {
173-
if (isGroupPlayer(this)) {
174-
this._childPlayers.forEach(function(child) {
175-
var time = child.currentTime;
176-
child.play();
177-
child.currentTime = time;
178-
});
179-
}
180-
});
181-
182-
scope.hookMethod(playerProto, 'cancel', function() {
183-
if (isGroupPlayer(this)) {
184-
this.source = null;
185-
this._removePlayers();
186-
}
187-
});
188-
189-
scope.hookSetter(playerProto, 'currentTime', function(v) {
190-
if (isGroupPlayer(this)) {
191-
var offset = 0;
192-
this._childPlayers.forEach(function(child) {
193-
child.currentTime = v - offset;
194-
if (this.source instanceof window.AnimationSequence)
195-
offset += child.source.activeDuration;
196-
}.bind(this));
197-
}
198-
});
199-
200-
scope.hookSetter(playerProto, 'startTime', function(v) {
201-
if (isGroupPlayer(this)) {
202-
var offset = 0;
203-
this._childPlayers.forEach(function(child) {
204-
child.startTime = v + offset;
205-
if (this.source instanceof window.AnimationSequence)
206-
offset += child.source.activeDuration;
207-
}.bind(this));
208-
}
209-
});
210136
}(webAnimationsShared, webAnimationsMaxifill, webAnimationsTesting));

src/effect-callback.js

+3-14
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818

1919
Element.prototype.animate = function(effect, timing) {
2020
if (typeof effect == 'function') {
21-
var player = originalAnimate.call(element, [], timing);
21+
var player = new scope.Player(originalAnimate.call(element, [], timing));
2222
bind(player, this, effect, timing);
2323
return player;
2424
}
25-
return originalAnimate.call(this, effect, timing);
25+
return new scope.Player(originalAnimate.call(this, effect, timing));
2626
};
2727

2828
var sequenceNumber = 0;
@@ -88,20 +88,9 @@
8888
}
8989
}
9090

91-
var playerProto = Object.getPrototypeOf(document.documentElement.animate([]));
92-
function registerHook() {
91+
scope.Player.prototype._register = function() {
9392
if (this._callback)
9493
register(this._callback);
9594
};
96-
scope.hookMethod(playerProto, 'play', registerHook);
97-
scope.hookMethod(playerProto, 'reverse', registerHook);
98-
scope.hookMethod(playerProto, 'cancel', function() {
99-
if (this._callback) {
100-
register(this._callback);
101-
this._callback._player = null;
102-
}
103-
});
104-
scope.hookSetter(playerProto, 'currentTime', registerHook);
105-
scope.hookSetter(playerProto, 'startTime', registerHook);
10695

10796
})(webAnimationsShared, webAnimationsMaxifill, webAnimationsTesting);

src/hooks.js

-36
This file was deleted.

0 commit comments

Comments
 (0)