OLD | NEW |
| (Empty) |
1 // Copyright 2014 Google Inc. All rights reserved. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 | |
15 | |
16 (function(shared, scope, testing) { | |
17 var originalRequestAnimationFrame = window.requestAnimationFrame; | |
18 var rafCallbacks = []; | |
19 var rafId = 0; | |
20 window.requestAnimationFrame = function(f) { | |
21 var id = rafId++; | |
22 if (rafCallbacks.length == 0 && !WEB_ANIMATIONS_TESTING) { | |
23 originalRequestAnimationFrame(processRafCallbacks); | |
24 } | |
25 rafCallbacks.push([id, f]); | |
26 return id; | |
27 }; | |
28 | |
29 window.cancelAnimationFrame = function(id) { | |
30 rafCallbacks.forEach(function(entry) { | |
31 if (entry[0] == id) { | |
32 entry[1] = function() {}; | |
33 } | |
34 }); | |
35 }; | |
36 | |
37 function processRafCallbacks(t) { | |
38 var processing = rafCallbacks; | |
39 rafCallbacks = []; | |
40 tick(t); | |
41 processing.forEach(function(entry) { entry[1](t); }); | |
42 if (needsRetick) | |
43 tick(t); | |
44 applyPendingEffects(); | |
45 } | |
46 | |
47 function comparePlayers(leftPlayer, rightPlayer) { | |
48 return leftPlayer._sequenceNumber - rightPlayer._sequenceNumber; | |
49 } | |
50 | |
51 function InternalTimeline() { | |
52 this._players = []; | |
53 // Android 4.3 browser has window.performance, but not window.performance.no
w | |
54 this.currentTime = window.performance && performance.now ? performance.now()
: 0; | |
55 }; | |
56 | |
57 InternalTimeline.prototype = { | |
58 _play: function(source) { | |
59 source._timing = shared.normalizeTimingInput(source.timing); | |
60 var player = new scope.Player(source); | |
61 player._idle = false; | |
62 player._timeline = this; | |
63 this._players.push(player); | |
64 scope.restart(); | |
65 scope.invalidateEffects(); | |
66 return player; | |
67 } | |
68 }; | |
69 | |
70 var ticking = false; | |
71 var hasRestartedThisFrame = false; | |
72 | |
73 scope.restart = function() { | |
74 if (!ticking) { | |
75 ticking = true; | |
76 requestAnimationFrame(function() {}); | |
77 hasRestartedThisFrame = true; | |
78 } | |
79 return hasRestartedThisFrame; | |
80 }; | |
81 | |
82 var needsRetick = false; | |
83 scope.invalidateEffects = function() { | |
84 needsRetick = true; | |
85 }; | |
86 | |
87 var pendingEffects = []; | |
88 function applyPendingEffects() { | |
89 pendingEffects.forEach(function(f) { f(); }); | |
90 } | |
91 | |
92 var originalGetComputedStyle = window.getComputedStyle; | |
93 Object.defineProperty(window, 'getComputedStyle', { | |
94 configurable: true, | |
95 enumerable: true, | |
96 value: function() { | |
97 if (needsRetick) tick(timeline.currentTime); | |
98 applyPendingEffects(); | |
99 return originalGetComputedStyle.apply(this, arguments); | |
100 }, | |
101 }); | |
102 | |
103 function tick(t) { | |
104 hasRestartedThisFrame = false; | |
105 var timeline = scope.timeline; | |
106 timeline.currentTime = t; | |
107 timeline._players.sort(comparePlayers); | |
108 ticking = false; | |
109 var updatingPlayers = timeline._players; | |
110 timeline._players = []; | |
111 | |
112 var newPendingClears = []; | |
113 var newPendingEffects = []; | |
114 updatingPlayers = updatingPlayers.filter(function(player) { | |
115 player._inTimeline = player._tick(t); | |
116 | |
117 if (!player._inEffect) | |
118 newPendingClears.push(player._source); | |
119 else | |
120 newPendingEffects.push(player._source); | |
121 | |
122 if (!player.finished && !player.paused && !player._idle) | |
123 ticking = true; | |
124 | |
125 return player._inTimeline; | |
126 }); | |
127 | |
128 pendingEffects.length = 0; | |
129 pendingEffects.push.apply(pendingEffects, newPendingClears); | |
130 pendingEffects.push.apply(pendingEffects, newPendingEffects); | |
131 | |
132 timeline._players.push.apply(timeline._players, updatingPlayers); | |
133 needsRetick = false; | |
134 | |
135 if (ticking) | |
136 requestAnimationFrame(function() {}); | |
137 }; | |
138 | |
139 if (WEB_ANIMATIONS_TESTING) { | |
140 testing.tick = processRafCallbacks; | |
141 testing.isTicking = function() { return ticking; }; | |
142 testing.setTicking = function(newVal) { ticking = newVal; }; | |
143 } | |
144 | |
145 var timeline = new InternalTimeline(); | |
146 scope.timeline = timeline; | |
147 | |
148 })(webAnimationsShared, webAnimations1, webAnimationsTesting); | |
OLD | NEW |