| 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 |