0
|
1 /*
|
|
2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
|
3 Code licensed under the BSD License:
|
|
4 http://developer.yahoo.net/yui/license.txt
|
|
5 version: 2.8.0r4
|
|
6 */
|
|
7 (function() {
|
|
8
|
|
9 var Y = YAHOO.util;
|
|
10
|
|
11 /*
|
|
12 Copyright (c) 2006, Yahoo! Inc. All rights reserved.
|
|
13 Code licensed under the BSD License:
|
|
14 http://developer.yahoo.net/yui/license.txt
|
|
15 */
|
|
16
|
|
17 /**
|
|
18 * The animation module provides allows effects to be added to HTMLElements.
|
|
19 * @module animation
|
|
20 * @requires yahoo, event, dom
|
|
21 */
|
|
22
|
|
23 /**
|
|
24 *
|
|
25 * Base animation class that provides the interface for building animated effects.
|
|
26 * <p>Usage: var myAnim = new YAHOO.util.Anim(el, { width: { from: 10, to: 100 } }, 1, YAHOO.util.Easing.easeOut);</p>
|
|
27 * @class Anim
|
|
28 * @namespace YAHOO.util
|
|
29 * @requires YAHOO.util.AnimMgr
|
|
30 * @requires YAHOO.util.Easing
|
|
31 * @requires YAHOO.util.Dom
|
|
32 * @requires YAHOO.util.Event
|
|
33 * @requires YAHOO.util.CustomEvent
|
|
34 * @constructor
|
|
35 * @param {String | HTMLElement} el Reference to the element that will be animated
|
|
36 * @param {Object} attributes The attribute(s) to be animated.
|
|
37 * Each attribute is an object with at minimum a "to" or "by" member defined.
|
|
38 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
|
|
39 * All attribute names use camelCase.
|
|
40 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
|
|
41 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
|
|
42 */
|
|
43
|
|
44 var Anim = function(el, attributes, duration, method) {
|
|
45 if (!el) {
|
|
46 }
|
|
47 this.init(el, attributes, duration, method);
|
|
48 };
|
|
49
|
|
50 Anim.NAME = 'Anim';
|
|
51
|
|
52 Anim.prototype = {
|
|
53 /**
|
|
54 * Provides a readable name for the Anim instance.
|
|
55 * @method toString
|
|
56 * @return {String}
|
|
57 */
|
|
58 toString: function() {
|
|
59 var el = this.getEl() || {};
|
|
60 var id = el.id || el.tagName;
|
|
61 return (this.constructor.NAME + ': ' + id);
|
|
62 },
|
|
63
|
|
64 patterns: { // cached for performance
|
|
65 noNegatives: /width|height|opacity|padding/i, // keep at zero or above
|
|
66 offsetAttribute: /^((width|height)|(top|left))$/, // use offsetValue as default
|
|
67 defaultUnit: /width|height|top$|bottom$|left$|right$/i, // use 'px' by default
|
|
68 offsetUnit: /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i // IE may return these, so convert these to offset
|
|
69 },
|
|
70
|
|
71 /**
|
|
72 * Returns the value computed by the animation's "method".
|
|
73 * @method doMethod
|
|
74 * @param {String} attr The name of the attribute.
|
|
75 * @param {Number} start The value this attribute should start from for this animation.
|
|
76 * @param {Number} end The value this attribute should end at for this animation.
|
|
77 * @return {Number} The Value to be applied to the attribute.
|
|
78 */
|
|
79 doMethod: function(attr, start, end) {
|
|
80 return this.method(this.currentFrame, start, end - start, this.totalFrames);
|
|
81 },
|
|
82
|
|
83 /**
|
|
84 * Applies a value to an attribute.
|
|
85 * @method setAttribute
|
|
86 * @param {String} attr The name of the attribute.
|
|
87 * @param {Number} val The value to be applied to the attribute.
|
|
88 * @param {String} unit The unit ('px', '%', etc.) of the value.
|
|
89 */
|
|
90 setAttribute: function(attr, val, unit) {
|
|
91 var el = this.getEl();
|
|
92 if ( this.patterns.noNegatives.test(attr) ) {
|
|
93 val = (val > 0) ? val : 0;
|
|
94 }
|
|
95
|
|
96 if (attr in el && !('style' in el && attr in el.style)) {
|
|
97 el[attr] = val;
|
|
98 } else {
|
|
99 Y.Dom.setStyle(el, attr, val + unit);
|
|
100 }
|
|
101 },
|
|
102
|
|
103 /**
|
|
104 * Returns current value of the attribute.
|
|
105 * @method getAttribute
|
|
106 * @param {String} attr The name of the attribute.
|
|
107 * @return {Number} val The current value of the attribute.
|
|
108 */
|
|
109 getAttribute: function(attr) {
|
|
110 var el = this.getEl();
|
|
111 var val = Y.Dom.getStyle(el, attr);
|
|
112
|
|
113 if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
|
|
114 return parseFloat(val);
|
|
115 }
|
|
116
|
|
117 var a = this.patterns.offsetAttribute.exec(attr) || [];
|
|
118 var pos = !!( a[3] ); // top or left
|
|
119 var box = !!( a[2] ); // width or height
|
|
120
|
|
121 if ('style' in el) {
|
|
122 // use offsets for width/height and abs pos top/left
|
|
123 if ( box || (Y.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
|
|
124 val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
|
|
125 } else { // default to zero for other 'auto'
|
|
126 val = 0;
|
|
127 }
|
|
128 } else if (attr in el) {
|
|
129 val = el[attr];
|
|
130 }
|
|
131
|
|
132 return val;
|
|
133 },
|
|
134
|
|
135 /**
|
|
136 * Returns the unit to use when none is supplied.
|
|
137 * @method getDefaultUnit
|
|
138 * @param {attr} attr The name of the attribute.
|
|
139 * @return {String} The default unit to be used.
|
|
140 */
|
|
141 getDefaultUnit: function(attr) {
|
|
142 if ( this.patterns.defaultUnit.test(attr) ) {
|
|
143 return 'px';
|
|
144 }
|
|
145
|
|
146 return '';
|
|
147 },
|
|
148
|
|
149 /**
|
|
150 * Sets the actual values to be used during the animation. Should only be needed for subclass use.
|
|
151 * @method setRuntimeAttribute
|
|
152 * @param {Object} attr The attribute object
|
|
153 * @private
|
|
154 */
|
|
155 setRuntimeAttribute: function(attr) {
|
|
156 var start;
|
|
157 var end;
|
|
158 var attributes = this.attributes;
|
|
159
|
|
160 this.runtimeAttributes[attr] = {};
|
|
161
|
|
162 var isset = function(prop) {
|
|
163 return (typeof prop !== 'undefined');
|
|
164 };
|
|
165
|
|
166 if ( !isset(attributes[attr]['to']) && !isset(attributes[attr]['by']) ) {
|
|
167 return false; // note return; nothing to animate to
|
|
168 }
|
|
169
|
|
170 start = ( isset(attributes[attr]['from']) ) ? attributes[attr]['from'] : this.getAttribute(attr);
|
|
171
|
|
172 // To beats by, per SMIL 2.1 spec
|
|
173 if ( isset(attributes[attr]['to']) ) {
|
|
174 end = attributes[attr]['to'];
|
|
175 } else if ( isset(attributes[attr]['by']) ) {
|
|
176 if (start.constructor == Array) {
|
|
177 end = [];
|
|
178 for (var i = 0, len = start.length; i < len; ++i) {
|
|
179 end[i] = start[i] + attributes[attr]['by'][i] * 1; // times 1 to cast "by"
|
|
180 }
|
|
181 } else {
|
|
182 end = start + attributes[attr]['by'] * 1;
|
|
183 }
|
|
184 }
|
|
185
|
|
186 this.runtimeAttributes[attr].start = start;
|
|
187 this.runtimeAttributes[attr].end = end;
|
|
188
|
|
189 // set units if needed
|
|
190 this.runtimeAttributes[attr].unit = ( isset(attributes[attr].unit) ) ?
|
|
191 attributes[attr]['unit'] : this.getDefaultUnit(attr);
|
|
192 return true;
|
|
193 },
|
|
194
|
|
195 /**
|
|
196 * Constructor for Anim instance.
|
|
197 * @method init
|
|
198 * @param {String | HTMLElement} el Reference to the element that will be animated
|
|
199 * @param {Object} attributes The attribute(s) to be animated.
|
|
200 * Each attribute is an object with at minimum a "to" or "by" member defined.
|
|
201 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
|
|
202 * All attribute names use camelCase.
|
|
203 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
|
|
204 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
|
|
205 */
|
|
206 init: function(el, attributes, duration, method) {
|
|
207 /**
|
|
208 * Whether or not the animation is running.
|
|
209 * @property isAnimated
|
|
210 * @private
|
|
211 * @type Boolean
|
|
212 */
|
|
213 var isAnimated = false;
|
|
214
|
|
215 /**
|
|
216 * A Date object that is created when the animation begins.
|
|
217 * @property startTime
|
|
218 * @private
|
|
219 * @type Date
|
|
220 */
|
|
221 var startTime = null;
|
|
222
|
|
223 /**
|
|
224 * The number of frames this animation was able to execute.
|
|
225 * @property actualFrames
|
|
226 * @private
|
|
227 * @type Int
|
|
228 */
|
|
229 var actualFrames = 0;
|
|
230
|
|
231 /**
|
|
232 * The element to be animated.
|
|
233 * @property el
|
|
234 * @private
|
|
235 * @type HTMLElement
|
|
236 */
|
|
237 el = Y.Dom.get(el);
|
|
238
|
|
239 /**
|
|
240 * The collection of attributes to be animated.
|
|
241 * Each attribute must have at least a "to" or "by" defined in order to animate.
|
|
242 * If "to" is supplied, the animation will end with the attribute at that value.
|
|
243 * If "by" is supplied, the animation will end at that value plus its starting value.
|
|
244 * If both are supplied, "to" is used, and "by" is ignored.
|
|
245 * Optional additional member include "from" (the value the attribute should start animating from, defaults to current value), and "unit" (the units to apply to the values).
|
|
246 * @property attributes
|
|
247 * @type Object
|
|
248 */
|
|
249 this.attributes = attributes || {};
|
|
250
|
|
251 /**
|
|
252 * The length of the animation. Defaults to "1" (second).
|
|
253 * @property duration
|
|
254 * @type Number
|
|
255 */
|
|
256 this.duration = !YAHOO.lang.isUndefined(duration) ? duration : 1;
|
|
257
|
|
258 /**
|
|
259 * The method that will provide values to the attribute(s) during the animation.
|
|
260 * Defaults to "YAHOO.util.Easing.easeNone".
|
|
261 * @property method
|
|
262 * @type Function
|
|
263 */
|
|
264 this.method = method || Y.Easing.easeNone;
|
|
265
|
|
266 /**
|
|
267 * Whether or not the duration should be treated as seconds.
|
|
268 * Defaults to true.
|
|
269 * @property useSeconds
|
|
270 * @type Boolean
|
|
271 */
|
|
272 this.useSeconds = true; // default to seconds
|
|
273
|
|
274 /**
|
|
275 * The location of the current animation on the timeline.
|
|
276 * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
|
|
277 * @property currentFrame
|
|
278 * @type Int
|
|
279 */
|
|
280 this.currentFrame = 0;
|
|
281
|
|
282 /**
|
|
283 * The total number of frames to be executed.
|
|
284 * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
|
|
285 * @property totalFrames
|
|
286 * @type Int
|
|
287 */
|
|
288 this.totalFrames = Y.AnimMgr.fps;
|
|
289
|
|
290 /**
|
|
291 * Changes the animated element
|
|
292 * @method setEl
|
|
293 */
|
|
294 this.setEl = function(element) {
|
|
295 el = Y.Dom.get(element);
|
|
296 };
|
|
297
|
|
298 /**
|
|
299 * Returns a reference to the animated element.
|
|
300 * @method getEl
|
|
301 * @return {HTMLElement}
|
|
302 */
|
|
303 this.getEl = function() { return el; };
|
|
304
|
|
305 /**
|
|
306 * Checks whether the element is currently animated.
|
|
307 * @method isAnimated
|
|
308 * @return {Boolean} current value of isAnimated.
|
|
309 */
|
|
310 this.isAnimated = function() {
|
|
311 return isAnimated;
|
|
312 };
|
|
313
|
|
314 /**
|
|
315 * Returns the animation start time.
|
|
316 * @method getStartTime
|
|
317 * @return {Date} current value of startTime.
|
|
318 */
|
|
319 this.getStartTime = function() {
|
|
320 return startTime;
|
|
321 };
|
|
322
|
|
323 this.runtimeAttributes = {};
|
|
324
|
|
325
|
|
326
|
|
327 /**
|
|
328 * Starts the animation by registering it with the animation manager.
|
|
329 * @method animate
|
|
330 */
|
|
331 this.animate = function() {
|
|
332 if ( this.isAnimated() ) {
|
|
333 return false;
|
|
334 }
|
|
335
|
|
336 this.currentFrame = 0;
|
|
337
|
|
338 this.totalFrames = ( this.useSeconds ) ? Math.ceil(Y.AnimMgr.fps * this.duration) : this.duration;
|
|
339
|
|
340 if (this.duration === 0 && this.useSeconds) { // jump to last frame if zero second duration
|
|
341 this.totalFrames = 1;
|
|
342 }
|
|
343 Y.AnimMgr.registerElement(this);
|
|
344 return true;
|
|
345 };
|
|
346
|
|
347 /**
|
|
348 * Stops the animation. Normally called by AnimMgr when animation completes.
|
|
349 * @method stop
|
|
350 * @param {Boolean} finish (optional) If true, animation will jump to final frame.
|
|
351 */
|
|
352 this.stop = function(finish) {
|
|
353 if (!this.isAnimated()) { // nothing to stop
|
|
354 return false;
|
|
355 }
|
|
356
|
|
357 if (finish) {
|
|
358 this.currentFrame = this.totalFrames;
|
|
359 this._onTween.fire();
|
|
360 }
|
|
361 Y.AnimMgr.stop(this);
|
|
362 };
|
|
363
|
|
364 var onStart = function() {
|
|
365 this.onStart.fire();
|
|
366
|
|
367 this.runtimeAttributes = {};
|
|
368 for (var attr in this.attributes) {
|
|
369 this.setRuntimeAttribute(attr);
|
|
370 }
|
|
371
|
|
372 isAnimated = true;
|
|
373 actualFrames = 0;
|
|
374 startTime = new Date();
|
|
375 };
|
|
376
|
|
377 /**
|
|
378 * Feeds the starting and ending values for each animated attribute to doMethod once per frame, then applies the resulting value to the attribute(s).
|
|
379 * @private
|
|
380 */
|
|
381
|
|
382 var onTween = function() {
|
|
383 var data = {
|
|
384 duration: new Date() - this.getStartTime(),
|
|
385 currentFrame: this.currentFrame
|
|
386 };
|
|
387
|
|
388 data.toString = function() {
|
|
389 return (
|
|
390 'duration: ' + data.duration +
|
|
391 ', currentFrame: ' + data.currentFrame
|
|
392 );
|
|
393 };
|
|
394
|
|
395 this.onTween.fire(data);
|
|
396
|
|
397 var runtimeAttributes = this.runtimeAttributes;
|
|
398
|
|
399 for (var attr in runtimeAttributes) {
|
|
400 this.setAttribute(attr, this.doMethod(attr, runtimeAttributes[attr].start, runtimeAttributes[attr].end), runtimeAttributes[attr].unit);
|
|
401 }
|
|
402
|
|
403 actualFrames += 1;
|
|
404 };
|
|
405
|
|
406 var onComplete = function() {
|
|
407 var actual_duration = (new Date() - startTime) / 1000 ;
|
|
408
|
|
409 var data = {
|
|
410 duration: actual_duration,
|
|
411 frames: actualFrames,
|
|
412 fps: actualFrames / actual_duration
|
|
413 };
|
|
414
|
|
415 data.toString = function() {
|
|
416 return (
|
|
417 'duration: ' + data.duration +
|
|
418 ', frames: ' + data.frames +
|
|
419 ', fps: ' + data.fps
|
|
420 );
|
|
421 };
|
|
422
|
|
423 isAnimated = false;
|
|
424 actualFrames = 0;
|
|
425 this.onComplete.fire(data);
|
|
426 };
|
|
427
|
|
428 /**
|
|
429 * Custom event that fires after onStart, useful in subclassing
|
|
430 * @private
|
|
431 */
|
|
432 this._onStart = new Y.CustomEvent('_start', this, true);
|
|
433
|
|
434 /**
|
|
435 * Custom event that fires when animation begins
|
|
436 * Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)
|
|
437 * @event onStart
|
|
438 */
|
|
439 this.onStart = new Y.CustomEvent('start', this);
|
|
440
|
|
441 /**
|
|
442 * Custom event that fires between each frame
|
|
443 * Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)
|
|
444 * @event onTween
|
|
445 */
|
|
446 this.onTween = new Y.CustomEvent('tween', this);
|
|
447
|
|
448 /**
|
|
449 * Custom event that fires after onTween
|
|
450 * @private
|
|
451 */
|
|
452 this._onTween = new Y.CustomEvent('_tween', this, true);
|
|
453
|
|
454 /**
|
|
455 * Custom event that fires when animation ends
|
|
456 * Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)
|
|
457 * @event onComplete
|
|
458 */
|
|
459 this.onComplete = new Y.CustomEvent('complete', this);
|
|
460 /**
|
|
461 * Custom event that fires after onComplete
|
|
462 * @private
|
|
463 */
|
|
464 this._onComplete = new Y.CustomEvent('_complete', this, true);
|
|
465
|
|
466 this._onStart.subscribe(onStart);
|
|
467 this._onTween.subscribe(onTween);
|
|
468 this._onComplete.subscribe(onComplete);
|
|
469 }
|
|
470 };
|
|
471
|
|
472 Y.Anim = Anim;
|
|
473 })();
|
|
474 /**
|
|
475 * Handles animation queueing and threading.
|
|
476 * Used by Anim and subclasses.
|
|
477 * @class AnimMgr
|
|
478 * @namespace YAHOO.util
|
|
479 */
|
|
480 YAHOO.util.AnimMgr = new function() {
|
|
481 /**
|
|
482 * Reference to the animation Interval.
|
|
483 * @property thread
|
|
484 * @private
|
|
485 * @type Int
|
|
486 */
|
|
487 var thread = null;
|
|
488
|
|
489 /**
|
|
490 * The current queue of registered animation objects.
|
|
491 * @property queue
|
|
492 * @private
|
|
493 * @type Array
|
|
494 */
|
|
495 var queue = [];
|
|
496
|
|
497 /**
|
|
498 * The number of active animations.
|
|
499 * @property tweenCount
|
|
500 * @private
|
|
501 * @type Int
|
|
502 */
|
|
503 var tweenCount = 0;
|
|
504
|
|
505 /**
|
|
506 * Base frame rate (frames per second).
|
|
507 * Arbitrarily high for better x-browser calibration (slower browsers drop more frames).
|
|
508 * @property fps
|
|
509 * @type Int
|
|
510 *
|
|
511 */
|
|
512 this.fps = 1000;
|
|
513
|
|
514 /**
|
|
515 * Interval delay in milliseconds, defaults to fastest possible.
|
|
516 * @property delay
|
|
517 * @type Int
|
|
518 *
|
|
519 */
|
|
520 this.delay = 1;
|
|
521
|
|
522 /**
|
|
523 * Adds an animation instance to the animation queue.
|
|
524 * All animation instances must be registered in order to animate.
|
|
525 * @method registerElement
|
|
526 * @param {object} tween The Anim instance to be be registered
|
|
527 */
|
|
528 this.registerElement = function(tween) {
|
|
529 queue[queue.length] = tween;
|
|
530 tweenCount += 1;
|
|
531 tween._onStart.fire();
|
|
532 this.start();
|
|
533 };
|
|
534
|
|
535 /**
|
|
536 * removes an animation instance from the animation queue.
|
|
537 * All animation instances must be registered in order to animate.
|
|
538 * @method unRegister
|
|
539 * @param {object} tween The Anim instance to be be registered
|
|
540 * @param {Int} index The index of the Anim instance
|
|
541 * @private
|
|
542 */
|
|
543 this.unRegister = function(tween, index) {
|
|
544 index = index || getIndex(tween);
|
|
545 if (!tween.isAnimated() || index === -1) {
|
|
546 return false;
|
|
547 }
|
|
548
|
|
549 tween._onComplete.fire();
|
|
550 queue.splice(index, 1);
|
|
551
|
|
552 tweenCount -= 1;
|
|
553 if (tweenCount <= 0) {
|
|
554 this.stop();
|
|
555 }
|
|
556
|
|
557 return true;
|
|
558 };
|
|
559
|
|
560 /**
|
|
561 * Starts the animation thread.
|
|
562 * Only one thread can run at a time.
|
|
563 * @method start
|
|
564 */
|
|
565 this.start = function() {
|
|
566 if (thread === null) {
|
|
567 thread = setInterval(this.run, this.delay);
|
|
568 }
|
|
569 };
|
|
570
|
|
571 /**
|
|
572 * Stops the animation thread or a specific animation instance.
|
|
573 * @method stop
|
|
574 * @param {object} tween A specific Anim instance to stop (optional)
|
|
575 * If no instance given, Manager stops thread and all animations.
|
|
576 */
|
|
577 this.stop = function(tween) {
|
|
578 if (!tween) {
|
|
579 clearInterval(thread);
|
|
580
|
|
581 for (var i = 0, len = queue.length; i < len; ++i) {
|
|
582 this.unRegister(queue[0], 0);
|
|
583 }
|
|
584
|
|
585 queue = [];
|
|
586 thread = null;
|
|
587 tweenCount = 0;
|
|
588 }
|
|
589 else {
|
|
590 this.unRegister(tween);
|
|
591 }
|
|
592 };
|
|
593
|
|
594 /**
|
|
595 * Called per Interval to handle each animation frame.
|
|
596 * @method run
|
|
597 */
|
|
598 this.run = function() {
|
|
599 for (var i = 0, len = queue.length; i < len; ++i) {
|
|
600 var tween = queue[i];
|
|
601 if ( !tween || !tween.isAnimated() ) { continue; }
|
|
602
|
|
603 if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
|
|
604 {
|
|
605 tween.currentFrame += 1;
|
|
606
|
|
607 if (tween.useSeconds) {
|
|
608 correctFrame(tween);
|
|
609 }
|
|
610 tween._onTween.fire();
|
|
611 }
|
|
612 else { YAHOO.util.AnimMgr.stop(tween, i); }
|
|
613 }
|
|
614 };
|
|
615
|
|
616 var getIndex = function(anim) {
|
|
617 for (var i = 0, len = queue.length; i < len; ++i) {
|
|
618 if (queue[i] === anim) {
|
|
619 return i; // note return;
|
|
620 }
|
|
621 }
|
|
622 return -1;
|
|
623 };
|
|
624
|
|
625 /**
|
|
626 * On the fly frame correction to keep animation on time.
|
|
627 * @method correctFrame
|
|
628 * @private
|
|
629 * @param {Object} tween The Anim instance being corrected.
|
|
630 */
|
|
631 var correctFrame = function(tween) {
|
|
632 var frames = tween.totalFrames;
|
|
633 var frame = tween.currentFrame;
|
|
634 var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
|
|
635 var elapsed = (new Date() - tween.getStartTime());
|
|
636 var tweak = 0;
|
|
637
|
|
638 if (elapsed < tween.duration * 1000) { // check if falling behind
|
|
639 tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
|
|
640 } else { // went over duration, so jump to end
|
|
641 tweak = frames - (frame + 1);
|
|
642 }
|
|
643 if (tweak > 0 && isFinite(tweak)) { // adjust if needed
|
|
644 if (tween.currentFrame + tweak >= frames) {// dont go past last frame
|
|
645 tweak = frames - (frame + 1);
|
|
646 }
|
|
647
|
|
648 tween.currentFrame += tweak;
|
|
649 }
|
|
650 };
|
|
651 this._queue = queue;
|
|
652 this._getIndex = getIndex;
|
|
653 };
|
|
654 /**
|
|
655 * Used to calculate Bezier splines for any number of control points.
|
|
656 * @class Bezier
|
|
657 * @namespace YAHOO.util
|
|
658 *
|
|
659 */
|
|
660 YAHOO.util.Bezier = new function() {
|
|
661 /**
|
|
662 * Get the current position of the animated element based on t.
|
|
663 * Each point is an array of "x" and "y" values (0 = x, 1 = y)
|
|
664 * At least 2 points are required (start and end).
|
|
665 * First point is start. Last point is end.
|
|
666 * Additional control points are optional.
|
|
667 * @method getPosition
|
|
668 * @param {Array} points An array containing Bezier points
|
|
669 * @param {Number} t A number between 0 and 1 which is the basis for determining current position
|
|
670 * @return {Array} An array containing int x and y member data
|
|
671 */
|
|
672 this.getPosition = function(points, t) {
|
|
673 var n = points.length;
|
|
674 var tmp = [];
|
|
675
|
|
676 for (var i = 0; i < n; ++i){
|
|
677 tmp[i] = [points[i][0], points[i][1]]; // save input
|
|
678 }
|
|
679
|
|
680 for (var j = 1; j < n; ++j) {
|
|
681 for (i = 0; i < n - j; ++i) {
|
|
682 tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
|
|
683 tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
|
|
684 }
|
|
685 }
|
|
686
|
|
687 return [ tmp[0][0], tmp[0][1] ];
|
|
688
|
|
689 };
|
|
690 };
|
|
691 (function() {
|
|
692 /**
|
|
693 * Anim subclass for color transitions.
|
|
694 * <p>Usage: <code>var myAnim = new Y.ColorAnim(el, { backgroundColor: { from: '#FF0000', to: '#FFFFFF' } }, 1, Y.Easing.easeOut);</code> Color values can be specified with either 112233, #112233,
|
|
695 * [255,255,255], or rgb(255,255,255)</p>
|
|
696 * @class ColorAnim
|
|
697 * @namespace YAHOO.util
|
|
698 * @requires YAHOO.util.Anim
|
|
699 * @requires YAHOO.util.AnimMgr
|
|
700 * @requires YAHOO.util.Easing
|
|
701 * @requires YAHOO.util.Bezier
|
|
702 * @requires YAHOO.util.Dom
|
|
703 * @requires YAHOO.util.Event
|
|
704 * @constructor
|
|
705 * @extends YAHOO.util.Anim
|
|
706 * @param {HTMLElement | String} el Reference to the element that will be animated
|
|
707 * @param {Object} attributes The attribute(s) to be animated.
|
|
708 * Each attribute is an object with at minimum a "to" or "by" member defined.
|
|
709 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
|
|
710 * All attribute names use camelCase.
|
|
711 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
|
|
712 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
|
|
713 */
|
|
714 var ColorAnim = function(el, attributes, duration, method) {
|
|
715 ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
|
|
716 };
|
|
717
|
|
718 ColorAnim.NAME = 'ColorAnim';
|
|
719
|
|
720 ColorAnim.DEFAULT_BGCOLOR = '#fff';
|
|
721 // shorthand
|
|
722 var Y = YAHOO.util;
|
|
723 YAHOO.extend(ColorAnim, Y.Anim);
|
|
724
|
|
725 var superclass = ColorAnim.superclass;
|
|
726 var proto = ColorAnim.prototype;
|
|
727
|
|
728 proto.patterns.color = /color$/i;
|
|
729 proto.patterns.rgb = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
|
|
730 proto.patterns.hex = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
|
|
731 proto.patterns.hex3 = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;
|
|
732 proto.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/; // need rgba for safari
|
|
733
|
|
734 /**
|
|
735 * Attempts to parse the given string and return a 3-tuple.
|
|
736 * @method parseColor
|
|
737 * @param {String} s The string to parse.
|
|
738 * @return {Array} The 3-tuple of rgb values.
|
|
739 */
|
|
740 proto.parseColor = function(s) {
|
|
741 if (s.length == 3) { return s; }
|
|
742
|
|
743 var c = this.patterns.hex.exec(s);
|
|
744 if (c && c.length == 4) {
|
|
745 return [ parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16) ];
|
|
746 }
|
|
747
|
|
748 c = this.patterns.rgb.exec(s);
|
|
749 if (c && c.length == 4) {
|
|
750 return [ parseInt(c[1], 10), parseInt(c[2], 10), parseInt(c[3], 10) ];
|
|
751 }
|
|
752
|
|
753 c = this.patterns.hex3.exec(s);
|
|
754 if (c && c.length == 4) {
|
|
755 return [ parseInt(c[1] + c[1], 16), parseInt(c[2] + c[2], 16), parseInt(c[3] + c[3], 16) ];
|
|
756 }
|
|
757
|
|
758 return null;
|
|
759 };
|
|
760
|
|
761 proto.getAttribute = function(attr) {
|
|
762 var el = this.getEl();
|
|
763 if (this.patterns.color.test(attr) ) {
|
|
764 var val = YAHOO.util.Dom.getStyle(el, attr);
|
|
765
|
|
766 var that = this;
|
|
767 if (this.patterns.transparent.test(val)) { // bgcolor default
|
|
768 var parent = YAHOO.util.Dom.getAncestorBy(el, function(node) {
|
|
769 return !that.patterns.transparent.test(val);
|
|
770 });
|
|
771
|
|
772 if (parent) {
|
|
773 val = Y.Dom.getStyle(parent, attr);
|
|
774 } else {
|
|
775 val = ColorAnim.DEFAULT_BGCOLOR;
|
|
776 }
|
|
777 }
|
|
778 } else {
|
|
779 val = superclass.getAttribute.call(this, attr);
|
|
780 }
|
|
781
|
|
782 return val;
|
|
783 };
|
|
784
|
|
785 proto.doMethod = function(attr, start, end) {
|
|
786 var val;
|
|
787
|
|
788 if ( this.patterns.color.test(attr) ) {
|
|
789 val = [];
|
|
790 for (var i = 0, len = start.length; i < len; ++i) {
|
|
791 val[i] = superclass.doMethod.call(this, attr, start[i], end[i]);
|
|
792 }
|
|
793
|
|
794 val = 'rgb('+Math.floor(val[0])+','+Math.floor(val[1])+','+Math.floor(val[2])+')';
|
|
795 }
|
|
796 else {
|
|
797 val = superclass.doMethod.call(this, attr, start, end);
|
|
798 }
|
|
799
|
|
800 return val;
|
|
801 };
|
|
802
|
|
803 proto.setRuntimeAttribute = function(attr) {
|
|
804 superclass.setRuntimeAttribute.call(this, attr);
|
|
805
|
|
806 if ( this.patterns.color.test(attr) ) {
|
|
807 var attributes = this.attributes;
|
|
808 var start = this.parseColor(this.runtimeAttributes[attr].start);
|
|
809 var end = this.parseColor(this.runtimeAttributes[attr].end);
|
|
810 // fix colors if going "by"
|
|
811 if ( typeof attributes[attr]['to'] === 'undefined' && typeof attributes[attr]['by'] !== 'undefined' ) {
|
|
812 end = this.parseColor(attributes[attr].by);
|
|
813
|
|
814 for (var i = 0, len = start.length; i < len; ++i) {
|
|
815 end[i] = start[i] + end[i];
|
|
816 }
|
|
817 }
|
|
818
|
|
819 this.runtimeAttributes[attr].start = start;
|
|
820 this.runtimeAttributes[attr].end = end;
|
|
821 }
|
|
822 };
|
|
823
|
|
824 Y.ColorAnim = ColorAnim;
|
|
825 })();
|
|
826 /*!
|
|
827 TERMS OF USE - EASING EQUATIONS
|
|
828 Open source under the BSD License.
|
|
829 Copyright 2001 Robert Penner All rights reserved.
|
|
830
|
|
831 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
832
|
|
833 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
834 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
835 * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
836
|
|
837 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
838 */
|
|
839
|
|
840 /**
|
|
841 * Singleton that determines how an animation proceeds from start to end.
|
|
842 * @class Easing
|
|
843 * @namespace YAHOO.util
|
|
844 */
|
|
845
|
|
846 YAHOO.util.Easing = {
|
|
847
|
|
848 /**
|
|
849 * Uniform speed between points.
|
|
850 * @method easeNone
|
|
851 * @param {Number} t Time value used to compute current value
|
|
852 * @param {Number} b Starting value
|
|
853 * @param {Number} c Delta between start and end values
|
|
854 * @param {Number} d Total length of animation
|
|
855 * @return {Number} The computed value for the current animation frame
|
|
856 */
|
|
857 easeNone: function (t, b, c, d) {
|
|
858 return c*t/d + b;
|
|
859 },
|
|
860
|
|
861 /**
|
|
862 * Begins slowly and accelerates towards end.
|
|
863 * @method easeIn
|
|
864 * @param {Number} t Time value used to compute current value
|
|
865 * @param {Number} b Starting value
|
|
866 * @param {Number} c Delta between start and end values
|
|
867 * @param {Number} d Total length of animation
|
|
868 * @return {Number} The computed value for the current animation frame
|
|
869 */
|
|
870 easeIn: function (t, b, c, d) {
|
|
871 return c*(t/=d)*t + b;
|
|
872 },
|
|
873
|
|
874 /**
|
|
875 * Begins quickly and decelerates towards end.
|
|
876 * @method easeOut
|
|
877 * @param {Number} t Time value used to compute current value
|
|
878 * @param {Number} b Starting value
|
|
879 * @param {Number} c Delta between start and end values
|
|
880 * @param {Number} d Total length of animation
|
|
881 * @return {Number} The computed value for the current animation frame
|
|
882 */
|
|
883 easeOut: function (t, b, c, d) {
|
|
884 return -c *(t/=d)*(t-2) + b;
|
|
885 },
|
|
886
|
|
887 /**
|
|
888 * Begins slowly and decelerates towards end.
|
|
889 * @method easeBoth
|
|
890 * @param {Number} t Time value used to compute current value
|
|
891 * @param {Number} b Starting value
|
|
892 * @param {Number} c Delta between start and end values
|
|
893 * @param {Number} d Total length of animation
|
|
894 * @return {Number} The computed value for the current animation frame
|
|
895 */
|
|
896 easeBoth: function (t, b, c, d) {
|
|
897 if ((t/=d/2) < 1) {
|
|
898 return c/2*t*t + b;
|
|
899 }
|
|
900
|
|
901 return -c/2 * ((--t)*(t-2) - 1) + b;
|
|
902 },
|
|
903
|
|
904 /**
|
|
905 * Begins slowly and accelerates towards end.
|
|
906 * @method easeInStrong
|
|
907 * @param {Number} t Time value used to compute current value
|
|
908 * @param {Number} b Starting value
|
|
909 * @param {Number} c Delta between start and end values
|
|
910 * @param {Number} d Total length of animation
|
|
911 * @return {Number} The computed value for the current animation frame
|
|
912 */
|
|
913 easeInStrong: function (t, b, c, d) {
|
|
914 return c*(t/=d)*t*t*t + b;
|
|
915 },
|
|
916
|
|
917 /**
|
|
918 * Begins quickly and decelerates towards end.
|
|
919 * @method easeOutStrong
|
|
920 * @param {Number} t Time value used to compute current value
|
|
921 * @param {Number} b Starting value
|
|
922 * @param {Number} c Delta between start and end values
|
|
923 * @param {Number} d Total length of animation
|
|
924 * @return {Number} The computed value for the current animation frame
|
|
925 */
|
|
926 easeOutStrong: function (t, b, c, d) {
|
|
927 return -c * ((t=t/d-1)*t*t*t - 1) + b;
|
|
928 },
|
|
929
|
|
930 /**
|
|
931 * Begins slowly and decelerates towards end.
|
|
932 * @method easeBothStrong
|
|
933 * @param {Number} t Time value used to compute current value
|
|
934 * @param {Number} b Starting value
|
|
935 * @param {Number} c Delta between start and end values
|
|
936 * @param {Number} d Total length of animation
|
|
937 * @return {Number} The computed value for the current animation frame
|
|
938 */
|
|
939 easeBothStrong: function (t, b, c, d) {
|
|
940 if ((t/=d/2) < 1) {
|
|
941 return c/2*t*t*t*t + b;
|
|
942 }
|
|
943
|
|
944 return -c/2 * ((t-=2)*t*t*t - 2) + b;
|
|
945 },
|
|
946
|
|
947 /**
|
|
948 * Snap in elastic effect.
|
|
949 * @method elasticIn
|
|
950 * @param {Number} t Time value used to compute current value
|
|
951 * @param {Number} b Starting value
|
|
952 * @param {Number} c Delta between start and end values
|
|
953 * @param {Number} d Total length of animation
|
|
954 * @param {Number} a Amplitude (optional)
|
|
955 * @param {Number} p Period (optional)
|
|
956 * @return {Number} The computed value for the current animation frame
|
|
957 */
|
|
958
|
|
959 elasticIn: function (t, b, c, d, a, p) {
|
|
960 if (t == 0) {
|
|
961 return b;
|
|
962 }
|
|
963 if ( (t /= d) == 1 ) {
|
|
964 return b+c;
|
|
965 }
|
|
966 if (!p) {
|
|
967 p=d*.3;
|
|
968 }
|
|
969
|
|
970 if (!a || a < Math.abs(c)) {
|
|
971 a = c;
|
|
972 var s = p/4;
|
|
973 }
|
|
974 else {
|
|
975 var s = p/(2*Math.PI) * Math.asin (c/a);
|
|
976 }
|
|
977
|
|
978 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
|
979 },
|
|
980
|
|
981 /**
|
|
982 * Snap out elastic effect.
|
|
983 * @method elasticOut
|
|
984 * @param {Number} t Time value used to compute current value
|
|
985 * @param {Number} b Starting value
|
|
986 * @param {Number} c Delta between start and end values
|
|
987 * @param {Number} d Total length of animation
|
|
988 * @param {Number} a Amplitude (optional)
|
|
989 * @param {Number} p Period (optional)
|
|
990 * @return {Number} The computed value for the current animation frame
|
|
991 */
|
|
992 elasticOut: function (t, b, c, d, a, p) {
|
|
993 if (t == 0) {
|
|
994 return b;
|
|
995 }
|
|
996 if ( (t /= d) == 1 ) {
|
|
997 return b+c;
|
|
998 }
|
|
999 if (!p) {
|
|
1000 p=d*.3;
|
|
1001 }
|
|
1002
|
|
1003 if (!a || a < Math.abs(c)) {
|
|
1004 a = c;
|
|
1005 var s = p / 4;
|
|
1006 }
|
|
1007 else {
|
|
1008 var s = p/(2*Math.PI) * Math.asin (c/a);
|
|
1009 }
|
|
1010
|
|
1011 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
|
|
1012 },
|
|
1013
|
|
1014 /**
|
|
1015 * Snap both elastic effect.
|
|
1016 * @method elasticBoth
|
|
1017 * @param {Number} t Time value used to compute current value
|
|
1018 * @param {Number} b Starting value
|
|
1019 * @param {Number} c Delta between start and end values
|
|
1020 * @param {Number} d Total length of animation
|
|
1021 * @param {Number} a Amplitude (optional)
|
|
1022 * @param {Number} p Period (optional)
|
|
1023 * @return {Number} The computed value for the current animation frame
|
|
1024 */
|
|
1025 elasticBoth: function (t, b, c, d, a, p) {
|
|
1026 if (t == 0) {
|
|
1027 return b;
|
|
1028 }
|
|
1029
|
|
1030 if ( (t /= d/2) == 2 ) {
|
|
1031 return b+c;
|
|
1032 }
|
|
1033
|
|
1034 if (!p) {
|
|
1035 p = d*(.3*1.5);
|
|
1036 }
|
|
1037
|
|
1038 if ( !a || a < Math.abs(c) ) {
|
|
1039 a = c;
|
|
1040 var s = p/4;
|
|
1041 }
|
|
1042 else {
|
|
1043 var s = p/(2*Math.PI) * Math.asin (c/a);
|
|
1044 }
|
|
1045
|
|
1046 if (t < 1) {
|
|
1047 return -.5*(a*Math.pow(2,10*(t-=1)) *
|
|
1048 Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
|
1049 }
|
|
1050 return a*Math.pow(2,-10*(t-=1)) *
|
|
1051 Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
|
|
1052 },
|
|
1053
|
|
1054
|
|
1055 /**
|
|
1056 * Backtracks slightly, then reverses direction and moves to end.
|
|
1057 * @method backIn
|
|
1058 * @param {Number} t Time value used to compute current value
|
|
1059 * @param {Number} b Starting value
|
|
1060 * @param {Number} c Delta between start and end values
|
|
1061 * @param {Number} d Total length of animation
|
|
1062 * @param {Number} s Overshoot (optional)
|
|
1063 * @return {Number} The computed value for the current animation frame
|
|
1064 */
|
|
1065 backIn: function (t, b, c, d, s) {
|
|
1066 if (typeof s == 'undefined') {
|
|
1067 s = 1.70158;
|
|
1068 }
|
|
1069 return c*(t/=d)*t*((s+1)*t - s) + b;
|
|
1070 },
|
|
1071
|
|
1072 /**
|
|
1073 * Overshoots end, then reverses and comes back to end.
|
|
1074 * @method backOut
|
|
1075 * @param {Number} t Time value used to compute current value
|
|
1076 * @param {Number} b Starting value
|
|
1077 * @param {Number} c Delta between start and end values
|
|
1078 * @param {Number} d Total length of animation
|
|
1079 * @param {Number} s Overshoot (optional)
|
|
1080 * @return {Number} The computed value for the current animation frame
|
|
1081 */
|
|
1082 backOut: function (t, b, c, d, s) {
|
|
1083 if (typeof s == 'undefined') {
|
|
1084 s = 1.70158;
|
|
1085 }
|
|
1086 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
|
|
1087 },
|
|
1088
|
|
1089 /**
|
|
1090 * Backtracks slightly, then reverses direction, overshoots end,
|
|
1091 * then reverses and comes back to end.
|
|
1092 * @method backBoth
|
|
1093 * @param {Number} t Time value used to compute current value
|
|
1094 * @param {Number} b Starting value
|
|
1095 * @param {Number} c Delta between start and end values
|
|
1096 * @param {Number} d Total length of animation
|
|
1097 * @param {Number} s Overshoot (optional)
|
|
1098 * @return {Number} The computed value for the current animation frame
|
|
1099 */
|
|
1100 backBoth: function (t, b, c, d, s) {
|
|
1101 if (typeof s == 'undefined') {
|
|
1102 s = 1.70158;
|
|
1103 }
|
|
1104
|
|
1105 if ((t /= d/2 ) < 1) {
|
|
1106 return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
|
|
1107 }
|
|
1108 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
|
|
1109 },
|
|
1110
|
|
1111 /**
|
|
1112 * Bounce off of start.
|
|
1113 * @method bounceIn
|
|
1114 * @param {Number} t Time value used to compute current value
|
|
1115 * @param {Number} b Starting value
|
|
1116 * @param {Number} c Delta between start and end values
|
|
1117 * @param {Number} d Total length of animation
|
|
1118 * @return {Number} The computed value for the current animation frame
|
|
1119 */
|
|
1120 bounceIn: function (t, b, c, d) {
|
|
1121 return c - YAHOO.util.Easing.bounceOut(d-t, 0, c, d) + b;
|
|
1122 },
|
|
1123
|
|
1124 /**
|
|
1125 * Bounces off end.
|
|
1126 * @method bounceOut
|
|
1127 * @param {Number} t Time value used to compute current value
|
|
1128 * @param {Number} b Starting value
|
|
1129 * @param {Number} c Delta between start and end values
|
|
1130 * @param {Number} d Total length of animation
|
|
1131 * @return {Number} The computed value for the current animation frame
|
|
1132 */
|
|
1133 bounceOut: function (t, b, c, d) {
|
|
1134 if ((t/=d) < (1/2.75)) {
|
|
1135 return c*(7.5625*t*t) + b;
|
|
1136 } else if (t < (2/2.75)) {
|
|
1137 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
|
|
1138 } else if (t < (2.5/2.75)) {
|
|
1139 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
|
|
1140 }
|
|
1141 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
|
|
1142 },
|
|
1143
|
|
1144 /**
|
|
1145 * Bounces off start and end.
|
|
1146 * @method bounceBoth
|
|
1147 * @param {Number} t Time value used to compute current value
|
|
1148 * @param {Number} b Starting value
|
|
1149 * @param {Number} c Delta between start and end values
|
|
1150 * @param {Number} d Total length of animation
|
|
1151 * @return {Number} The computed value for the current animation frame
|
|
1152 */
|
|
1153 bounceBoth: function (t, b, c, d) {
|
|
1154 if (t < d/2) {
|
|
1155 return YAHOO.util.Easing.bounceIn(t*2, 0, c, d) * .5 + b;
|
|
1156 }
|
|
1157 return YAHOO.util.Easing.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
|
|
1158 }
|
|
1159 };
|
|
1160
|
|
1161 (function() {
|
|
1162 /**
|
|
1163 * Anim subclass for moving elements along a path defined by the "points"
|
|
1164 * member of "attributes". All "points" are arrays with x, y coordinates.
|
|
1165 * <p>Usage: <code>var myAnim = new YAHOO.util.Motion(el, { points: { to: [800, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
|
|
1166 * @class Motion
|
|
1167 * @namespace YAHOO.util
|
|
1168 * @requires YAHOO.util.Anim
|
|
1169 * @requires YAHOO.util.AnimMgr
|
|
1170 * @requires YAHOO.util.Easing
|
|
1171 * @requires YAHOO.util.Bezier
|
|
1172 * @requires YAHOO.util.Dom
|
|
1173 * @requires YAHOO.util.Event
|
|
1174 * @requires YAHOO.util.CustomEvent
|
|
1175 * @constructor
|
|
1176 * @extends YAHOO.util.ColorAnim
|
|
1177 * @param {String | HTMLElement} el Reference to the element that will be animated
|
|
1178 * @param {Object} attributes The attribute(s) to be animated.
|
|
1179 * Each attribute is an object with at minimum a "to" or "by" member defined.
|
|
1180 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
|
|
1181 * All attribute names use camelCase.
|
|
1182 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
|
|
1183 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
|
|
1184 */
|
|
1185 var Motion = function(el, attributes, duration, method) {
|
|
1186 if (el) { // dont break existing subclasses not using YAHOO.extend
|
|
1187 Motion.superclass.constructor.call(this, el, attributes, duration, method);
|
|
1188 }
|
|
1189 };
|
|
1190
|
|
1191
|
|
1192 Motion.NAME = 'Motion';
|
|
1193
|
|
1194 // shorthand
|
|
1195 var Y = YAHOO.util;
|
|
1196 YAHOO.extend(Motion, Y.ColorAnim);
|
|
1197
|
|
1198 var superclass = Motion.superclass;
|
|
1199 var proto = Motion.prototype;
|
|
1200
|
|
1201 proto.patterns.points = /^points$/i;
|
|
1202
|
|
1203 proto.setAttribute = function(attr, val, unit) {
|
|
1204 if ( this.patterns.points.test(attr) ) {
|
|
1205 unit = unit || 'px';
|
|
1206 superclass.setAttribute.call(this, 'left', val[0], unit);
|
|
1207 superclass.setAttribute.call(this, 'top', val[1], unit);
|
|
1208 } else {
|
|
1209 superclass.setAttribute.call(this, attr, val, unit);
|
|
1210 }
|
|
1211 };
|
|
1212
|
|
1213 proto.getAttribute = function(attr) {
|
|
1214 if ( this.patterns.points.test(attr) ) {
|
|
1215 var val = [
|
|
1216 superclass.getAttribute.call(this, 'left'),
|
|
1217 superclass.getAttribute.call(this, 'top')
|
|
1218 ];
|
|
1219 } else {
|
|
1220 val = superclass.getAttribute.call(this, attr);
|
|
1221 }
|
|
1222
|
|
1223 return val;
|
|
1224 };
|
|
1225
|
|
1226 proto.doMethod = function(attr, start, end) {
|
|
1227 var val = null;
|
|
1228
|
|
1229 if ( this.patterns.points.test(attr) ) {
|
|
1230 var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;
|
|
1231 val = Y.Bezier.getPosition(this.runtimeAttributes[attr], t);
|
|
1232 } else {
|
|
1233 val = superclass.doMethod.call(this, attr, start, end);
|
|
1234 }
|
|
1235 return val;
|
|
1236 };
|
|
1237
|
|
1238 proto.setRuntimeAttribute = function(attr) {
|
|
1239 if ( this.patterns.points.test(attr) ) {
|
|
1240 var el = this.getEl();
|
|
1241 var attributes = this.attributes;
|
|
1242 var start;
|
|
1243 var control = attributes['points']['control'] || [];
|
|
1244 var end;
|
|
1245 var i, len;
|
|
1246
|
|
1247 if (control.length > 0 && !(control[0] instanceof Array) ) { // could be single point or array of points
|
|
1248 control = [control];
|
|
1249 } else { // break reference to attributes.points.control
|
|
1250 var tmp = [];
|
|
1251 for (i = 0, len = control.length; i< len; ++i) {
|
|
1252 tmp[i] = control[i];
|
|
1253 }
|
|
1254 control = tmp;
|
|
1255 }
|
|
1256
|
|
1257 if (Y.Dom.getStyle(el, 'position') == 'static') { // default to relative
|
|
1258 Y.Dom.setStyle(el, 'position', 'relative');
|
|
1259 }
|
|
1260
|
|
1261 if ( isset(attributes['points']['from']) ) {
|
|
1262 Y.Dom.setXY(el, attributes['points']['from']); // set position to from point
|
|
1263 }
|
|
1264 else { Y.Dom.setXY( el, Y.Dom.getXY(el) ); } // set it to current position
|
|
1265
|
|
1266 start = this.getAttribute('points'); // get actual top & left
|
|
1267
|
|
1268 // TO beats BY, per SMIL 2.1 spec
|
|
1269 if ( isset(attributes['points']['to']) ) {
|
|
1270 end = translateValues.call(this, attributes['points']['to'], start);
|
|
1271
|
|
1272 var pageXY = Y.Dom.getXY(this.getEl());
|
|
1273 for (i = 0, len = control.length; i < len; ++i) {
|
|
1274 control[i] = translateValues.call(this, control[i], start);
|
|
1275 }
|
|
1276
|
|
1277
|
|
1278 } else if ( isset(attributes['points']['by']) ) {
|
|
1279 end = [ start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1] ];
|
|
1280
|
|
1281 for (i = 0, len = control.length; i < len; ++i) {
|
|
1282 control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
|
|
1283 }
|
|
1284 }
|
|
1285
|
|
1286 this.runtimeAttributes[attr] = [start];
|
|
1287
|
|
1288 if (control.length > 0) {
|
|
1289 this.runtimeAttributes[attr] = this.runtimeAttributes[attr].concat(control);
|
|
1290 }
|
|
1291
|
|
1292 this.runtimeAttributes[attr][this.runtimeAttributes[attr].length] = end;
|
|
1293 }
|
|
1294 else {
|
|
1295 superclass.setRuntimeAttribute.call(this, attr);
|
|
1296 }
|
|
1297 };
|
|
1298
|
|
1299 var translateValues = function(val, start) {
|
|
1300 var pageXY = Y.Dom.getXY(this.getEl());
|
|
1301 val = [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1] ];
|
|
1302
|
|
1303 return val;
|
|
1304 };
|
|
1305
|
|
1306 var isset = function(prop) {
|
|
1307 return (typeof prop !== 'undefined');
|
|
1308 };
|
|
1309
|
|
1310 Y.Motion = Motion;
|
|
1311 })();
|
|
1312 (function() {
|
|
1313 /**
|
|
1314 * Anim subclass for scrolling elements to a position defined by the "scroll"
|
|
1315 * member of "attributes". All "scroll" members are arrays with x, y scroll positions.
|
|
1316 * <p>Usage: <code>var myAnim = new YAHOO.util.Scroll(el, { scroll: { to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
|
|
1317 * @class Scroll
|
|
1318 * @namespace YAHOO.util
|
|
1319 * @requires YAHOO.util.Anim
|
|
1320 * @requires YAHOO.util.AnimMgr
|
|
1321 * @requires YAHOO.util.Easing
|
|
1322 * @requires YAHOO.util.Bezier
|
|
1323 * @requires YAHOO.util.Dom
|
|
1324 * @requires YAHOO.util.Event
|
|
1325 * @requires YAHOO.util.CustomEvent
|
|
1326 * @extends YAHOO.util.ColorAnim
|
|
1327 * @constructor
|
|
1328 * @param {String or HTMLElement} el Reference to the element that will be animated
|
|
1329 * @param {Object} attributes The attribute(s) to be animated.
|
|
1330 * Each attribute is an object with at minimum a "to" or "by" member defined.
|
|
1331 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
|
|
1332 * All attribute names use camelCase.
|
|
1333 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
|
|
1334 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
|
|
1335 */
|
|
1336 var Scroll = function(el, attributes, duration, method) {
|
|
1337 if (el) { // dont break existing subclasses not using YAHOO.extend
|
|
1338 Scroll.superclass.constructor.call(this, el, attributes, duration, method);
|
|
1339 }
|
|
1340 };
|
|
1341
|
|
1342 Scroll.NAME = 'Scroll';
|
|
1343
|
|
1344 // shorthand
|
|
1345 var Y = YAHOO.util;
|
|
1346 YAHOO.extend(Scroll, Y.ColorAnim);
|
|
1347
|
|
1348 var superclass = Scroll.superclass;
|
|
1349 var proto = Scroll.prototype;
|
|
1350
|
|
1351 proto.doMethod = function(attr, start, end) {
|
|
1352 var val = null;
|
|
1353
|
|
1354 if (attr == 'scroll') {
|
|
1355 val = [
|
|
1356 this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames),
|
|
1357 this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)
|
|
1358 ];
|
|
1359
|
|
1360 } else {
|
|
1361 val = superclass.doMethod.call(this, attr, start, end);
|
|
1362 }
|
|
1363 return val;
|
|
1364 };
|
|
1365
|
|
1366 proto.getAttribute = function(attr) {
|
|
1367 var val = null;
|
|
1368 var el = this.getEl();
|
|
1369
|
|
1370 if (attr == 'scroll') {
|
|
1371 val = [ el.scrollLeft, el.scrollTop ];
|
|
1372 } else {
|
|
1373 val = superclass.getAttribute.call(this, attr);
|
|
1374 }
|
|
1375
|
|
1376 return val;
|
|
1377 };
|
|
1378
|
|
1379 proto.setAttribute = function(attr, val, unit) {
|
|
1380 var el = this.getEl();
|
|
1381
|
|
1382 if (attr == 'scroll') {
|
|
1383 el.scrollLeft = val[0];
|
|
1384 el.scrollTop = val[1];
|
|
1385 } else {
|
|
1386 superclass.setAttribute.call(this, attr, val, unit);
|
|
1387 }
|
|
1388 };
|
|
1389
|
|
1390 Y.Scroll = Scroll;
|
|
1391 })();
|
|
1392 YAHOO.register("animation", YAHOO.util.Anim, {version: "2.8.0r4", build: "2449"});
|