Skip to content

Commit c35281a

Browse files
committed
Merge pull request #246 from dstockwell/pass-anim
Wrap custom effect with animation in source
2 parents 52eeb92 + 7d5f3e2 commit c35281a

File tree

6 files changed

+117
-65
lines changed

6 files changed

+117
-65
lines changed

src/animation-constructor.js

Lines changed: 24 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
getFrames: function() { return this._frames; }
2727
};
2828

29-
window.Animation = function(target, effect, timingInput) {
29+
scope.Animation = function(target, effect, timingInput) {
3030
this.target = target;
3131
// TODO: Make modifications to specified update the underlying player
3232
this._timing = shared.normalizeTimingInput(timingInput);
@@ -43,6 +43,27 @@
4343
return this;
4444
};
4545

46+
var originalElementAnimate = Element.prototype.animate;
47+
Element.prototype.animate = function(effect, timing) {
48+
return scope.timeline.play(new scope.Animation(this, effect, timing));
49+
};
50+
51+
var nullTarget = document.createElement('div');
52+
scope.newUnderlyingPlayerForAnimation = function(animation) {
53+
var target = animation.target || nullTarget;
54+
var effect = animation._effect;
55+
if (typeof effect == 'function') {
56+
effect = [];
57+
}
58+
return originalElementAnimate.apply(target, [effect, animation.timing]);
59+
};
60+
61+
scope.bindPlayerForAnimation = function(player) {
62+
if (player.source && typeof player.source.effect == 'function') {
63+
scope.bindPlayerForCustomEffect(player);
64+
}
65+
};
66+
4667
var pendingGroups = [];
4768
scope.awaitStartTime = function(groupPlayer) {
4869
if (groupPlayer.startTime !== null || !groupPlayer._isGroup)
@@ -103,44 +124,10 @@
103124
}
104125
};
105126

106-
var nullTarget = document.createElement('div');
107-
108-
window.document.timeline.play = function(source) {
109-
// TODO: Handle effect callback.
110-
if (source instanceof window.Animation) {
111-
var target = source.target ? source.target : nullTarget;
112-
var player = target.animate(source._effect, source.timing);
113-
player.source = source;
114-
source.player = player;
115-
return player;
116-
}
117-
// FIXME: Move this code out of this module
118-
if (source instanceof window.AnimationSequence || source instanceof window.AnimationGroup) {
119-
var ticker = function(tf) {
120-
if (!player.source)
121-
return;
122-
if (tf == null) {
123-
player._removePlayers();
124-
return;
125-
}
126-
if (player.startTime === null)
127-
return;
128-
129-
player._updateChildren();
130-
};
131-
132-
var player = nullTarget.animate(ticker, source._timing);
133-
player.source = source;
134-
player._isGroup = true;
135-
source.player = player;
136-
scope.awaitStartTime(player);
137-
return player;
138-
}
139-
};
140-
127+
window.Animation = scope.Animation;
141128
window.Element.prototype.getAnimationPlayers = function() {
142129
return document.timeline.getAnimationPlayers().filter(function(player) {
143-
return player._player.source !== null && player._player.source.target == this;
130+
return player.source !== null && player.source.target == this;
144131
}.bind(this));
145132
};
146133

src/effect-callback.js

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,13 @@
1313
// limitations under the License.
1414
(function(shared, scope, testing) {
1515

16-
var element = document.createElement('div');
17-
var originalAnimate = Element.prototype.animate;
18-
19-
Element.prototype.animate = function(effect, timing) {
20-
var player;
21-
if (typeof effect == 'function') {
22-
player = new scope.Player(originalAnimate.apply(element, [[], timing]));
23-
bind(player, this, effect, timing);
24-
} else {
25-
player = new scope.Player(originalAnimate.apply(this, [effect, timing]));
26-
}
27-
// FIXME: See if we can just use the maxifill player source and remove this all together.
28-
player._player.source = {target: this};
29-
window.document.timeline._addPlayer(player);
30-
return player;
31-
};
16+
var nullTarget = document.createElement('div');
3217

3318
var sequenceNumber = 0;
34-
function bind(player, target, effect, timing) {
35-
var animation = 'fixme';
19+
scope.bindPlayerForCustomEffect = function(player) {
20+
var target = player.source.target;
21+
var effect = player.source.effect;
22+
var timing = player.source.timing;
3623
var last = undefined;
3724
timing = shared.normalizeTimingInput(timing);
3825
var callback = function() {
@@ -45,7 +32,7 @@
4532
// FIXME: There are actually more conditions under which the effect
4633
// should be called.
4734
if (t !== last)
48-
effect(t, target, animation);
35+
effect(t, target, player.source);
4936
last = t;
5037
};
5138

@@ -54,7 +41,7 @@
5441
callback._sequenceNumber = sequenceNumber++;
5542
player._callback = callback;
5643
register(callback);
57-
}
44+
};
5845

5946
var callbacks = [];
6047
var ticking = false;

src/group-constructors.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,31 @@
5252
}
5353
};
5454

