author | Giulio Cesare Solaroli <giulio.cesare@clipperz.com> | 2011-10-02 23:56:18 (UTC) |
---|---|---|
committer | Giulio Cesare Solaroli <giulio.cesare@clipperz.com> | 2011-10-02 23:56:18 (UTC) |
commit | ef68436ac04da078ffdcacd7e1f785473a303d45 (patch) (unidiff) | |
tree | c403752d66a2c4775f00affd4fa8431b29c5b68c /frontend/beta/js/YUI-extensions/anim/Animator.js | |
parent | 597ecfbc0249d83e1b856cbd558340c01237a360 (diff) | |
download | clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.zip clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.gz clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.bz2 |
First version of the newly restructured repository
Diffstat (limited to 'frontend/beta/js/YUI-extensions/anim/Animator.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/beta/js/YUI-extensions/anim/Animator.js | 482 |
1 files changed, 482 insertions, 0 deletions
diff --git a/frontend/beta/js/YUI-extensions/anim/Animator.js b/frontend/beta/js/YUI-extensions/anim/Animator.js new file mode 100644 index 0000000..ed250fb --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/anim/Animator.js | |||
@@ -0,0 +1,482 @@ | |||
1 | /** | ||
2 | * @class YAHOO.ext.Animator | ||
3 | * Provides support for syncing animations for multiple {@link YAHOO.ext.Actor}s.<br><br> | ||
4 | * <br><br>This example can be seen in action <a href="http://www.jackslocum.com/yui/2006/08/19/a-splitbar-component-for-yahoo-ui/" target="_new">here</a> | ||
5 | * by clicking on "Click here and I will point it out" at the end of the first paragraph.<br> | ||
6 | * <pre><code> | ||
7 | var animator = new YAHOO.ext.Animator(); | ||
8 | var cursor = new YAHOO.ext.Actor('cursor-img', animator); | ||
9 | var click = new YAHOO.ext.Actor('click-img', animator); | ||
10 | var resize = new YAHOO.ext.Actor('resize-img', animator); | ||
11 | |||
12 | // start capturing | ||
13 | animator.startCapture(); | ||
14 | |||
15 | // these animations will be run in sequence | ||
16 | cursor.show(); | ||
17 | cursor.moveTo(500,400); | ||
18 | cursor.moveTo(20, getEl('navbar').getY()+10, true, .75); | ||
19 | click.show(); | ||
20 | click.alignTo(cursor, 'tl', [-4, -4]); | ||
21 | |||
22 | // Add an async function call, pass callback to argument 1 | ||
23 | animator.addAsyncCall(Blog.navbar.undockDelegate, 1); | ||
24 | |||
25 | // pause .5 seconds | ||
26 | animator.pause(.5); | ||
27 | |||
28 | // again, these animations will be run in sequence | ||
29 | click.hide(true, .7); | ||
30 | cursor.alignTo('splitter', 'tr', [0, +100], true, 1); | ||
31 | resize.alignTo('splitter', 'tr', [-12, +100]); | ||
32 | |||
33 | // start sync block: these animations will run at the same time | ||
34 | animator.beginSync(); | ||
35 | cursor.hide(); | ||
36 | resize.show(); | ||
37 | animator.endSync(); | ||
38 | |||
39 | // play the captured animation sequences, call myCallback when done | ||
40 | animator.play(myCallback); | ||
41 | * </code></pre> | ||
42 | * @requires YAHOO.ext.Element | ||
43 | * @requires YAHOO.util.Dom | ||
44 | * @requires YAHOO.util.Event | ||
45 | * @requires YAHOO.util.CustomEvent | ||
46 | * @requires YAHOO.util.Anim | ||
47 | * @requires YAHOO.util.ColorAnim | ||
48 | * @requires YAHOO.util.Motion | ||
49 | * @constructor | ||
50 | * @param {String/HTMLElement} el The dom element or element id | ||
51 | * @param {<i>YAHOO.ext.Animator</i>} animator (optional) The Animator that will capture this Actor's actions | ||
52 | * @param {<i>Boolean</i>} selfCapture (optional) Whether this actor should capture it's own actions to support self playback without an animator (defaults to false) | ||
53 | */ | ||
54 | YAHOO.ext.Animator = function(/*Actors...*/){ | ||
55 | this.actors = []; | ||
56 | this.playlist = new YAHOO.ext.Animator.AnimSequence(); | ||
57 | this.captureDelegate = this.capture.createDelegate(this); | ||
58 | this.playDelegate = this.play.createDelegate(this); | ||
59 | this.syncing = false; | ||
60 | this.stopping = false; | ||
61 | this.playing = false; | ||
62 | for(var i = 0; i < arguments.length; i++){ | ||
63 | this.addActor(arguments[i]); | ||
64 | } | ||
65 | }; | ||
66 | |||
67 | YAHOO.ext.Animator.prototype = { | ||
68 | |||
69 | capture : function(actor, action){ | ||
70 | if(this.syncing){ | ||
71 | if(!this.syncMap[actor.id]){ | ||
72 | this.syncMap[actor.id] = new YAHOO.ext.Animator.AnimSequence(); | ||
73 | } | ||
74 | this.syncMap[actor.id].add(action); | ||
75 | }else{ | ||
76 | this.playlist.add(action); | ||
77 | } | ||
78 | }, | ||
79 | |||
80 | /** | ||
81 | * Add an actor. The actor is also set to capturing = true. | ||
82 | * @param {YAHOO.ext.Actor} actor | ||
83 | */ | ||
84 | addActor : function(actor){ | ||
85 | actor.onCapture.subscribe(this.captureDelegate); | ||
86 | this.actors.push(actor); | ||
87 | }, | ||
88 | |||
89 | |||
90 | /** | ||
91 | * Start capturing actions on the added actors. | ||
92 | * @param {<i>Boolean</i>} clearPlaylist Whether to also create a new playlist | ||
93 | */ | ||
94 | startCapture : function(clearPlaylist){ | ||
95 | for(var i = 0; i < this.actors.length; i++){ | ||
96 | var a = this.actors[i]; | ||
97 | if(!this.isCapturing(a)){ | ||
98 | a.onCapture.subscribe(this.captureDelegate); | ||
99 | } | ||
100 | a.capturing = true; | ||
101 | } | ||
102 | if(clearPlaylist){ | ||
103 | this.playlist = new YAHOO.ext.Animator.AnimSequence(); | ||
104 | } | ||
105 | }, | ||
106 | |||
107 | /** | ||
108 | * Checks whether this animator is listening to a specific actor. | ||
109 | * @param {YAHOO.ext.Actor} actor | ||
110 | */ | ||
111 | isCapturing : function(actor){ | ||
112 | var subscribers = actor.onCapture.subscribers; | ||
113 | if(subscribers){ | ||
114 | for(var i = 0; i < subscribers.length; i++){ | ||
115 | if(subscribers[i] && subscribers[i].contains(this.captureDelegate)){ | ||
116 | return true; | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | return false; | ||
121 | }, | ||
122 | |||
123 | /** | ||
124 | * Stop capturing on all added actors. | ||
125 | */ | ||
126 | stopCapture : function(){ | ||
127 | for(var i = 0; i < this.actors.length; i++){ | ||
128 | var a = this.actors[i]; | ||
129 | a.onCapture.unsubscribe(this.captureDelegate); | ||
130 | a.capturing = false; | ||
131 | } | ||
132 | }, | ||
133 | |||
134 | /** | ||
135 | * Start a multi-actor sync block. By default all animations are run in sequence. While in the sync block | ||
136 | * each actor's own animations will still be sequenced, but all actors will animate at the same time. | ||
137 | */ | ||
138 | beginSync : function(){ | ||
139 | this.syncing = true; | ||
140 | this.syncMap = {}; | ||
141 | }, | ||
142 | |||
143 | /** | ||
144 | * End the multi-actor sync block | ||
145 | */ | ||
146 | endSync : function(){ | ||
147 | this.syncing = false; | ||
148 | var composite = new YAHOO.ext.Animator.CompositeSequence(); | ||
149 | for(key in this.syncMap){ | ||
150 | if(typeof this.syncMap[key] != 'function'){ | ||
151 | composite.add(this.syncMap[key]); | ||
152 | } | ||
153 | } | ||
154 | this.playlist.add(composite); | ||
155 | this.syncMap = null; | ||
156 | }, | ||
157 | |||
158 | /** | ||
159 | * Starts playback of the playlist, also stops any capturing. To start capturing again call {@link #startCapture}. | ||
160 | * @param {<i>Function</i>} oncomplete (optional) Callback to execute when playback has completed | ||
161 | */ | ||
162 | play : function(oncomplete){ | ||
163 | if(this.playing) return; // can't play the same animation twice at once | ||
164 | this.stopCapture(); | ||
165 | this.playlist.play(oncomplete); | ||
166 | }, | ||
167 | |||
168 | /** | ||
169 | * Stop at the next available stopping point | ||
170 | */ | ||
171 | stop : function(){ | ||
172 | this.playlist.stop(); | ||
173 | }, | ||
174 | |||
175 | /** | ||
176 | * Check if this animator is currently playing | ||
177 | */ | ||
178 | isPlaying : function(){ | ||
179 | return this.playlist.isPlaying(); | ||
180 | }, | ||
181 | /** | ||
182 | * Clear the playlist | ||
183 | */ | ||
184 | clear : function(){ | ||
185 | this.playlist = new YAHOO.ext.Animator.AnimSequence(); | ||
186 | }, | ||
187 | |||
188 | /** | ||
189 | * Add a function call to the playlist. | ||
190 | * @param {Function} fcn The function to call | ||
191 | * @param {<i>Array</i>} args The arguments to call the function with | ||
192 | * @param {<i>Object</i>} scope (optional) The scope of the function | ||
193 | */ | ||
194 | addCall : function(fcn, args, scope){ | ||
195 | this.playlist.add(new YAHOO.ext.Actor.Action(scope, fcn, args || [])); | ||
196 | }, | ||
197 | |||
198 | /** | ||
199 | * Add an async function call to the playlist. | ||
200 | * @param {Function} fcn The function to call | ||
201 | * @param {Number} callbackIndex The index of the callback parameter on the passed function. A CALLBACK IS REQUIRED. | ||
202 | * @param {<i>Array</i>} args The arguments to call the function with | ||
203 | * @param {<i>Object</i>} scope (optional) The scope of the function | ||
204 | */ | ||
205 | addAsyncCall : function(fcn, callbackIndex, args, scope){ | ||
206 | this.playlist.add(new YAHOO.ext.Actor.AsyncAction(scope, fcn, args || [], callbackIndex)); | ||
207 | }, | ||
208 | |||
209 | /** | ||
210 | * Add a pause to the playlist (in seconds) | ||
211 | * @param {Number} seconds The number of seconds to pause. | ||
212 | */ | ||
213 | pause : function(seconds){ | ||
214 | this.playlist.add(new YAHOO.ext.Actor.PauseAction(seconds)); | ||
215 | } | ||
216 | |||
217 | }; | ||
218 | /** | ||
219 | * Static function to build a AnimatorComposite from a css selector (requires YAHOO.ext.Element.selectorFunction be defined) | ||
220 | * @param {String/Array} selector The css selector or an array of nodes to animate | ||
221 | * @method @static | ||
222 | */ | ||
223 | YAHOO.ext.Animator.select = function(selector){ | ||
224 | var els; | ||
225 | if(typeof selector == 'string'){ | ||
226 | els = YAHOO.ext.Element.selectorFunction(selector); | ||
227 | }else if(selector instanceof Array){ | ||
228 | els = selector; | ||
229 | }else{ | ||
230 | throw 'Invalid selector'; | ||
231 | } | ||
232 | return new YAHOO.ext.AnimatorComposite(els); | ||
233 | }; | ||
234 | var getActors = YAHOO.ext.Animator.select; | ||
235 | |||
236 | /** | ||
237 | * @class YAHOO.ext.AnimatorComposite | ||
238 | * Composite class with synchronized animations. This is the class returned by getActors(selector) or YAHOO.ext.Animator.select(). | ||
239 | */ | ||
240 | YAHOO.ext.AnimatorComposite = function(els){ | ||
241 | this.animator = new YAHOO.ext.Animator(); | ||
242 | this.addElements(els); | ||
243 | this.syncAnims = true; | ||
244 | }; | ||
245 | YAHOO.ext.AnimatorComposite.prototype = { | ||
246 | isComposite: true, | ||
247 | /** | ||
248 | * Adds elements to this composite. | ||
249 | * @param {Array} els An array of elements to add | ||
250 | * @return {AnimatorComposite} this | ||
251 | */ | ||
252 | addElements : function(els){ | ||
253 | if(!els) return this; | ||
254 | var anim = this.animator; | ||
255 | for(var i = 0, len = els.length; i < len; i++) { | ||
256 | anim.addActor(new YAHOO.ext.Actor(els[i])); | ||
257 | } | ||
258 | anim.startCapture(); | ||
259 | return this; | ||
260 | }, | ||
261 | /** | ||
262 | * Operations called after sequence() will be performed one by one on each element in this composite. | ||
263 | * @return {AnimatorComposite} this | ||
264 | */ | ||
265 | sequence : function(){ | ||
266 | this.syncAnims = false; | ||
267 | return this; | ||
268 | }, | ||
269 | /** | ||
270 | * Operations called after sync() will be performed at the same time on each element in this composite. | ||
271 | * @return {AnimatorComposite} this | ||
272 | */ | ||
273 | sync : function(){ | ||
274 | this.syncAnims = true; | ||
275 | return this; | ||
276 | }, | ||
277 | invoke : function(fn, args){ | ||
278 | var els = this.animator.actors; | ||
279 | if(this.syncAnims) this.animator.beginSync(); | ||
280 | for(var i = 0, len = els.length; i < len; i++) { | ||
281 | YAHOO.ext.Actor.prototype[fn].apply(els[i], args); | ||
282 | } | ||
283 | if(this.syncAnims) this.animator.endSync(); | ||
284 | return this; | ||
285 | }, | ||
286 | /** | ||
287 | * Play the actions queued in this composite. | ||
288 | * @param {Function} callback (optional) callback is called when all animations have compelted | ||
289 | * @return {AnimatorComposite} this | ||
290 | */ | ||
291 | play : function(callback){ | ||
292 | this.animator.play(callback); | ||
293 | return this; | ||
294 | }, | ||
295 | /** | ||
296 | * Clear all actions in the queue. | ||
297 | * @param {Function} callback (optional) callback is called when all animations have compelted | ||
298 | * @return {AnimatorComposite} this | ||
299 | */ | ||
300 | reset : function(callback){ | ||
301 | this.animator.startCapture(true); | ||
302 | return this; | ||
303 | }, | ||
304 | /** | ||
305 | * Add a pause | ||
306 | * @param {Number} seconds | ||
307 | * @return {AnimatorComposite} this | ||
308 | */ | ||
309 | pause : function(seconds){ | ||
310 | this.animator.pause(seconds); | ||
311 | return this; | ||
312 | }, | ||
313 | /** | ||
314 | * Get the YAHOO.ext.Animator that controls the animations for this composite. | ||
315 | * @return {YAHOO.ext.Animator} | ||
316 | */ | ||
317 | getAnimator : function(){ | ||
318 | return this.animator; | ||
319 | }, | ||
320 | /** | ||
321 | * Calls the passed function passing (el, this, index) for each element in this composite. | ||
322 | * @param {Function} fn The function to call | ||
323 | * @param {Object} scope (optional) The <i>this</i> object (defaults to the element) | ||
324 | * @return {AnimatorComposite} this | ||
325 | */ | ||
326 | each : function(fn, scope){ | ||
327 | var els = this.animator.actors; | ||
328 | if(this.syncAnims) this.animator.beginSync(); | ||
329 | for(var i = 0, len = els.length; i < len; i++){ | ||
330 | fn.call(scope || els[i], els[i], this, i); | ||
331 | } | ||
332 | if(this.syncAnims) this.animator.endSync(); | ||
333 | return this; | ||
334 | }, | ||
335 | /** | ||
336 | * Add a function call to the playlist. | ||
337 | * @param {Function} fcn The function to call | ||
338 | * @param {<i>Array</i>} args (optional) The arguments to call the function with | ||
339 | * @param {<i>Object</i>} scope (optional) The scope of the function | ||
340 | * @return {AnimatorComposite} this | ||
341 | */ | ||
342 | addCall : function(fcn, args, scope){ | ||
343 | this.animator.addCall(fcn, args, scope); | ||
344 | return this; | ||
345 | }, | ||
346 | /** | ||
347 | * Add an async function call to the playlist. | ||
348 | * @param {Function} fcn The function to call | ||
349 | * @param {Number} callbackIndex The index of the callback parameter on the passed function. <b>A CALLBACK IS REQUIRED</b>. | ||
350 | * @param {<i>Array</i>} args (optional) The arguments to call the function with | ||
351 | * @param {<i>Object</i>} scope (optional) The scope of the function | ||
352 | * @return {AnimatorComposite} this | ||
353 | */ | ||
354 | addAsyncCall : function(fcn, callbackIndex, args, scope){ | ||
355 | this.animator.addAsyncCall(fcn, callbackIndex, args, scope); | ||
356 | return this; | ||
357 | } | ||
358 | }; | ||
359 | for(var fnName in YAHOO.ext.Actor.prototype){ | ||
360 | if(typeof YAHOO.ext.Actor.prototype[fnName] == 'function'){ | ||
361 | YAHOO.ext.CompositeElement.createCall(YAHOO.ext.AnimatorComposite.prototype, fnName); | ||
362 | } | ||
363 | } | ||
364 | |||
365 | |||
366 | YAHOO.ext.Animator.AnimSequence = function(){ | ||
367 | this.actions = []; | ||
368 | this.nextDelegate = this.next.createDelegate(this); | ||
369 | this.playDelegate = this.play.createDelegate(this); | ||
370 | this.oncomplete = null; | ||
371 | this.playing = false; | ||
372 | this.stopping = false; | ||
373 | this.actionIndex = -1; | ||
374 | }; | ||
375 | |||
376 | YAHOO.ext.Animator.AnimSequence.prototype = { | ||
377 | |||
378 | add : function(action){ | ||
379 | this.actions.push(action); | ||
380 | }, | ||
381 | |||
382 | next : function(){ | ||
383 | if(this.stopping){ | ||
384 | this.playing = false; | ||
385 | if(this.oncomplete){ | ||
386 | this.oncomplete(this, false); | ||
387 | } | ||
388 | return; | ||
389 | } | ||
390 | var nextAction = this.actions[++this.actionIndex]; | ||
391 | if(nextAction){ | ||
392 | nextAction.play(this.nextDelegate); | ||
393 | }else{ | ||
394 | this.playing = false; | ||
395 | if(this.oncomplete){ | ||
396 | this.oncomplete(this, true); | ||
397 | } | ||
398 | } | ||
399 | }, | ||
400 | |||
401 | play : function(oncomplete){ | ||
402 | if(this.playing) return; // can't play the same sequence twice at once | ||
403 | this.oncomplete = oncomplete; | ||
404 | this.stopping = false; | ||
405 | this.playing = true; | ||
406 | this.actionIndex = -1; | ||
407 | this.next(); | ||
408 | }, | ||
409 | |||
410 | stop : function(){ | ||
411 | this.stopping = true; | ||
412 | }, | ||
413 | |||
414 | isPlaying : function(){ | ||
415 | return this.playing; | ||
416 | }, | ||
417 | |||
418 | clear : function(){ | ||
419 | this.actions = []; | ||
420 | }, | ||
421 | |||
422 | addCall : function(fcn, args, scope){ | ||
423 | this.actions.push(new YAHOO.ext.Actor.Action(scope, fcn, args || [])); | ||
424 | }, | ||
425 | |||
426 | addAsyncCall : function(fcn, callbackIndex, args, scope){ | ||
427 | this.actions.push(new YAHOO.ext.Actor.AsyncAction(scope, fcn, args || [], callbackIndex)); | ||
428 | }, | ||
429 | |||
430 | pause : function(seconds){ | ||
431 | this.actions.push(new YAHOO.ext.Actor.PauseAction(seconds)); | ||
432 | } | ||
433 | |||
434 | }; | ||
435 | |||
436 | YAHOO.ext.Animator.CompositeSequence = function(){ | ||
437 | this.sequences = []; | ||
438 | this.completed = 0; | ||
439 | this.trackDelegate = this.trackCompletion.createDelegate(this); | ||
440 | } | ||
441 | |||
442 | YAHOO.ext.Animator.CompositeSequence.prototype = { | ||
443 | add : function(sequence){ | ||
444 | this.sequences.push(sequence); | ||
445 | }, | ||
446 | |||
447 | play : function(onComplete){ | ||
448 | this.completed = 0; | ||
449 | if(this.sequences.length < 1){ | ||
450 | if(onComplete)onComplete(); | ||
451 | return; | ||
452 | } | ||
453 | this.onComplete = onComplete; | ||
454 | for(var i = 0; i < this.sequences.length; i++){ | ||
455 | this.sequences[i].play(this.trackDelegate); | ||
456 | } | ||
457 | }, | ||
458 | |||
459 | trackCompletion : function(){ | ||
460 | ++this.completed; | ||
461 | if(this.completed >= this.sequences.length && this.onComplete){ | ||
462 | this.onComplete(); | ||
463 | } | ||
464 | }, | ||
465 | |||
466 | stop : function(){ | ||
467 | for(var i = 0; i < this.sequences.length; i++){ | ||
468 | this.sequences[i].stop(); | ||
469 | } | ||
470 | }, | ||
471 | |||
472 | isPlaying : function(){ | ||
473 | for(var i = 0; i < this.sequences.length; i++){ | ||
474 | if(this.sequences[i].isPlaying()){ | ||
475 | return true; | ||
476 | } | ||
477 | } | ||
478 | return false; | ||
479 | } | ||
480 | }; | ||
481 | |||
482 | |||