]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/anim/anim.js
Release 6.5.0
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / anim / anim.js
1 /*
2 Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
5 version: 3.3.0
6 build: 3167
7 */
8 YUI.add('anim-base', function(Y) {
9
10 /**
11 * The Animation Utility provides an API for creating advanced transitions.
12 * @module anim
13 */
14
15 /**
16 * Provides the base Anim class, for animating numeric properties.
17 *
18 * @module anim
19 * @submodule anim-base
20 */
21
22     /**
23      * A class for constructing animation instances.
24      * @class Anim
25      * @for Anim
26      * @constructor
27      * @extends Base
28      */
29
30     var RUNNING = 'running',
31         START_TIME = 'startTime',
32         ELAPSED_TIME = 'elapsedTime',
33         /**
34         * @for Anim
35         * @event start
36         * @description fires when an animation begins.
37         * @param {Event} ev The start event.
38         * @type Event.Custom
39         */
40         START = 'start',
41
42         /**
43         * @event tween
44         * @description fires every frame of the animation.
45         * @param {Event} ev The tween event.
46         * @type Event.Custom
47         */
48         TWEEN = 'tween',
49
50         /**
51         * @event end
52         * @description fires after the animation completes.
53         * @param {Event} ev The end event.
54         * @type Event.Custom
55         */
56         END = 'end',
57         NODE = 'node',
58         PAUSED = 'paused',
59         REVERSE = 'reverse', // TODO: cleanup
60         ITERATION_COUNT = 'iterationCount',
61
62         NUM = Number;
63
64     var _running = {},
65         _timer;
66
67     Y.Anim = function() {
68         Y.Anim.superclass.constructor.apply(this, arguments);
69         Y.Anim._instances[Y.stamp(this)] = this;
70     };
71
72     Y.Anim.NAME = 'anim';
73
74     Y.Anim._instances = {};
75
76     /**
77      * Regex of properties that should use the default unit.
78      *
79      * @property RE_DEFAULT_UNIT
80      * @static
81      */
82     Y.Anim.RE_DEFAULT_UNIT = /^width|height|top|right|bottom|left|margin.*|padding.*|border.*$/i;
83
84     /**
85      * The default unit to use with properties that pass the RE_DEFAULT_UNIT test.
86      *
87      * @property DEFAULT_UNIT
88      * @static
89      */
90     Y.Anim.DEFAULT_UNIT = 'px';
91
92     Y.Anim.DEFAULT_EASING = function (t, b, c, d) {
93         return c * t / d + b; // linear easing
94     };
95
96     /**
97      * Time in milliseconds passed to setInterval for frame processing 
98      *
99      * @property intervalTime
100      * @default 20
101      * @static
102      */
103     Y.Anim._intervalTime = 20;
104
105     /**
106      * Bucket for custom getters and setters
107      *
108      * @property behaviors
109      * @static
110      */
111     Y.Anim.behaviors = {
112         left: {
113             get: function(anim, attr) {
114                 return anim._getOffset(attr);
115             }
116         }
117     };
118
119     Y.Anim.behaviors.top = Y.Anim.behaviors.left;
120
121     /**
122      * The default setter to use when setting object properties.
123      *
124      * @property DEFAULT_SETTER
125      * @static
126      */
127     Y.Anim.DEFAULT_SETTER = function(anim, att, from, to, elapsed, duration, fn, unit) {
128         var node = anim._node,
129             val = fn(elapsed, NUM(from), NUM(to) - NUM(from), duration);
130
131         if (att in node._node.style || att in Y.DOM.CUSTOM_STYLES) {
132             unit = unit || '';
133             node.setStyle(att, val + unit);
134         } else if (node._node.attributes[att]) {
135             node.setAttribute(att, val);
136         } else {
137             node.set(att, val);
138         }
139     };
140
141     /**
142      * The default getter to use when getting object properties.
143      *
144      * @property DEFAULT_GETTER
145      * @static
146      */
147     Y.Anim.DEFAULT_GETTER = function(anim, att) {
148         var node = anim._node,
149             val = '';
150
151         if (att in node._node.style || att in Y.DOM.CUSTOM_STYLES) {
152             val = node.getComputedStyle(att);
153         } else if (node._node.attributes[att]) {
154             val = node.getAttribute(att);
155         } else {
156             val = node.get(att);
157         }
158
159         return val;
160     };
161
162     Y.Anim.ATTRS = {
163         /**
164          * The object to be animated.
165          * @attribute node
166          * @type Node
167          */
168         node: {
169             setter: function(node) {
170                 node = Y.one(node);
171                 this._node = node;
172                 if (!node) {
173                 }
174                 return node;
175             }
176         },
177
178         /**
179          * The length of the animation.  Defaults to "1" (second).
180          * @attribute duration
181          * @type NUM
182          */
183         duration: {
184             value: 1
185         },
186
187         /**
188          * The method that will provide values to the attribute(s) during the animation. 
189          * Defaults to "Easing.easeNone".
190          * @attribute easing
191          * @type Function
192          */
193         easing: {
194             value: Y.Anim.DEFAULT_EASING,
195
196             setter: function(val) {
197                 if (typeof val === 'string' && Y.Easing) {
198                     return Y.Easing[val];
199                 }
200             }
201         },
202
203         /**
204          * The starting values for the animated properties. 
205          * Fields may be strings, numbers, or functions.
206          * If a function is used, the return value becomes the from value.
207          * If no from value is specified, the DEFAULT_GETTER will be used. 
208          * @attribute from
209          * @type Object
210          * supports any unit, provided it matches the "to" (or default)
211          * unit (e.g. "{width: 10em', color: 'rgb(0, 0 0)', borderColor: '#ccc'}".
212          * If using the default ('px' for length-based units), the unit may be omitted  (
213          * (e.g. "{width: 100}, borderColor: 'ccc'}", which defaults to pixels 
214          * and hex, respectively).
215          */
216         from: {},
217
218         /**
219          * The ending values for the animated properties. 
220          * Fields may be strings, numbers, or functions.
221          * @attribute to
222          * @type Object
223          * supports any unit, provided it matches the "from" (or default)
224          * unit (e.g. "{width: '50%', color: 'red', borderColor: '#ccc'}".
225          * If using the default ('px' for length-based units), the unit may be omitted (
226          * (e.g. "{width: 100}, borderColor: 'ccc'}", which defaults to pixels 
227          * and hex, respectively).
228          */
229         to: {},
230
231         /**
232          * Date stamp for the first frame of the animation.
233          * @attribute startTime
234          * @type Int
235          * @default 0 
236          * @readOnly
237          */
238         startTime: {
239             value: 0,
240             readOnly: true
241         },
242
243         /**
244          * Current time the animation has been running.
245          * @attribute elapsedTime
246          * @type Int
247          * @default 0 
248          * @readOnly
249          */
250         elapsedTime: {
251             value: 0,
252             readOnly: true
253         },
254
255         /**
256          * Whether or not the animation is currently running.
257          * @attribute running 
258          * @type Boolean
259          * @default false 
260          * @readOnly
261          */
262         running: {
263             getter: function() {
264                 return !!_running[Y.stamp(this)];
265             },
266             value: false,
267             readOnly: true
268         },
269
270         /**
271          * The number of times the animation should run 
272          * @attribute iterations
273          * @type Int
274          * @default 1 
275          */
276         iterations: {
277             value: 1
278         },
279
280         /**
281          * The number of iterations that have occurred.
282          * Resets when an animation ends (reaches iteration count or stop() called). 
283          * @attribute iterationCount
284          * @type Int
285          * @default 0
286          * @readOnly
287          */
288         iterationCount: {
289             value: 0,
290             readOnly: true
291         },
292
293         /**
294          * How iterations of the animation should behave. 
295          * Possible values are "normal" and "alternate".
296          * Normal will repeat the animation, alternate will reverse on every other pass.
297          *
298          * @attribute direction
299          * @type String
300          * @default "normal"
301          */
302         direction: {
303             value: 'normal' // | alternate (fwd on odd, rev on even per spec)
304         },
305
306         /**
307          * Whether or not the animation is currently paused.
308          * @attribute paused 
309          * @type Boolean
310          * @default false 
311          * @readOnly
312          */
313         paused: {
314             readOnly: true,
315             value: false
316         },
317
318         /**
319          * If true, animation begins from last frame
320          * @attribute reverse
321          * @type Boolean
322          * @default false 
323          */
324         reverse: {
325             value: false
326         }
327
328
329     };
330
331     /**
332      * Runs all animation instances.
333      * @method run
334      * @static
335      */    
336     Y.Anim.run = function() {
337         var instances = Y.Anim._instances;
338         for (var i in instances) {
339             if (instances[i].run) {
340                 instances[i].run();
341             }
342         }
343     };
344
345     /**
346      * Pauses all animation instances.
347      * @method pause
348      * @static
349      */    
350     Y.Anim.pause = function() {
351         for (var i in _running) { // stop timer if nothing running
352             if (_running[i].pause) {
353                 _running[i].pause();
354             }
355         }
356
357         Y.Anim._stopTimer();
358     };
359
360     /**
361      * Stops all animation instances.
362      * @method stop
363      * @static
364      */    
365     Y.Anim.stop = function() {
366         for (var i in _running) { // stop timer if nothing running
367             if (_running[i].stop) {
368                 _running[i].stop();
369             }
370         }
371         Y.Anim._stopTimer();
372     };
373     
374     Y.Anim._startTimer = function() {
375         if (!_timer) {
376             _timer = setInterval(Y.Anim._runFrame, Y.Anim._intervalTime);
377         }
378     };
379
380     Y.Anim._stopTimer = function() {
381         clearInterval(_timer);
382         _timer = 0;
383     };
384
385     /**
386      * Called per Interval to handle each animation frame.
387      * @method _runFrame
388      * @private
389      * @static
390      */    
391     Y.Anim._runFrame = function() {
392         var done = true;
393         for (var anim in _running) {
394             if (_running[anim]._runFrame) {
395                 done = false;
396                 _running[anim]._runFrame();
397             }
398         }
399
400         if (done) {
401             Y.Anim._stopTimer();
402         }
403     };
404
405     Y.Anim.RE_UNITS = /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/;
406
407     var proto = {
408         /**
409          * Starts or resumes an animation.
410          * @method run
411          * @chainable
412          */    
413         run: function() {
414             if (this.get(PAUSED)) {
415                 this._resume();
416             } else if (!this.get(RUNNING)) {
417                 this._start();
418             }
419             return this;
420         },
421
422         /**
423          * Pauses the animation and
424          * freezes it in its current state and time.
425          * Calling run() will continue where it left off.
426          * @method pause
427          * @chainable
428          */    
429         pause: function() {
430             if (this.get(RUNNING)) {
431                 this._pause();
432             }
433             return this;
434         },
435
436         /**
437          * Stops the animation and resets its time.
438          * @method stop
439          * @param {Boolean} finish If true, the animation will move to the last frame
440          * @chainable
441          */    
442         stop: function(finish) {
443             if (this.get(RUNNING) || this.get(PAUSED)) {
444                 this._end(finish);
445             }
446             return this;
447         },
448
449         _added: false,
450
451         _start: function() {
452             this._set(START_TIME, new Date() - this.get(ELAPSED_TIME));
453             this._actualFrames = 0;
454             if (!this.get(PAUSED)) {
455                 this._initAnimAttr();
456             }
457             _running[Y.stamp(this)] = this;
458             Y.Anim._startTimer();
459
460             this.fire(START);
461         },
462
463         _pause: function() {
464             this._set(START_TIME, null);
465             this._set(PAUSED, true);
466             delete _running[Y.stamp(this)];
467
468             /**
469             * @event pause
470             * @description fires when an animation is paused.
471             * @param {Event} ev The pause event.
472             * @type Event.Custom
473             */
474             this.fire('pause');
475         },
476
477         _resume: function() {
478             this._set(PAUSED, false);
479             _running[Y.stamp(this)] = this;
480             this._set(START_TIME, new Date() - this.get(ELAPSED_TIME));
481             Y.Anim._startTimer();
482
483             /**
484             * @event resume
485             * @description fires when an animation is resumed (run from pause).
486             * @param {Event} ev The pause event.
487             * @type Event.Custom
488             */
489             this.fire('resume');
490         },
491
492         _end: function(finish) {
493             var duration = this.get('duration') * 1000;
494             if (finish) { // jump to last frame
495                 this._runAttrs(duration, duration, this.get(REVERSE));
496             }
497
498             this._set(START_TIME, null);
499             this._set(ELAPSED_TIME, 0);
500             this._set(PAUSED, false);
501
502             delete _running[Y.stamp(this)];
503             this.fire(END, {elapsed: this.get(ELAPSED_TIME)});
504         },
505
506         _runFrame: function() {
507             var d = this._runtimeAttr.duration,
508                 t = new Date() - this.get(START_TIME),
509                 reverse = this.get(REVERSE),
510                 done = (t >= d),
511                 attribute,
512                 setter;
513                 
514             this._runAttrs(t, d, reverse);
515             this._actualFrames += 1;
516             this._set(ELAPSED_TIME, t);
517
518             this.fire(TWEEN);
519             if (done) {
520                 this._lastFrame();
521             }
522         },
523
524         _runAttrs: function(t, d, reverse) {
525             var attr = this._runtimeAttr,
526                 customAttr = Y.Anim.behaviors,
527                 easing = attr.easing,
528                 lastFrame = d,
529                 done = false,
530                 attribute,
531                 setter,
532                 i;
533
534             if (t >= d) {
535                 done = true;
536             }
537
538             if (reverse) {
539                 t = d - t;
540                 lastFrame = 0;
541             }
542
543             for (i in attr) {
544                 if (attr[i].to) {
545                     attribute = attr[i];
546                     setter = (i in customAttr && 'set' in customAttr[i]) ?
547                             customAttr[i].set : Y.Anim.DEFAULT_SETTER;
548
549                     if (!done) {
550                         setter(this, i, attribute.from, attribute.to, t, d, easing, attribute.unit); 
551                     } else {
552                         setter(this, i, attribute.from, attribute.to, lastFrame, d, easing, attribute.unit); 
553                     }
554                 }
555             }
556
557
558         },
559
560         _lastFrame: function() {
561             var iter = this.get('iterations'),
562                 iterCount = this.get(ITERATION_COUNT);
563
564             iterCount += 1;
565             if (iter === 'infinite' || iterCount < iter) {
566                 if (this.get('direction') === 'alternate') {
567                     this.set(REVERSE, !this.get(REVERSE)); // flip it
568                 }
569                 /**
570                 * @event iteration
571                 * @description fires when an animation begins an iteration.
572                 * @param {Event} ev The iteration event.
573                 * @type Event.Custom
574                 */
575                 this.fire('iteration');
576             } else {
577                 iterCount = 0;
578                 this._end();
579             }
580
581             this._set(START_TIME, new Date());
582             this._set(ITERATION_COUNT, iterCount);
583         },
584
585         _initAnimAttr: function() {
586             var from = this.get('from') || {},
587                 to = this.get('to') || {},
588                 attr = {
589                     duration: this.get('duration') * 1000,
590                     easing: this.get('easing')
591                 },
592                 customAttr = Y.Anim.behaviors,
593                 node = this.get(NODE), // implicit attr init
594                 unit, begin, end;
595
596             Y.each(to, function(val, name) {
597                 if (typeof val === 'function') {
598                     val = val.call(this, node);
599                 }
600
601                 begin = from[name];
602                 if (begin === undefined) {
603                     begin = (name in customAttr && 'get' in customAttr[name])  ?
604                             customAttr[name].get(this, name) : Y.Anim.DEFAULT_GETTER(this, name);
605                 } else if (typeof begin === 'function') {
606                     begin = begin.call(this, node);
607                 }
608
609                 var mFrom = Y.Anim.RE_UNITS.exec(begin);
610                 var mTo = Y.Anim.RE_UNITS.exec(val);
611
612                 begin = mFrom ? mFrom[1] : begin;
613                 end = mTo ? mTo[1] : val;
614                 unit = mTo ? mTo[2] : mFrom ?  mFrom[2] : ''; // one might be zero TODO: mixed units
615
616                 if (!unit && Y.Anim.RE_DEFAULT_UNIT.test(name)) {
617                     unit = Y.Anim.DEFAULT_UNIT;
618                 }
619
620                 if (!begin || !end) {
621                     Y.error('invalid "from" or "to" for "' + name + '"', 'Anim');
622                     return;
623                 }
624
625                 attr[name] = {
626                     from: begin,
627                     to: end,
628                     unit: unit
629                 };
630
631             }, this);
632
633             this._runtimeAttr = attr;
634         },
635
636
637         // TODO: move to computedStyle? (browsers dont agree on default computed offsets)
638         _getOffset: function(attr) {
639             var node = this._node,
640                 val = node.getComputedStyle(attr),
641                 get = (attr === 'left') ? 'getX': 'getY',
642                 set = (attr === 'left') ? 'setX': 'setY';
643
644             if (val === 'auto') {
645                 var position = node.getStyle('position');
646                 if (position === 'absolute' || position === 'fixed') {
647                     val = node[get]();
648                     node[set](val);
649                 } else {
650                     val = 0;
651                 }
652             }
653
654             return val;
655         },
656
657         destructor: function() {
658             delete Y.Anim._instances[Y.stamp(this)];
659         }
660     };
661
662     Y.extend(Y.Anim, Y.Base, proto);
663
664
665 }, '3.3.0' ,{requires:['base-base', 'node-style']});
666 YUI.add('anim-color', function(Y) {
667
668 /**
669  * Adds support for color properties in <code>to</code>
670  * and <code>from</code> attributes.
671  * @module anim
672  * @submodule anim-color
673  */
674
675 var NUM = Number;
676
677 Y.Anim.behaviors.color = {
678     set: function(anim, att, from, to, elapsed, duration, fn) {
679         from = Y.Color.re_RGB.exec(Y.Color.toRGB(from));
680         to = Y.Color.re_RGB.exec(Y.Color.toRGB(to));
681
682         if (!from || from.length < 3 || !to || to.length < 3) {
683             Y.error('invalid from or to passed to color behavior');
684         }
685
686         anim._node.setStyle(att, 'rgb(' + [
687             Math.floor(fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)),
688             Math.floor(fn(elapsed, NUM(from[2]), NUM(to[2]) - NUM(from[2]), duration)),
689             Math.floor(fn(elapsed, NUM(from[3]), NUM(to[3]) - NUM(from[3]), duration))
690         ].join(', ') + ')');
691     },
692     
693     // TODO: default bgcolor const
694     get: function(anim, att) {
695         var val = anim._node.getComputedStyle(att);
696         val = (val === 'transparent') ? 'rgb(255, 255, 255)' : val;
697         return val;
698     }
699 };
700
701 Y.each(['backgroundColor',
702         'borderColor',
703         'borderTopColor',
704         'borderRightColor', 
705         'borderBottomColor', 
706         'borderLeftColor'],
707         function(v, i) {
708             Y.Anim.behaviors[v] = Y.Anim.behaviors.color;
709         }
710 );
711
712
713 }, '3.3.0' ,{requires:['anim-base']});
714 YUI.add('anim-curve', function(Y) {
715
716 /**
717  * Adds support for the <code>curve</code> property for the <code>to</code> 
718  * attribute.  A curve is zero or more control points and an end point.
719  * @module anim
720  * @submodule anim-curve
721  */
722
723 Y.Anim.behaviors.curve = {
724     set: function(anim, att, from, to, elapsed, duration, fn) {
725         from = from.slice.call(from);
726         to = to.slice.call(to);
727         var t = fn(elapsed, 0, 100, duration) / 100;
728         to.unshift(from);
729         anim._node.setXY(Y.Anim.getBezier(to, t));
730     },
731
732     get: function(anim, att) {
733         return anim._node.getXY();
734     }
735 };
736
737 /**
738  * Get the current position of the animated element based on t.
739  * Each point is an array of "x" and "y" values (0 = x, 1 = y)
740  * At least 2 points are required (start and end).
741  * First point is start. Last point is end.
742  * Additional control points are optional.     
743  * @for Anim
744  * @method getBezier
745  * @static
746  * @param {Array} points An array containing Bezier points
747  * @param {Number} t A number between 0 and 1 which is the basis for determining current position
748  * @return {Array} An array containing int x and y member data
749  */
750 Y.Anim.getBezier = function(points, t) {  
751     var n = points.length;
752     var tmp = [];
753
754     for (var i = 0; i < n; ++i){
755         tmp[i] = [points[i][0], points[i][1]]; // save input
756     }
757     
758     for (var j = 1; j < n; ++j) {
759         for (i = 0; i < n - j; ++i) {
760             tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
761             tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1]; 
762         }
763     }
764
765     return [ tmp[0][0], tmp[0][1] ]; 
766
767 };
768
769
770 }, '3.3.0' ,{requires:['anim-xy']});
771 YUI.add('anim-easing', function(Y) {
772
773 /*
774 TERMS OF USE - EASING EQUATIONS
775 Open source under the BSD License.
776 Copyright 2001 Robert Penner All rights reserved.
777
778 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
779
780  * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
781  * 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.
782  * 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.
783
784 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.
785 */
786
787 /**
788  * The easing module provides methods for customizing
789  * how an animation behaves during each run.
790  * @class Easing
791  * @module anim
792  * @submodule anim-easing
793  */
794
795 var Easing = {
796
797     /**
798      * Uniform speed between points.
799      * @for Easing
800      * @method easeNone
801      * @param {Number} t Time value used to compute current value
802      * @param {Number} b Starting value
803      * @param {Number} c Delta between start and end values
804      * @param {Number} d Total length of animation
805      * @return {Number} The computed value for the current animation frame
806      */
807     easeNone: function (t, b, c, d) {
808         return c*t/d + b;
809     },
810     
811     /**
812      * Begins slowly and accelerates towards end. (quadratic)
813      * @method easeIn
814      * @param {Number} t Time value used to compute current value
815      * @param {Number} b Starting value
816      * @param {Number} c Delta between start and end values
817      * @param {Number} d Total length of animation
818      * @return {Number} The computed value for the current animation frame
819      */
820     easeIn: function (t, b, c, d) {
821         return c*(t/=d)*t + b;
822     },
823
824     /**
825      * Begins quickly and decelerates towards end.  (quadratic)
826      * @method easeOut
827      * @param {Number} t Time value used to compute current value
828      * @param {Number} b Starting value
829      * @param {Number} c Delta between start and end values
830      * @param {Number} d Total length of animation
831      * @return {Number} The computed value for the current animation frame
832      */
833     easeOut: function (t, b, c, d) {
834         return -c *(t/=d)*(t-2) + b;
835     },
836     
837     /**
838      * Begins slowly and decelerates towards end. (quadratic)
839      * @method easeBoth
840      * @param {Number} t Time value used to compute current value
841      * @param {Number} b Starting value
842      * @param {Number} c Delta between start and end values
843      * @param {Number} d Total length of animation
844      * @return {Number} The computed value for the current animation frame
845      */
846     easeBoth: function (t, b, c, d) {
847         if ((t/=d/2) < 1) {
848             return c/2*t*t + b;
849         }
850         
851         return -c/2 * ((--t)*(t-2) - 1) + b;
852     },
853     
854     /**
855      * Begins slowly and accelerates towards end. (quartic)
856      * @method easeInStrong
857      * @param {Number} t Time value used to compute current value
858      * @param {Number} b Starting value
859      * @param {Number} c Delta between start and end values
860      * @param {Number} d Total length of animation
861      * @return {Number} The computed value for the current animation frame
862      */
863     easeInStrong: function (t, b, c, d) {
864         return c*(t/=d)*t*t*t + b;
865     },
866     
867     /**
868      * Begins quickly and decelerates towards end.  (quartic)
869      * @method easeOutStrong
870      * @param {Number} t Time value used to compute current value
871      * @param {Number} b Starting value
872      * @param {Number} c Delta between start and end values
873      * @param {Number} d Total length of animation
874      * @return {Number} The computed value for the current animation frame
875      */
876     easeOutStrong: function (t, b, c, d) {
877         return -c * ((t=t/d-1)*t*t*t - 1) + b;
878     },
879     
880     /**
881      * Begins slowly and decelerates towards end. (quartic)
882      * @method easeBothStrong
883      * @param {Number} t Time value used to compute current value
884      * @param {Number} b Starting value
885      * @param {Number} c Delta between start and end values
886      * @param {Number} d Total length of animation
887      * @return {Number} The computed value for the current animation frame
888      */
889     easeBothStrong: function (t, b, c, d) {
890         if ((t/=d/2) < 1) {
891             return c/2*t*t*t*t + b;
892         }
893         
894         return -c/2 * ((t-=2)*t*t*t - 2) + b;
895     },
896
897     /**
898      * Snap in elastic effect.
899      * @method elasticIn
900      * @param {Number} t Time value used to compute current value
901      * @param {Number} b Starting value
902      * @param {Number} c Delta between start and end values
903      * @param {Number} d Total length of animation
904      * @param {Number} a Amplitude (optional)
905      * @param {Number} p Period (optional)
906      * @return {Number} The computed value for the current animation frame
907      */
908
909     elasticIn: function (t, b, c, d, a, p) {
910         var s;
911         if (t === 0) {
912             return b;
913         }
914         if ( (t /= d) === 1 ) {
915             return b+c;
916         }
917         if (!p) {
918             p = d* 0.3;
919         }
920         
921         if (!a || a < Math.abs(c)) {
922             a = c; 
923             s = p/4;
924         }
925         else {
926             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     },
931
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         var s;
945         if (t === 0) {
946             return b;
947         }
948         if ( (t /= d) === 1 ) {
949             return b+c;
950         }
951         if (!p) {
952             p=d * 0.3;
953         }
954         
955         if (!a || a < Math.abs(c)) {
956             a = c;
957             s = p / 4;
958         }
959         else {
960             s = p/(2*Math.PI) * Math.asin (c/a);
961         }
962         
963         return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
964     },
965     
966     /**
967      * Snap both elastic effect.
968      * @method elasticBoth
969      * @param {Number} t Time value used to compute current value
970      * @param {Number} b Starting value
971      * @param {Number} c Delta between start and end values
972      * @param {Number} d Total length of animation
973      * @param {Number} a Amplitude (optional)
974      * @param {Number} p Period (optional)
975      * @return {Number} The computed value for the current animation frame
976      */
977     elasticBoth: function (t, b, c, d, a, p) {
978         var s;
979         if (t === 0) {
980             return b;
981         }
982         
983         if ( (t /= d/2) === 2 ) {
984             return b+c;
985         }
986         
987         if (!p) {
988             p = d*(0.3*1.5);
989         }
990         
991         if ( !a || a < Math.abs(c) ) {
992             a = c; 
993             s = p/4;
994         }
995         else {
996             s = p/(2*Math.PI) * Math.asin (c/a);
997         }
998         
999         if (t < 1) {
1000             return -0.5*(a*Math.pow(2,10*(t-=1)) * 
1001                     Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
1002         }
1003         return a*Math.pow(2,-10*(t-=1)) * 
1004                 Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b;
1005     },
1006
1007
1008     /**
1009      * Backtracks slightly, then reverses direction and moves to end.
1010      * @method backIn
1011      * @param {Number} t Time value used to compute current value
1012      * @param {Number} b Starting value
1013      * @param {Number} c Delta between start and end values
1014      * @param {Number} d Total length of animation
1015      * @param {Number} s Overshoot (optional)
1016      * @return {Number} The computed value for the current animation frame
1017      */
1018     backIn: function (t, b, c, d, s) {
1019         if (s === undefined) {
1020             s = 1.70158;
1021         }
1022         if (t === d) {
1023             t -= 0.001;
1024         }
1025         return c*(t/=d)*t*((s+1)*t - s) + b;
1026     },
1027
1028     /**
1029      * Overshoots end, then reverses and comes back to end.
1030      * @method backOut
1031      * @param {Number} t Time value used to compute current value
1032      * @param {Number} b Starting value
1033      * @param {Number} c Delta between start and end values
1034      * @param {Number} d Total length of animation
1035      * @param {Number} s Overshoot (optional)
1036      * @return {Number} The computed value for the current animation frame
1037      */
1038     backOut: function (t, b, c, d, s) {
1039         if (typeof s === 'undefined') {
1040             s = 1.70158;
1041         }
1042         return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
1043     },
1044     
1045     /**
1046      * Backtracks slightly, then reverses direction, overshoots end, 
1047      * then reverses and comes back to end.
1048      * @method backBoth
1049      * @param {Number} t Time value used to compute current value
1050      * @param {Number} b Starting value
1051      * @param {Number} c Delta between start and end values
1052      * @param {Number} d Total length of animation
1053      * @param {Number} s Overshoot (optional)
1054      * @return {Number} The computed value for the current animation frame
1055      */
1056     backBoth: function (t, b, c, d, s) {
1057         if (typeof s === 'undefined') {
1058             s = 1.70158; 
1059         }
1060         
1061         if ((t /= d/2 ) < 1) {
1062             return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
1063         }
1064         return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
1065     },
1066
1067     /**
1068      * Bounce off of start.
1069      * @method bounceIn
1070      * @param {Number} t Time value used to compute current value
1071      * @param {Number} b Starting value
1072      * @param {Number} c Delta between start and end values
1073      * @param {Number} d Total length of animation
1074      * @return {Number} The computed value for the current animation frame
1075      */
1076     bounceIn: function (t, b, c, d) {
1077         return c - Y.Easing.bounceOut(d-t, 0, c, d) + b;
1078     },
1079     
1080     /**
1081      * Bounces off end.
1082      * @method bounceOut
1083      * @param {Number} t Time value used to compute current value
1084      * @param {Number} b Starting value
1085      * @param {Number} c Delta between start and end values
1086      * @param {Number} d Total length of animation
1087      * @return {Number} The computed value for the current animation frame
1088      */
1089     bounceOut: function (t, b, c, d) {
1090         if ((t/=d) < (1/2.75)) {
1091                 return c*(7.5625*t*t) + b;
1092         } else if (t < (2/2.75)) {
1093                 return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
1094         } else if (t < (2.5/2.75)) {
1095                 return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
1096         }
1097         return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
1098     },
1099     
1100     /**
1101      * Bounces off start and end.
1102      * @method bounceBoth
1103      * @param {Number} t Time value used to compute current value
1104      * @param {Number} b Starting value
1105      * @param {Number} c Delta between start and end values
1106      * @param {Number} d Total length of animation
1107      * @return {Number} The computed value for the current animation frame
1108      */
1109     bounceBoth: function (t, b, c, d) {
1110         if (t < d/2) {
1111             return Y.Easing.bounceIn(t * 2, 0, c, d) * 0.5 + b;
1112         }
1113         return Y.Easing.bounceOut(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;
1114     }
1115 };
1116
1117 Y.Easing = Easing;
1118
1119
1120 }, '3.3.0' ,{requires:['anim-base']});
1121 YUI.add('anim-node-plugin', function(Y) {
1122
1123 /**
1124  *  Binds an Anim instance to a Node instance
1125  * @module anim
1126  * @class Plugin.NodeFX
1127  * @extends Base
1128  * @submodule anim-node-plugin
1129  */
1130
1131 var NodeFX = function(config) {
1132     config = (config) ? Y.merge(config) : {};
1133     config.node = config.host;
1134     NodeFX.superclass.constructor.apply(this, arguments);
1135 };
1136
1137 NodeFX.NAME = "nodefx";
1138 NodeFX.NS = "fx";
1139
1140 Y.extend(NodeFX, Y.Anim);
1141
1142 Y.namespace('Plugin');
1143 Y.Plugin.NodeFX = NodeFX;
1144
1145
1146 }, '3.3.0' ,{requires:['node-pluginhost', 'anim-base']});
1147 YUI.add('anim-scroll', function(Y) {
1148
1149 /**
1150  * Adds support for the <code>scroll</code> property in <code>to</code>
1151  * and <code>from</code> attributes.
1152  * @module anim
1153  * @submodule anim-scroll
1154  */
1155
1156 var NUM = Number;
1157
1158 //TODO: deprecate for scrollTop/Left properties?
1159 Y.Anim.behaviors.scroll = {
1160     set: function(anim, att, from, to, elapsed, duration, fn) {
1161         var
1162             node = anim._node, 
1163             val = ([
1164             fn(elapsed, NUM(from[0]), NUM(to[0]) - NUM(from[0]), duration),
1165             fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)
1166         ]);
1167
1168         if (val[0]) {
1169             node.set('scrollLeft', val[0]);
1170         }
1171
1172         if (val[1]) {
1173             node.set('scrollTop', val[1]);
1174         }
1175     },
1176     get: function(anim) {
1177         var node = anim._node;
1178         return [node.get('scrollLeft'), node.get('scrollTop')];
1179     }
1180 };
1181
1182
1183
1184 }, '3.3.0' ,{requires:['anim-base']});
1185 YUI.add('anim-xy', function(Y) {
1186
1187 /**
1188  * Adds support for the <code>xy</code> property in <code>from</code> and 
1189  * <code>to</code> attributes.
1190  * @module anim
1191  * @submodule anim-xy
1192  */
1193
1194 var NUM = Number;
1195
1196 Y.Anim.behaviors.xy = {
1197     set: function(anim, att, from, to, elapsed, duration, fn) {
1198         anim._node.setXY([
1199             fn(elapsed, NUM(from[0]), NUM(to[0]) - NUM(from[0]), duration),
1200             fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)
1201         ]);
1202     },
1203     get: function(anim) {
1204         return anim._node.getXY();
1205     }
1206 };
1207
1208
1209
1210 }, '3.3.0' ,{requires:['anim-base', 'node-screen']});
1211
1212
1213 YUI.add('anim', function(Y){}, '3.3.0' ,{use:['anim-base', 'anim-color', 'anim-curve', 'anim-easing', 'anim-node-plugin', 'anim-scroll', 'anim-xy'], skinnable:false});
1214