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