55+
scope.newUnderlyingPlayerForGroup = function(group) {
56+
var underlyingPlayer;
57+
var ticker = function(tf) {
58+
var player = underlyingPlayer._wrapper;
59+
if (!player.source)
60+
return;
61+
if (tf == null) {
62+
player._removePlayers();
63+
return;
64+
}
65+
if (player.startTime === null)
66+
return;
67+
68+
player._updateChildren();
69+
};
70+
71+
underlyingPlayer = scope.timeline.play(new scope.Animation(null, ticker, group._timing));
72+
return underlyingPlayer;
73+
};
74+
75+
scope.bindPlayerForGroup = function(player) {
76+
player._player._wrapper = player;
77+
player._isGroup = true;
78+
scope.awaitStartTime(player);
79+
};
80+
81+
5582
})(webAnimationsShared, webAnimationsMaxifill, webAnimationsTesting);

src/maxifill-player.js

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,40 @@
1313
// limitations under the License.
1414

1515
(function(shared, scope, testing) {
16-
scope.Player = function(player) {
17-
this.source = null;
16+
scope.Player = function(source) {
17+
this.source = source;
18+
if (source) {
19+
// FIXME: detach existing player.
20+
source.player = this;
21+
}
1822
this._isGroup = false;
19-
this._player = player;
23+
this._player = null;
2024
this._childPlayers = [];
2125
this._callback = null;
26+
this._rebuildUnderlyingPlayer();
2227
};
2328

2429
// TODO: add a source getter/setter
2530
scope.Player.prototype = {
31+
_rebuildUnderlyingPlayer: function() {
32+
if (this._player) {
33+
this._player.cancel();
34+
this._player = null;
35+
}
36+
37+
if (!this.source) {
38+
return;
39+
}
40+
41+
if (this.source instanceof window.Animation) {
42+
this._player = scope.newUnderlyingPlayerForAnimation(this.source);
43+
scope.bindPlayerForAnimation(this);
44+
}
45+
if (this.source instanceof window.AnimationSequence || this.source instanceof window.AnimationGroup) {
46+
this._player = scope.newUnderlyingPlayerForGroup(this.source);
47+
scope.bindPlayerForGroup(this);
48+
}
49+
},
2650
get paused() {
2751
return this._player.paused;
2852
},

src/timeline.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,13 @@
1414

1515

1616
(function(shared, scope, testing) {
17+
1718
scope.AnimationTimeline = function() {
1819
this._players = [];
1920
this.currentTime = undefined;
2021
};
2122

2223
scope.AnimationTimeline.prototype = {
23-
_addPlayer: function(player) {
24-
this._players.push(player);
25-
scope.restartMaxifillTick();
26-
},
2724
// FIXME: This needs to return the wrapped players in maxifill
2825
// TODO: Does this need to be sorted?
2926
// TODO: Do we need to consider needsRetick?
@@ -35,7 +32,13 @@
3532
this._players = this._players.filter(function(player) {
3633
return player.playState != 'finished' && player.playState != 'idle';
3734
});
38-
}
35+
},
36+
play: function(source) {
37+
var player = new scope.Player(source);
38+
this._players.push(player);
39+
scope.restartMaxifillTick();
40+
return player;
41+
},
3942
};
4043

4144
var ticking = false;

test/js/effect-callback.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,28 @@ suite('effect-callback', function() {
4949
tick(501);
5050
assert.deepEqual(fractions, [0, 0.5, null]);
5151
});
52+
53+
test('element.animate is given animation', function() {
54+
var callbackAnim;
55+
var player = document.body.animate(function(t, target, a) {
56+
callbackAnim = a;
57+
}, 100);
58+
tick(50);
59+
tick(150);
60+
assert.equal(isTicking(), false);
61+
assert(callbackAnim, 'callback should be set');
62+
assert.equal(callbackAnim.target, document.body);
63+
});
64+
65+
test('effect callback on animation is given source animation', function() {
66+
var callbackAnim;
67+
var anim = new Animation(document.body, function(t, target, a) {
68+
callbackAnim = a;
69+
}, 1000);
70+
var player = document.timeline.play(anim);
71+
tick(50);
72+
tick(550);
73+
assert.equal(player.currentTime, 500);
74+
assert.equal(callbackAnim, anim);
75+
});
5276
});

0 commit comments

Comments
 (0)