Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: third_party/polymer/components/web-animations-js/src/animation.js

Issue 3010683002: Update Polymer components. (Closed)
Patch Set: Rebase Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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(shared, scope, testing) {
16
17 shared.sequenceNumber = 0;
18
19 var AnimationEvent = 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.Animation = function(effect) {
34 this.id = '';
35 if (effect && effect._id) {
36 this.id = effect._id;
37 }
38 this._sequenceNumber = shared.sequenceNumber++;
39 this._currentTime = 0;
40 this._startTime = null;
41 this._paused = false;
42 this._playbackRate = 1;
43 this._inTimeline = true;
44 this._finishedFlag = true;
45 this.onfinish = null;
46 this._finishHandlers = [];
47 this._effect = effect;
48 this._inEffect = this._effect._update(0);
49 this._idle = true;
50 this._currentTimePending = false;
51 };
52
53 scope.Animation.prototype = {
54 _ensureAlive: function() {
55 // If an animation is playing backwards and is not fill backwards/both
56 // then it should go out of effect when it reaches the start of its
57 // active interval (currentTime == 0).
58 if (this.playbackRate < 0 && this.currentTime === 0) {
59 this._inEffect = this._effect._update(-1);
60 } else {
61 this._inEffect = this._effect._update(this.currentTime);
62 }
63 if (!this._inTimeline && (this._inEffect || !this._finishedFlag)) {
64 this._inTimeline = true;
65 scope.timeline._animations.push(this);
66 }
67 },
68 _tickCurrentTime: function(newTime, ignoreLimit) {
69 if (newTime != this._currentTime) {
70 this._currentTime = newTime;
71 if (this._isFinished && !ignoreLimit)
72 this._currentTime = this._playbackRate > 0 ? this._totalDuration : 0;
73 this._ensureAlive();
74 }
75 },
76 get currentTime() {
77 if (this._idle || this._currentTimePending)
78 return null;
79 return this._currentTime;
80 },
81 set currentTime(newTime) {
82 newTime = +newTime;
83 if (isNaN(newTime))
84 return;
85 scope.restart();
86 if (!this._paused && this._startTime != null) {
87 this._startTime = this._timeline.currentTime - newTime / this._playbackR ate;
88 }
89 this._currentTimePending = false;
90 if (this._currentTime == newTime)
91 return;
92 if (this._idle) {
93 this._idle = false;
94 this._paused = true;
95 }
96 this._tickCurrentTime(newTime, true);
97 scope.applyDirtiedAnimation(this);
98 },
99 get startTime() {
100 return this._startTime;
101 },
102 set startTime(newTime) {
103 newTime = +newTime;
104 if (isNaN(newTime))
105 return;
106 if (this._paused || this._idle)
107 return;
108 this._startTime = newTime;
109 this._tickCurrentTime((this._timeline.currentTime - this._startTime) * thi s.playbackRate);
110 scope.applyDirtiedAnimation(this);
111 },
112 get playbackRate() {
113 return this._playbackRate;
114 },
115 set playbackRate(value) {
116 if (value == this._playbackRate) {
117 return;
118 }
119 var oldCurrentTime = this.currentTime;
120 this._playbackRate = value;
121 this._startTime = null;
122 if (this.playState != 'paused' && this.playState != 'idle') {
123 this._finishedFlag = false;
124 this._idle = false;
125 this._ensureAlive();
126 scope.applyDirtiedAnimation(this);
127 }
128 if (oldCurrentTime != null) {
129 this.currentTime = oldCurrentTime;
130 }
131 },
132 get _isFinished() {
133 return !this._idle && (this._playbackRate > 0 && this._currentTime >= this ._totalDuration ||
134 this._playbackRate < 0 && this._currentTime <= 0);
135 },
136 get _totalDuration() { return this._effect._totalDuration; },
137 get playState() {
138 if (this._idle)
139 return 'idle';
140 if ((this._startTime == null && !this._paused && this.playbackRate != 0) | | this._currentTimePending)
141 return 'pending';
142 if (this._paused)
143 return 'paused';
144 if (this._isFinished)
145 return 'finished';
146 return 'running';
147 },
148 _rewind: function() {
149 if (this._playbackRate >= 0) {
150 this._currentTime = 0;
151 } else if (this._totalDuration < Infinity) {
152 this._currentTime = this._totalDuration;
153 } else {
154 throw new DOMException(
155 'Unable to rewind negative playback rate animation with infinite dur ation',
156 'InvalidStateError');
157 }
158 },
159 play: function() {
160 this._paused = false;
161 if (this._isFinished || this._idle) {
162 this._rewind();
163 this._startTime = null;
164 }
165 this._finishedFlag = false;
166 this._idle = false;
167 this._ensureAlive();
168 scope.applyDirtiedAnimation(this);
169 },
170 pause: function() {
171 if (!this._isFinished && !this._paused && !this._idle) {
172 this._currentTimePending = true;
173 } else if (this._idle) {
174 this._rewind();
175 this._idle = false;
176 }
177 this._startTime = null;
178 this._paused = true;
179 },
180 finish: function() {
181 if (this._idle)
182 return;
183 this.currentTime = this._playbackRate > 0 ? this._totalDuration : 0;
184 this._startTime = this._totalDuration - this.currentTime;
185 this._currentTimePending = false;
186 scope.applyDirtiedAnimation(this);
187 },
188 cancel: function() {
189 if (!this._inEffect)
190 return;
191 this._inEffect = false;
192 this._idle = true;
193 this._paused = false;
194 this._isFinished = true;
195 this._finishedFlag = true;
196 this._currentTime = 0;
197 this._startTime = null;
198 this._effect._update(null);
199 // effects are invalid after cancellation as the animation state
200 // needs to un-apply.
201 scope.applyDirtiedAnimation(this);
202 },
203 reverse: function() {
204 this.playbackRate *= -1;
205 this.play();
206 },
207 addEventListener: function(type, handler) {
208 if (typeof handler == 'function' && type == 'finish')
209 this._finishHandlers.push(handler);
210 },
211 removeEventListener: function(type, handler) {
212 if (type != 'finish')
213 return;
214 var index = this._finishHandlers.indexOf(handler);
215 if (index >= 0)
216 this._finishHandlers.splice(index, 1);
217 },
218 _fireEvents: function(baseTime) {
219 if (this._isFinished) {
220 if (!this._finishedFlag) {
221 var event = new AnimationEvent(this, this._currentTime, baseTime);
222 var handlers = this._finishHandlers.concat(this.onfinish ? [this.onfin ish] : []);
223 setTimeout(function() {
224 handlers.forEach(function(handler) {
225 handler.call(event.target, event);
226 });
227 }, 0);
228 this._finishedFlag = true;
229 }
230 } else {
231 this._finishedFlag = false;
232 }
233 },
234 _tick: function(timelineTime, isAnimationFrame) {
235 if (!this._idle && !this._paused) {
236 if (this._startTime == null) {
237 if (isAnimationFrame) {
238 this.startTime = timelineTime - this._currentTime / this.playbackRat e;
239 }
240 } else if (!this._isFinished) {
241 this._tickCurrentTime((timelineTime - this._startTime) * this.playback Rate);
242 }
243 }
244
245 if (isAnimationFrame) {
246 this._currentTimePending = false;
247 this._fireEvents(timelineTime);
248 }
249 },
250 get _needsTick() {
251 return (this.playState in {'pending': 1, 'running': 1}) || !this._finished Flag;
252 },
253 _targetAnimations: function() {
254 var target = this._effect._target;
255 if (!target._activeAnimations) {
256 target._activeAnimations = [];
257 }
258 return target._activeAnimations;
259 },
260 _markTarget: function() {
261 var animations = this._targetAnimations();
262 if (animations.indexOf(this) === -1) {
263 animations.push(this);
264 }
265 },
266 _unmarkTarget: function() {
267 var animations = this._targetAnimations();
268 var index = animations.indexOf(this);
269 if (index !== -1) {
270 animations.splice(index, 1);
271 }
272 },
273 };
274
275 if (WEB_ANIMATIONS_TESTING) {
276 testing.webAnimations1Animation = scope.Animation;
277 }
278
279 })(webAnimationsShared, webAnimations1, webAnimationsTesting);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698