]> ToastFreeware Gitweb - philipp/winterrodeln/wradmin.git/blob - wradmin/public/yui/animation/animation.js
Start to use flask instead of pylons.
[philipp/winterrodeln/wradmin.git] / wradmin / public / yui / animation / animation.js
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.7.0
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 ('style' in el) {
97             Y.Dom.setStyle(el, attr, val + unit);
98         } else if (attr in el) {
99             el[attr] = val;
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 };
652 /**
653  * Used to calculate Bezier splines for any number of control points.
654  * @class Bezier
655  * @namespace YAHOO.util
656  *
657  */
658 YAHOO.util.Bezier = new function() {
659     /**
660      * Get the current position of the animated element based on t.
661      * Each point is an array of "x" and "y" values (0 = x, 1 = y)
662      * At least 2 points are required (start and end).
663      * First point is start. Last point is end.
664      * Additional control points are optional.     
665      * @method getPosition
666      * @param {Array} points An array containing Bezier points
667      * @param {Number} t A number between 0 and 1 which is the basis for determining current position
668      * @return {Array} An array containing int x and y member data
669      */
670     this.getPosition = function(points, t) {  
671         var n = points.length;
672         var tmp = [];
673
674         for (var i = 0; i < n; ++i){
675             tmp[i] = [points[i][0], points[i][1]]; // save input
676         }
677         
678         for (var j = 1; j < n; ++j) {
679             for (i = 0; i < n - j; ++i) {
680                 tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
681                 tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1]; 
682             }
683         }
684     
685         return [ tmp[0][0], tmp[0][1] ]; 
686     
687     };
688 };
689 (function() {
690 /**
691  * Anim subclass for color transitions.
692  * <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, 
693  * [255,255,255], or rgb(255,255,255)</p>
694  * @class ColorAnim
695  * @namespace YAHOO.util
696  * @requires YAHOO.util.Anim
697  * @requires YAHOO.util.AnimMgr
698  * @requires YAHOO.util.Easing
699  * @requires YAHOO.util.Bezier
700  * @requires YAHOO.util.Dom
701  * @requires YAHOO.util.Event
702  * @constructor
703  * @extends YAHOO.util.Anim
704  * @param {HTMLElement | String} el Reference to the element that will be animated
705  * @param {Object} attributes The attribute(s) to be animated.
706  * Each attribute is an object with at minimum a "to" or "by" member defined.
707  * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
708  * All attribute names use camelCase.
709  * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
710  * @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)
711  */
712     var ColorAnim = function(el, attributes, duration,  method) {
713         ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
714     };
715     
716     ColorAnim.NAME = 'ColorAnim';
717
718     ColorAnim.DEFAULT_BGCOLOR = '#fff';
719     // shorthand
720     var Y = YAHOO.util;
721     YAHOO.extend(ColorAnim, Y.Anim);
722
723     var superclass = ColorAnim.superclass;
724     var proto = ColorAnim.prototype;
725     
726     proto.patterns.color = /color$/i;
727     proto.patterns.rgb            = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
728     proto.patterns.hex            = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
729     proto.patterns.hex3          = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;
730     proto.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/; // need rgba for safari
731     
732     /**
733      * Attempts to parse the given string and return a 3-tuple.
734      * @method parseColor
735      * @param {String} s The string to parse.
736      * @return {Array} The 3-tuple of rgb values.
737      */
738     proto.parseColor = function(s) {
739         if (s.length == 3) { return s; }
740     
741         var c = this.patterns.hex.exec(s);
742         if (c && c.length == 4) {
743             return [ parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16) ];
744         }
745     
746         c = this.patterns.rgb.exec(s);
747         if (c && c.length == 4) {
748             return [ parseInt(c[1], 10), parseInt(c[2], 10), parseInt(c[3], 10) ];
749         }
750     
751         c = this.patterns.hex3.exec(s);
752         if (c && c.length == 4) {
753             return [ parseInt(c[1] + c[1], 16), parseInt(c[2] + c[2], 16), parseInt(c[3] + c[3], 16) ];
754         }
755         
756         return null;
757     };
758
759     proto.getAttribute = function(attr) {
760         var el = this.getEl();
761         if (this.patterns.color.test(attr) ) {
762             var val = YAHOO.util.Dom.getStyle(el, attr);
763             
764             var that = this;
765             if (this.patterns.transparent.test(val)) { // bgcolor default
766                 var parent = YAHOO.util.Dom.getAncestorBy(el, function(node) {
767                     return !that.patterns.transparent.test(val);
768                 });
769
770                 if (parent) {
771                     val = Y.Dom.getStyle(parent, attr);
772                 } else {
773                     val = ColorAnim.DEFAULT_BGCOLOR;
774                 }
775             }
776         } else {
777             val = superclass.getAttribute.call(this, attr);
778         }
779
780         return val;
781     };
782     
783     proto.doMethod = function(attr, start, end) {
784         var val;
785     
786         if ( this.patterns.color.test(attr) ) {
787             val = [];
788             for (var i = 0, len = start.length; i < len; ++i) {
789                 val[i] = superclass.doMethod.call(this, attr, start[i], end[i]);
790             }
791             
792             val = 'rgb('+Math.floor(val[0])+','+Math.floor(val[1])+','+Math.floor(val[2])+')';
793         }
794         else {
795             val = superclass.doMethod.call(this, attr, start, end);
796         }
797
798         return val;
799     };
800
801     proto.setRuntimeAttribute = function(attr) {
802         superclass.setRuntimeAttribute.call(this, attr);
803         
804         if ( this.patterns.color.test(attr) ) {
805             var attributes = this.attributes;
806             var start = this.parseColor(this.runtimeAttributes[attr].start);
807             var end = this.parseColor(this.runtimeAttributes[attr].end);
808             // fix colors if going "by"
809             if ( typeof attributes[attr]['to'] === 'undefined' && typeof attributes[attr]['by'] !== 'undefined' ) {
810                 end = this.parseColor(attributes[attr].by);
811             
812                 for (var i = 0, len = start.length; i < len; ++i) {
813                     end[i] = start[i] + end[i];
814                 }
815             }
816             
817             this.runtimeAttributes[attr].start = start;
818             this.runtimeAttributes[attr].end = end;
819         }
820     };
821
822     Y.ColorAnim = ColorAnim;
823 })();
824 /*!
825 TERMS OF USE - EASING EQUATIONS
826 Open source under the BSD License.
827 Copyright 2001 Robert Penner All rights reserved.
828
829 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
830
831  * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
832  * 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.
833  * 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.
834
835 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.
836 */
837
838 /**
839  * Singleton that determines how an animation proceeds from start to end.
840  * @class Easing
841  * @namespace YAHOO.util
842 */
843
844 YAHOO.util.Easing = {
845
846     /**
847      * Uniform speed between points.
848      * @method easeNone
849      * @param {Number} t Time value used to compute current value
850      * @param {Number} b Starting value
851      * @param {Number} c Delta between start and end values
852      * @param {Number} d Total length of animation
853      * @return {Number} The computed value for the current animation frame
854      */
855     easeNone: function (t, b, c, d) {
856         return c*t/d + b;
857     },
858     
859     /**
860      * Begins slowly and accelerates towards end.
861      * @method easeIn
862      * @param {Number} t Time value used to compute current value
863      * @param {Number} b Starting value
864      * @param {Number} c Delta between start and end values
865      * @param {Number} d Total length of animation
866      * @return {Number} The computed value for the current animation frame
867      */
868     easeIn: function (t, b, c, d) {
869         return c*(t/=d)*t + b;
870     },
871
872     /**
873      * Begins quickly and decelerates towards end.
874      * @method easeOut
875      * @param {Number} t Time value used to compute current value
876      * @param {Number} b Starting value
877      * @param {Number} c Delta between start and end values
878      * @param {Number} d Total length of animation
879      * @return {Number} The computed value for the current animation frame
880      */
881     easeOut: function (t, b, c, d) {
882         return -c *(t/=d)*(t-2) + b;
883     },
884     
885     /**
886      * Begins slowly and decelerates towards end.
887      * @method easeBoth
888      * @param {Number} t Time value used to compute current value
889      * @param {Number} b Starting value
890      * @param {Number} c Delta between start and end values
891      * @param {Number} d Total length of animation
892      * @return {Number} The computed value for the current animation frame
893      */
894     easeBoth: function (t, b, c, d) {
895         if ((t/=d/2) < 1) {
896             return c/2*t*t + b;
897         }
898         
899         return -c/2 * ((--t)*(t-2) - 1) + b;
900     },
901     
902     /**
903      * Begins slowly and accelerates towards end.
904      * @method easeInStrong
905      * @param {Number} t Time value used to compute current value
906      * @param {Number} b Starting value
907      * @param {Number} c Delta between start and end values
908      * @param {Number} d Total length of animation
909      * @return {Number} The computed value for the current animation frame
910      */
911     easeInStrong: function (t, b, c, d) {
912         return c*(t/=d)*t*t*t + b;
913     },
914     
915     /**
916      * Begins quickly and decelerates towards end.
917      * @method easeOutStrong
918      * @param {Number} t Time value used to compute current value
919      * @param {Number} b Starting value
920      * @param {Number} c Delta between start and end values
921      * @param {Number} d Total length of animation
922      * @return {Number} The computed value for the current animation frame
923      */
924     easeOutStrong: function (t, b, c, d) {
925         return -c * ((t=t/d-1)*t*t*t - 1) + b;
926     },
927     
928     /**
929      * Begins slowly and decelerates towards end.
930      * @method easeBothStrong
931      * @param {Number} t Time value used to compute current value
932      * @param {Number} b Starting value
933      * @param {Number} c Delta between start and end values
934      * @param {Number} d Total length of animation
935      * @return {Number} The computed value for the current animation frame
936      */
937     easeBothStrong: function (t, b, c, d) {
938         if ((t/=d/2) < 1) {
939             return c/2*t*t*t*t + b;
940         }
941         
942         return -c/2 * ((t-=2)*t*t*t - 2) + b;
943     },
944
945     /**
946      * Snap in elastic effect.
947      * @method elasticIn
948      * @param {Number} t Time value used to compute current value
949      * @param {Number} b Starting value
950      * @param {Number} c Delta between start and end values
951      * @param {Number} d Total length of animation
952      * @param {Number} a Amplitude (optional)
953      * @param {Number} p Period (optional)
954      * @return {Number} The computed value for the current animation frame
955      */
956
957     elasticIn: function (t, b, c, d, a, p) {
958         if (t == 0) {
959             return b;
960         }
961         if ( (t /= d) == 1 ) {
962             return b+c;
963         }
964         if (!p) {
965             p=d*.3;
966         }
967         
968         if (!a || a < Math.abs(c)) {
969             a = c; 
970             var s = p/4;
971         }
972         else {
973             var s = p/(2*Math.PI) * Math.asin (c/a);
974         }
975         
976         return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
977     },
978
979     /**
980      * Snap out elastic effect.
981      * @method elasticOut
982      * @param {Number} t Time value used to compute current value
983      * @param {Number} b Starting value
984      * @param {Number} c Delta between start and end values
985      * @param {Number} d Total length of animation
986      * @param {Number} a Amplitude (optional)
987      * @param {Number} p Period (optional)
988      * @return {Number} The computed value for the current animation frame
989      */
990     elasticOut: function (t, b, c, d, a, p) {
991         if (t == 0) {
992             return b;
993         }
994         if ( (t /= d) == 1 ) {
995             return b+c;
996         }
997         if (!p) {
998             p=d*.3;
999         }
1000         
1001         if (!a || a < Math.abs(c)) {
1002             a = c;
1003             var s = p / 4;
1004         }
1005         else {
1006             var s = p/(2*Math.PI) * Math.asin (c/a);
1007         }
1008         
1009         return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
1010     },
1011     
1012     /**
1013      * Snap both elastic effect.
1014      * @method elasticBoth
1015      * @param {Number} t Time value used to compute current value
1016      * @param {Number} b Starting value
1017      * @param {Number} c Delta between start and end values
1018      * @param {Number} d Total length of animation
1019      * @param {Number} a Amplitude (optional)
1020      * @param {Number} p Period (optional)
1021      * @return {Number} The computed value for the current animation frame
1022      */
1023     elasticBoth: function (t, b, c, d, a, p) {
1024         if (t == 0) {
1025             return b;
1026         }
1027         
1028         if ( (t /= d/2) == 2 ) {
1029             return b+c;
1030         }
1031         
1032         if (!p) {
1033             p = d*(.3*1.5);
1034         }
1035         
1036         if ( !a || a < Math.abs(c) ) {
1037             a = c; 
1038             var s = p/4;
1039         }
1040         else {
1041             var s = p/(2*Math.PI) * Math.asin (c/a);
1042         }
1043         
1044         if (t < 1) {
1045             return -.5*(a*Math.pow(2,10*(t-=1)) * 
1046                     Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
1047         }
1048         return a*Math.pow(2,-10*(t-=1)) * 
1049                 Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
1050     },
1051
1052
1053     /**
1054      * Backtracks slightly, then reverses direction and moves to end.
1055      * @method backIn
1056      * @param {Number} t Time value used to compute current value
1057      * @param {Number} b Starting value
1058      * @param {Number} c Delta between start and end values
1059      * @param {Number} d Total length of animation
1060      * @param {Number} s Overshoot (optional)
1061      * @return {Number} The computed value for the current animation frame
1062      */
1063     backIn: function (t, b, c, d, s) {
1064         if (typeof s == 'undefined') {
1065             s = 1.70158;
1066         }
1067         return c*(t/=d)*t*((s+1)*t - s) + b;
1068     },
1069
1070     /**
1071      * Overshoots end, then reverses and comes back to end.
1072      * @method backOut
1073      * @param {Number} t Time value used to compute current value
1074      * @param {Number} b Starting value
1075      * @param {Number} c Delta between start and end values
1076      * @param {Number} d Total length of animation
1077      * @param {Number} s Overshoot (optional)
1078      * @return {Number} The computed value for the current animation frame
1079      */
1080     backOut: function (t, b, c, d, s) {
1081         if (typeof s == 'undefined') {
1082             s = 1.70158;
1083         }
1084         return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
1085     },
1086     
1087     /**
1088      * Backtracks slightly, then reverses direction, overshoots end, 
1089      * then reverses and comes back to end.
1090      * @method backBoth
1091      * @param {Number} t Time value used to compute current value
1092      * @param {Number} b Starting value
1093      * @param {Number} c Delta between start and end values
1094      * @param {Number} d Total length of animation
1095      * @param {Number} s Overshoot (optional)
1096      * @return {Number} The computed value for the current animation frame
1097      */
1098     backBoth: function (t, b, c, d, s) {
1099         if (typeof s == 'undefined') {
1100             s = 1.70158; 
1101         }
1102         
1103         if ((t /= d/2 ) < 1) {
1104             return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
1105         }
1106         return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
1107     },
1108
1109     /**
1110      * Bounce off of start.
1111      * @method bounceIn
1112      * @param {Number} t Time value used to compute current value
1113      * @param {Number} b Starting value
1114      * @param {Number} c Delta between start and end values
1115      * @param {Number} d Total length of animation
1116      * @return {Number} The computed value for the current animation frame
1117      */
1118     bounceIn: function (t, b, c, d) {
1119         return c - YAHOO.util.Easing.bounceOut(d-t, 0, c, d) + b;
1120     },
1121     
1122     /**
1123      * Bounces off end.
1124      * @method bounceOut
1125      * @param {Number} t Time value used to compute current value
1126      * @param {Number} b Starting value
1127      * @param {Number} c Delta between start and end values
1128      * @param {Number} d Total length of animation
1129      * @return {Number} The computed value for the current animation frame
1130      */
1131     bounceOut: function (t, b, c, d) {
1132         if ((t/=d) < (1/2.75)) {
1133                 return c*(7.5625*t*t) + b;
1134         } else if (t < (2/2.75)) {
1135                 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
1136         } else if (t < (2.5/2.75)) {
1137                 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
1138         }
1139         return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
1140     },
1141     
1142     /**
1143      * Bounces off start and end.
1144      * @method bounceBoth
1145      * @param {Number} t Time value used to compute current value
1146      * @param {Number} b Starting value
1147      * @param {Number} c Delta between start and end values
1148      * @param {Number} d Total length of animation
1149      * @return {Number} The computed value for the current animation frame
1150      */
1151     bounceBoth: function (t, b, c, d) {
1152         if (t < d/2) {
1153             return YAHOO.util.Easing.bounceIn(t*2, 0, c, d) * .5 + b;
1154         }
1155         return YAHOO.util.Easing.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
1156     }
1157 };
1158
1159 (function() {
1160 /**
1161  * Anim subclass for moving elements along a path defined by the "points" 
1162  * member of "attributes".  All "points" are arrays with x, y coordinates.
1163  * <p>Usage: <code>var myAnim = new YAHOO.util.Motion(el, { points: { to: [800, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
1164  * @class Motion
1165  * @namespace YAHOO.util
1166  * @requires YAHOO.util.Anim
1167  * @requires YAHOO.util.AnimMgr
1168  * @requires YAHOO.util.Easing
1169  * @requires YAHOO.util.Bezier
1170  * @requires YAHOO.util.Dom
1171  * @requires YAHOO.util.Event
1172  * @requires YAHOO.util.CustomEvent 
1173  * @constructor
1174  * @extends YAHOO.util.ColorAnim
1175  * @param {String | HTMLElement} el Reference to the element that will be animated
1176  * @param {Object} attributes The attribute(s) to be animated.  
1177  * Each attribute is an object with at minimum a "to" or "by" member defined.  
1178  * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
1179  * All attribute names use camelCase.
1180  * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
1181  * @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)
1182  */
1183     var Motion = function(el, attributes, duration,  method) {
1184         if (el) { // dont break existing subclasses not using YAHOO.extend
1185             Motion.superclass.constructor.call(this, el, attributes, duration, method);
1186         }
1187     };
1188
1189
1190     Motion.NAME = 'Motion';
1191
1192     // shorthand
1193     var Y = YAHOO.util;
1194     YAHOO.extend(Motion, Y.ColorAnim);
1195     
1196     var superclass = Motion.superclass;
1197     var proto = Motion.prototype;
1198
1199     proto.patterns.points = /^points$/i;
1200     
1201     proto.setAttribute = function(attr, val, unit) {
1202         if (  this.patterns.points.test(attr) ) {
1203             unit = unit || 'px';
1204             superclass.setAttribute.call(this, 'left', val[0], unit);
1205             superclass.setAttribute.call(this, 'top', val[1], unit);
1206         } else {
1207             superclass.setAttribute.call(this, attr, val, unit);
1208         }
1209     };
1210
1211     proto.getAttribute = function(attr) {
1212         if (  this.patterns.points.test(attr) ) {
1213             var val = [
1214                 superclass.getAttribute.call(this, 'left'),
1215                 superclass.getAttribute.call(this, 'top')
1216             ];
1217         } else {
1218             val = superclass.getAttribute.call(this, attr);
1219         }
1220
1221         return val;
1222     };
1223
1224     proto.doMethod = function(attr, start, end) {
1225         var val = null;
1226
1227         if ( this.patterns.points.test(attr) ) {
1228             var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;                             
1229             val = Y.Bezier.getPosition(this.runtimeAttributes[attr], t);
1230         } else {
1231             val = superclass.doMethod.call(this, attr, start, end);
1232         }
1233         return val;
1234     };
1235
1236     proto.setRuntimeAttribute = function(attr) {
1237         if ( this.patterns.points.test(attr) ) {
1238             var el = this.getEl();
1239             var attributes = this.attributes;
1240             var start;
1241             var control = attributes['points']['control'] || [];
1242             var end;
1243             var i, len;
1244             
1245             if (control.length > 0 && !(control[0] instanceof Array) ) { // could be single point or array of points
1246                 control = [control];
1247             } else { // break reference to attributes.points.control
1248                 var tmp = []; 
1249                 for (i = 0, len = control.length; i< len; ++i) {
1250                     tmp[i] = control[i];
1251                 }
1252                 control = tmp;
1253             }
1254
1255             if (Y.Dom.getStyle(el, 'position') == 'static') { // default to relative
1256                 Y.Dom.setStyle(el, 'position', 'relative');
1257             }
1258     
1259             if ( isset(attributes['points']['from']) ) {
1260                 Y.Dom.setXY(el, attributes['points']['from']); // set position to from point
1261             } 
1262             else { Y.Dom.setXY( el, Y.Dom.getXY(el) ); } // set it to current position
1263             
1264             start = this.getAttribute('points'); // get actual top & left
1265             
1266             // TO beats BY, per SMIL 2.1 spec
1267             if ( isset(attributes['points']['to']) ) {
1268                 end = translateValues.call(this, attributes['points']['to'], start);
1269                 
1270                 var pageXY = Y.Dom.getXY(this.getEl());
1271                 for (i = 0, len = control.length; i < len; ++i) {
1272                     control[i] = translateValues.call(this, control[i], start);
1273                 }
1274
1275                 
1276             } else if ( isset(attributes['points']['by']) ) {
1277                 end = [ start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1] ];
1278                 
1279                 for (i = 0, len = control.length; i < len; ++i) {
1280                     control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
1281                 }
1282             }
1283
1284             this.runtimeAttributes[attr] = [start];
1285             
1286             if (control.length > 0) {
1287                 this.runtimeAttributes[attr] = this.runtimeAttributes[attr].concat(control); 
1288             }
1289
1290             this.runtimeAttributes[attr][this.runtimeAttributes[attr].length] = end;
1291         }
1292         else {
1293             superclass.setRuntimeAttribute.call(this, attr);
1294         }
1295     };
1296     
1297     var translateValues = function(val, start) {
1298         var pageXY = Y.Dom.getXY(this.getEl());
1299         val = [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1] ];
1300
1301         return val; 
1302     };
1303     
1304     var isset = function(prop) {
1305         return (typeof prop !== 'undefined');
1306     };
1307
1308     Y.Motion = Motion;
1309 })();
1310 (function() {
1311 /**
1312  * Anim subclass for scrolling elements to a position defined by the "scroll"
1313  * member of "attributes".  All "scroll" members are arrays with x, y scroll positions.
1314  * <p>Usage: <code>var myAnim = new YAHOO.util.Scroll(el, { scroll: { to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
1315  * @class Scroll
1316  * @namespace YAHOO.util
1317  * @requires YAHOO.util.Anim
1318  * @requires YAHOO.util.AnimMgr
1319  * @requires YAHOO.util.Easing
1320  * @requires YAHOO.util.Bezier
1321  * @requires YAHOO.util.Dom
1322  * @requires YAHOO.util.Event
1323  * @requires YAHOO.util.CustomEvent 
1324  * @extends YAHOO.util.ColorAnim
1325  * @constructor
1326  * @param {String or HTMLElement} el Reference to the element that will be animated
1327  * @param {Object} attributes The attribute(s) to be animated.  
1328  * Each attribute is an object with at minimum a "to" or "by" member defined.  
1329  * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
1330  * All attribute names use camelCase.
1331  * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
1332  * @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)
1333  */
1334     var Scroll = function(el, attributes, duration,  method) {
1335         if (el) { // dont break existing subclasses not using YAHOO.extend
1336             Scroll.superclass.constructor.call(this, el, attributes, duration, method);
1337         }
1338     };
1339
1340     Scroll.NAME = 'Scroll';
1341
1342     // shorthand
1343     var Y = YAHOO.util;
1344     YAHOO.extend(Scroll, Y.ColorAnim);
1345     
1346     var superclass = Scroll.superclass;
1347     var proto = Scroll.prototype;
1348
1349     proto.doMethod = function(attr, start, end) {
1350         var val = null;
1351     
1352         if (attr == 'scroll') {
1353             val = [
1354                 this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames),
1355                 this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)
1356             ];
1357             
1358         } else {
1359             val = superclass.doMethod.call(this, attr, start, end);
1360         }
1361         return val;
1362     };
1363
1364     proto.getAttribute = function(attr) {
1365         var val = null;
1366         var el = this.getEl();
1367         
1368         if (attr == 'scroll') {
1369             val = [ el.scrollLeft, el.scrollTop ];
1370         } else {
1371             val = superclass.getAttribute.call(this, attr);
1372         }
1373         
1374         return val;
1375     };
1376
1377     proto.setAttribute = function(attr, val, unit) {
1378         var el = this.getEl();
1379         
1380         if (attr == 'scroll') {
1381             el.scrollLeft = val[0];
1382             el.scrollTop = val[1];
1383         } else {
1384             superclass.setAttribute.call(this, attr, val, unit);
1385         }
1386     };
1387
1388     Y.Scroll = Scroll;
1389 })();
1390 YAHOO.register("animation", YAHOO.util.Anim, {version: "2.7.0", build: "1799"});