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