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 (function(scope, testing) { |
| 16 |
| 17 var sequenceNumber = 0; |
| 18 |
| 19 var AnimationPlayerEvent = function(target, currentTime, timelineTime) { |
| 20 this.target = target; |
| 21 this.currentTime = currentTime; |
| 22 this.timelineTime = timelineTime; |
| 23 |
| 24 this.type = 'finish'; |
| 25 this.bubbles = false; |
| 26 this.cancelable = false; |
| 27 this.currentTarget = target; |
| 28 this.defaultPrevented = false; |
| 29 this.eventPhase = Event.AT_TARGET; |
| 30 this.timeStamp = Date.now(); |
| 31 }; |
| 32 |
| 33 scope.Player = function(source) { |
| 34 this._sequenceNumber = sequenceNumber++; |
| 35 this._currentTime = 0; |
| 36 this._startTime = null; |
| 37 this.paused = false; |
| 38 this._playbackRate = 1; |
| 39 this._inTimeline = true; |
| 40 this._finishedFlag = false; |
| 41 this.onfinish = null; |
| 42 this._finishHandlers = []; |
| 43 this._source = source; |
| 44 this._inEffect = this._source._update(0); |
| 45 this._idle = true; |
| 46 this._currentTimePending = false; |
| 47 }; |
| 48 |
| 49 scope.Player.prototype = { |
| 50 _ensureAlive: function() { |
| 51 this._inEffect = this._source._update(this.currentTime); |
| 52 if (!this._inTimeline && (this._inEffect || !this._finishedFlag)) { |
| 53 this._inTimeline = true; |
| 54 scope.timeline._players.push(this); |
| 55 } |
| 56 }, |
| 57 _tickCurrentTime: function(newTime, ignoreLimit) { |
| 58 if (newTime != this._currentTime) { |
| 59 this._currentTime = newTime; |
| 60 if (this.finished && !ignoreLimit) |
| 61 this._currentTime = this._playbackRate > 0 ? this._totalDuration : 0; |
| 62 this._ensureAlive(); |
| 63 } |
| 64 }, |
| 65 get currentTime() { |
| 66 if (this._idle || this._currentTimePending) |
| 67 return null; |
| 68 return this._currentTime; |
| 69 }, |
| 70 set currentTime(newTime) { |
| 71 newTime = +newTime; |
| 72 if (isNaN(newTime)) |
| 73 return; |
| 74 scope.restart(); |
| 75 if (!this.paused && this._startTime != null) { |
| 76 this._startTime = this._timeline.currentTime - newTime / this._playbackR
ate; |
| 77 } |
| 78 this._currentTimePending = false; |
| 79 if (this._currentTime == newTime) |
| 80 return; |
| 81 this._tickCurrentTime(newTime, true); |
| 82 scope.invalidateEffects(); |
| 83 }, |
| 84 get startTime() { |
| 85 return this._startTime; |
| 86 }, |
| 87 set startTime(newTime) { |
| 88 newTime = +newTime; |
| 89 if (isNaN(newTime)) |
| 90 return; |
| 91 if (this.paused || this._idle) |
| 92 return; |
| 93 this._startTime = newTime; |
| 94 this._tickCurrentTime((this._timeline.currentTime - this._startTime) * thi
s.playbackRate); |
| 95 scope.invalidateEffects(); |
| 96 }, |
| 97 get playbackRate() { return this._playbackRate; }, |
| 98 get finished() { |
| 99 return !this._idle && (this._playbackRate > 0 && this._currentTime >= this
._totalDuration || |
| 100 this._playbackRate < 0 && this._currentTime <= 0); |
| 101 }, |
| 102 get _totalDuration() { return this._source._totalDuration; }, |
| 103 get playState() { |
| 104 if (this._idle) |
| 105 return 'idle'; |
| 106 if ((this._startTime == null && !this.paused && this.playbackRate != 0) ||
this._currentTimePending) |
| 107 return 'pending'; |
| 108 if (this.paused) |
| 109 return 'paused'; |
| 110 if (this.finished) |
| 111 return 'finished'; |
| 112 return 'running'; |
| 113 }, |
| 114 play: function() { |
| 115 this.paused = false; |
| 116 if (this.finished || this._idle) { |
| 117 this._currentTime = this._playbackRate > 0 ? 0 : this._totalDuration; |
| 118 this._startTime = null; |
| 119 scope.invalidateEffects(); |
| 120 } |
| 121 this._finishedFlag = false; |
| 122 scope.restart(); |
| 123 this._idle = false; |
| 124 this._ensureAlive(); |
| 125 }, |
| 126 pause: function() { |
| 127 if (!this.finished && !this.paused && !this._idle) { |
| 128 this._currentTimePending = true; |
| 129 } |
| 130 this._startTime = null; |
| 131 this.paused = true; |
| 132 }, |
| 133 finish: function() { |
| 134 if (this._idle) |
| 135 return; |
| 136 this.currentTime = this._playbackRate > 0 ? this._totalDuration : 0; |
| 137 this._startTime = this._totalDuration - this.currentTime; |
| 138 this._currentTimePending = false; |
| 139 }, |
| 140 cancel: function() { |
| 141 this._inEffect = false; |
| 142 this._idle = true; |
| 143 this.currentTime = 0; |
| 144 this._startTime = null; |
| 145 }, |
| 146 reverse: function() { |
| 147 this._playbackRate *= -1; |
| 148 this._startTime = null; |
| 149 this.play(); |
| 150 }, |
| 151 addEventListener: function(type, handler) { |
| 152 if (typeof handler == 'function' && type == 'finish') |
| 153 this._finishHandlers.push(handler); |
| 154 }, |
| 155 removeEventListener: function(type, handler) { |
| 156 if (type != 'finish') |
| 157 return; |
| 158 var index = this._finishHandlers.indexOf(handler); |
| 159 if (index >= 0) |
| 160 this._finishHandlers.splice(index, 1); |
| 161 }, |
| 162 _fireEvents: function(baseTime) { |
| 163 var finished = this.finished; |
| 164 if ((finished || this._idle) && !this._finishedFlag) { |
| 165 var event = new AnimationPlayerEvent(this, this._currentTime, baseTime); |
| 166 var handlers = this._finishHandlers.concat(this.onfinish ? [this.onfinis
h] : []); |
| 167 setTimeout(function() { |
| 168 handlers.forEach(function(handler) { |
| 169 handler.call(event.target, event); |
| 170 }); |
| 171 }, 0); |
| 172 } |
| 173 this._finishedFlag = finished; |
| 174 }, |
| 175 _tick: function(timelineTime) { |
| 176 if (!this._idle && !this.paused) { |
| 177 if (this._startTime == null) |
| 178 this.startTime = timelineTime - this._currentTime / this.playbackRate; |
| 179 else if (!this.finished) |
| 180 this._tickCurrentTime((timelineTime - this._startTime) * this.playback
Rate); |
| 181 } |
| 182 |
| 183 this._currentTimePending = false; |
| 184 this._fireEvents(timelineTime); |
| 185 return !this._idle && (this._inEffect || !this._finishedFlag); |
| 186 }, |
| 187 }; |
| 188 |
| 189 if (WEB_ANIMATIONS_TESTING) { |
| 190 testing.Player = scope.Player; |
| 191 } |
| 192 |
| 193 })(webAnimationsMinifill, webAnimationsTesting); |
OLD | NEW |