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 this.currentTime = window.performance ? performance.now() : 0; |
| 54 }; |
| 55 |
| 56 InternalTimeline.prototype = { |
| 57 _play: function(source) { |
| 58 source._timing = shared.normalizeTimingInput(source.timing); |
| 59 var player = new scope.Player(source); |
| 60 player._idle = false; |
| 61 player._timeline = this; |
| 62 this._players.push(player); |
| 63 scope.restart(); |
| 64 scope.invalidateEffects(); |
| 65 return player; |
| 66 } |
| 67 }; |
| 68 |
| 69 var ticking = false; |
| 70 var hasRestartedThisFrame = false; |
| 71 |
| 72 scope.restart = function() { |
| 73 if (!ticking) { |
| 74 ticking = true; |
| 75 requestAnimationFrame(function() {}); |
| 76 hasRestartedThisFrame = true; |
| 77 } |
| 78 return hasRestartedThisFrame; |
| 79 }; |
| 80 |
| 81 var needsRetick = false; |
| 82 scope.invalidateEffects = function() { |
| 83 needsRetick = true; |
| 84 }; |
| 85 |
| 86 var pendingEffects = []; |
| 87 function applyPendingEffects() { |
| 88 pendingEffects.forEach(function(f) { f(); }); |
| 89 } |
| 90 |
| 91 var originalGetComputedStyle = window.getComputedStyle; |
| 92 Object.defineProperty(window, 'getComputedStyle', { |
| 93 configurable: true, |
| 94 enumerable: true, |
| 95 value: function() { |
| 96 if (needsRetick) tick(timeline.currentTime); |
| 97 applyPendingEffects(); |
| 98 return originalGetComputedStyle.apply(this, arguments); |
| 99 }, |
| 100 }); |
| 101 |
| 102 function tick(t) { |
| 103 hasRestartedThisFrame = false; |
| 104 var timeline = scope.timeline; |
| 105 timeline.currentTime = t; |
| 106 timeline._players.sort(comparePlayers); |
| 107 ticking = false; |
| 108 var updatingPlayers = timeline._players; |
| 109 timeline._players = []; |
| 110 |
| 111 var newPendingClears = []; |
| 112 var newPendingEffects = []; |
| 113 updatingPlayers = updatingPlayers.filter(function(player) { |
| 114 player._inTimeline = player._tick(t); |
| 115 |
| 116 if (!player._inEffect) |
| 117 newPendingClears.push(player._source); |
| 118 else |
| 119 newPendingEffects.push(player._source); |
| 120 |
| 121 if (!player.finished && !player.paused && !player._idle) |
| 122 ticking = true; |
| 123 |
| 124 return player._inTimeline; |
| 125 }); |
| 126 |
| 127 pendingEffects.length = 0; |
| 128 pendingEffects.push.apply(pendingEffects, newPendingClears); |
| 129 pendingEffects.push.apply(pendingEffects, newPendingEffects); |
| 130 |
| 131 timeline._players.push.apply(timeline._players, updatingPlayers); |
| 132 needsRetick = false; |
| 133 |
| 134 if (ticking) |
| 135 requestAnimationFrame(function() {}); |
| 136 }; |
| 137 |
| 138 if (WEB_ANIMATIONS_TESTING) { |
| 139 testing.tick = processRafCallbacks; |
| 140 testing.isTicking = function() { return ticking; }; |
| 141 testing.setTicking = function(newVal) { ticking = newVal; }; |
| 142 } |
| 143 |
| 144 var timeline = new InternalTimeline(); |
| 145 scope.timeline = timeline; |
| 146 |
| 147 })(webAnimationsShared, webAnimationsMinifill, webAnimationsTesting); |
OLD | NEW |