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 })(webAnimations1, webAnimationsTesting); | |
OLD | NEW |