2 Copyright (c) 2008, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
12 Copyright (c) 2006, Yahoo! Inc. All rights reserved.
13 Code licensed under the BSD License:
14 http://developer.yahoo.net/yui/license.txt
18 * The animation module provides allows effects to be added to HTMLElements.
20 * @requires yahoo, event, dom
25 * Base animation class that provides the interface for building animated effects.
26 * <p>Usage: var myAnim = new YAHOO.util.Anim(el, { width: { from: 10, to: 100 } }, 1, YAHOO.util.Easing.easeOut);</p>
28 * @namespace YAHOO.util
29 * @requires YAHOO.util.AnimMgr
30 * @requires YAHOO.util.Easing
31 * @requires YAHOO.util.Dom
32 * @requires YAHOO.util.Event
33 * @requires YAHOO.util.CustomEvent
35 * @param {String | HTMLElement} el Reference to the element that will be animated
36 * @param {Object} attributes The attribute(s) to be animated.
37 * Each attribute is an object with at minimum a "to" or "by" member defined.
38 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
39 * All attribute names use camelCase.
40 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
41 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
44 var Anim = function(el
, attributes
, duration
, method
) {
47 this.init(el
, attributes
, duration
, method
);
54 * Provides a readable name for the Anim instance.
58 toString: function() {
59 var el
= this.getEl() || {};
60 var id
= el
.id
|| el
.tagName
;
61 return (this.constructor.NAME
+ ': ' + id
);
64 patterns
: { // cached for performance
65 noNegatives
: /width|height|opacity|padding/i, // keep at zero or above
66 offsetAttribute
: /^((width|height)|(top|left))$/, // use offsetValue as default
67 defaultUnit
: /width|height|top$|bottom$|left$|right$/i, // use 'px' by default
68 offsetUnit
: /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i // IE may return these, so convert these to offset
72 * Returns the value computed by the animation's "method".
74 * @param {String} attr The name of the attribute.
75 * @param {Number} start The value this attribute should start from for this animation.
76 * @param {Number} end The value this attribute should end at for this animation.
77 * @return {Number} The Value to be applied to the attribute.
79 doMethod: function(attr
, start
, end
) {
80 return this.method(this.currentFrame
, start
, end
- start
, this.totalFrames
);
84 * Applies a value to an attribute.
85 * @method setAttribute
86 * @param {String} attr The name of the attribute.
87 * @param {Number} val The value to be applied to the attribute.
88 * @param {String} unit The unit ('px', '%', etc.) of the value.
90 setAttribute: function(attr
, val
, unit
) {
91 if ( this.patterns
.noNegatives
.test(attr
) ) {
92 val
= (val
> 0) ? val
: 0;
95 Y
.Dom
.setStyle(this.getEl(), attr
, val
+ unit
);
99 * Returns current value of the attribute.
100 * @method getAttribute
101 * @param {String} attr The name of the attribute.
102 * @return {Number} val The current value of the attribute.
104 getAttribute: function(attr
) {
105 var el
= this.getEl();
106 var val
= Y
.Dom
.getStyle(el
, attr
);
108 if (val
!== 'auto' && !this.patterns
.offsetUnit
.test(val
)) {
109 return parseFloat(val
);
112 var a
= this.patterns
.offsetAttribute
.exec(attr
) || [];
113 var pos
= !!( a
[3] ); // top or left
114 var box
= !!( a
[2] ); // width or height
116 // use offsets for width/height and abs pos top/left
117 if ( box
|| (Y
.Dom
.getStyle(el
, 'position') == 'absolute' && pos
) ) {
118 val
= el
['offset' + a
[0].charAt(0).toUpperCase() + a
[0].substr(1)];
119 } else { // default to zero for other 'auto'
127 * Returns the unit to use when none is supplied.
128 * @method getDefaultUnit
129 * @param {attr} attr The name of the attribute.
130 * @return {String} The default unit to be used.
132 getDefaultUnit: function(attr
) {
133 if ( this.patterns
.defaultUnit
.test(attr
) ) {
141 * Sets the actual values to be used during the animation. Should only be needed for subclass use.
142 * @method setRuntimeAttribute
143 * @param {Object} attr The attribute object
146 setRuntimeAttribute: function(attr
) {
149 var attributes
= this.attributes
;
151 this.runtimeAttributes
[attr
] = {};
153 var isset = function(prop
) {
154 return (typeof prop
!== 'undefined');
157 if ( !isset(attributes
[attr
]['to']) && !isset(attributes
[attr
]['by']) ) {
158 return false; // note return; nothing to animate to
161 start
= ( isset(attributes
[attr
]['from']) ) ? attributes
[attr
]['from'] : this.getAttribute(attr
);
163 // To beats by, per SMIL 2.1 spec
164 if ( isset(attributes
[attr
]['to']) ) {
165 end
= attributes
[attr
]['to'];
166 } else if ( isset(attributes
[attr
]['by']) ) {
167 if (start
.constructor == Array
) {
169 for (var i
= 0, len
= start
.length
; i
< len
; ++i
) {
170 end
[i
] = start
[i
] + attributes
[attr
]['by'][i
] * 1; // times 1 to cast "by"
173 end
= start
+ attributes
[attr
]['by'] * 1;
177 this.runtimeAttributes
[attr
].start
= start
;
178 this.runtimeAttributes
[attr
].end
= end
;
180 // set units if needed
181 this.runtimeAttributes
[attr
].unit
= ( isset(attributes
[attr
].unit
) ) ?
182 attributes
[attr
]['unit'] : this.getDefaultUnit(attr
);
187 * Constructor for Anim instance.
189 * @param {String | HTMLElement} el Reference to the element that will be animated
190 * @param {Object} attributes The attribute(s) to be animated.
191 * Each attribute is an object with at minimum a "to" or "by" member defined.
192 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
193 * All attribute names use camelCase.
194 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
195 * @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)
197 init: function(el
, attributes
, duration
, method
) {
199 * Whether or not the animation is running.
200 * @property isAnimated
204 var isAnimated
= false;
207 * A Date object that is created when the animation begins.
208 * @property startTime
212 var startTime
= null;
215 * The number of frames this animation was able to execute.
216 * @property actualFrames
220 var actualFrames
= 0;
223 * The element to be animated.
231 * The collection of attributes to be animated.
232 * Each attribute must have at least a "to" or "by" defined in order to animate.
233 * If "to" is supplied, the animation will end with the attribute at that value.
234 * If "by" is supplied, the animation will end at that value plus its starting value.
235 * If both are supplied, "to" is used, and "by" is ignored.
236 * 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).
237 * @property attributes
240 this.attributes
= attributes
|| {};
243 * The length of the animation. Defaults to "1" (second).
247 this.duration
= !YAHOO
.lang
.isUndefined(duration
) ? duration
: 1;
250 * The method that will provide values to the attribute(s) during the animation.
251 * Defaults to "YAHOO.util.Easing.easeNone".
255 this.method
= method
|| Y
.Easing
.easeNone
;
258 * Whether or not the duration should be treated as seconds.
260 * @property useSeconds
263 this.useSeconds
= true; // default to seconds
266 * The location of the current animation on the timeline.
267 * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
268 * @property currentFrame
271 this.currentFrame
= 0;
274 * The total number of frames to be executed.
275 * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
276 * @property totalFrames
279 this.totalFrames
= Y
.AnimMgr
.fps
;
282 * Changes the animated element
285 this.setEl = function(element
) {
286 el
= Y
.Dom
.get(element
);
290 * Returns a reference to the animated element.
292 * @return {HTMLElement}
294 this.getEl = function() { return el
; };
297 * Checks whether the element is currently animated.
299 * @return {Boolean} current value of isAnimated.
301 this.isAnimated = function() {
306 * Returns the animation start time.
307 * @method getStartTime
308 * @return {Date} current value of startTime.
310 this.getStartTime = function() {
314 this.runtimeAttributes
= {};
319 * Starts the animation by registering it with the animation manager.
322 this.animate = function() {
323 if ( this.isAnimated() ) {
327 this.currentFrame
= 0;
329 this.totalFrames
= ( this.useSeconds
) ? Math
.ceil(Y
.AnimMgr
.fps
* this.duration
) : this.duration
;
331 if (this.duration
=== 0 && this.useSeconds
) { // jump to last frame if zero second duration
332 this.totalFrames
= 1;
334 Y
.AnimMgr
.registerElement(this);
339 * Stops the animation. Normally called by AnimMgr when animation completes.
341 * @param {Boolean} finish (optional) If true, animation will jump to final frame.
343 this.stop = function(finish
) {
344 if (!this.isAnimated()) { // nothing to stop
349 this.currentFrame
= this.totalFrames
;
350 this._onTween
.fire();
352 Y
.AnimMgr
.stop(this);
355 var onStart = function() {
358 this.runtimeAttributes
= {};
359 for (var attr
in this.attributes
) {
360 this.setRuntimeAttribute(attr
);
365 startTime
= new Date();
369 * Feeds the starting and ending values for each animated attribute to doMethod once per frame, then applies the resulting value to the attribute(s).
373 var onTween = function() {
375 duration
: new Date() - this.getStartTime(),
376 currentFrame
: this.currentFrame
379 data
.toString = function() {
381 'duration: ' + data
.duration
+
382 ', currentFrame: ' + data
.currentFrame
386 this.onTween
.fire(data
);
388 var runtimeAttributes
= this.runtimeAttributes
;
390 for (var attr
in runtimeAttributes
) {
391 this.setAttribute(attr
, this.doMethod(attr
, runtimeAttributes
[attr
].start
, runtimeAttributes
[attr
].end
), runtimeAttributes
[attr
].unit
);
397 var onComplete = function() {
398 var actual_duration
= (new Date() - startTime
) / 1000 ;
401 duration
: actual_duration
,
402 frames
: actualFrames
,
403 fps
: actualFrames
/ actual_duration
406 data
.toString = function() {
408 'duration: ' + data
.duration
+
409 ', frames: ' + data
.frames
+
416 this.onComplete
.fire(data
);
420 * Custom event that fires after onStart, useful in subclassing
423 this._onStart
= new Y
.CustomEvent('_start', this, true);
426 * Custom event that fires when animation begins
427 * Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)
430 this.onStart
= new Y
.CustomEvent('start', this);
433 * Custom event that fires between each frame
434 * Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)
437 this.onTween
= new Y
.CustomEvent('tween', this);
440 * Custom event that fires after onTween
443 this._onTween
= new Y
.CustomEvent('_tween', this, true);
446 * Custom event that fires when animation ends
447 * Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)
450 this.onComplete
= new Y
.CustomEvent('complete', this);
452 * Custom event that fires after onComplete
455 this._onComplete
= new Y
.CustomEvent('_complete', this, true);
457 this._onStart
.subscribe(onStart
);
458 this._onTween
.subscribe(onTween
);
459 this._onComplete
.subscribe(onComplete
);
466 * Handles animation queueing and threading.
467 * Used by Anim and subclasses.
469 * @namespace YAHOO.util
471 YAHOO
.util
.AnimMgr
= new function() {
473 * Reference to the animation Interval.
481 * The current queue of registered animation objects.
489 * The number of active animations.
490 * @property tweenCount
497 * Base frame rate (frames per second).
498 * Arbitrarily high for better x-browser calibration (slower browsers drop more frames).
506 * Interval delay in milliseconds, defaults to fastest possible.
514 * Adds an animation instance to the animation queue.
515 * All animation instances must be registered in order to animate.
516 * @method registerElement
517 * @param {object} tween The Anim instance to be be registered
519 this.registerElement = function(tween
) {
520 queue
[queue
.length
] = tween
;
522 tween
._onStart
.fire();
527 * removes an animation instance from the animation queue.
528 * All animation instances must be registered in order to animate.
530 * @param {object} tween The Anim instance to be be registered
531 * @param {Int} index The index of the Anim instance
534 this.unRegister = function(tween
, index
) {
535 index
= index
|| getIndex(tween
);
536 if (!tween
.isAnimated() || index
== -1) {
540 tween
._onComplete
.fire();
541 queue
.splice(index
, 1);
544 if (tweenCount
<= 0) {
552 * Starts the animation thread.
553 * Only one thread can run at a time.
556 this.start = function() {
557 if (thread
=== null) {
558 thread
= setInterval(this.run
, this.delay
);
563 * Stops the animation thread or a specific animation instance.
565 * @param {object} tween A specific Anim instance to stop (optional)
566 * If no instance given, Manager stops thread and all animations.
568 this.stop = function(tween
) {
570 clearInterval(thread
);
572 for (var i
= 0, len
= queue
.length
; i
< len
; ++i
) {
573 this.unRegister(queue
[0], 0);
581 this.unRegister(tween
);
586 * Called per Interval to handle each animation frame.
589 this.run = function() {
590 for (var i
= 0, len
= queue
.length
; i
< len
; ++i
) {
591 var tween
= queue
[i
];
592 if ( !tween
|| !tween
.isAnimated() ) { continue; }
594 if (tween
.currentFrame
< tween
.totalFrames
|| tween
.totalFrames
=== null)
596 tween
.currentFrame
+= 1;
598 if (tween
.useSeconds
) {
601 tween
._onTween
.fire();
603 else { YAHOO
.util
.AnimMgr
.stop(tween
, i
); }
607 var getIndex = function(anim
) {
608 for (var i
= 0, len
= queue
.length
; i
< len
; ++i
) {
609 if (queue
[i
] == anim
) {
610 return i
; // note return;
617 * On the fly frame correction to keep animation on time.
618 * @method correctFrame
620 * @param {Object} tween The Anim instance being corrected.
622 var correctFrame = function(tween
) {
623 var frames
= tween
.totalFrames
;
624 var frame
= tween
.currentFrame
;
625 var expected
= (tween
.currentFrame
* tween
.duration
* 1000 / tween
.totalFrames
);
626 var elapsed
= (new Date() - tween
.getStartTime());
629 if (elapsed
< tween
.duration
* 1000) { // check if falling behind
630 tweak
= Math
.round((elapsed
/ expected
- 1) * tween
.currentFrame
);
631 } else { // went over duration, so jump to end
632 tweak
= frames
- (frame
+ 1);
634 if (tweak
> 0 && isFinite(tweak
)) { // adjust if needed
635 if (tween
.currentFrame
+ tweak
>= frames
) {// dont go past last frame
636 tweak
= frames
- (frame
+ 1);
639 tween
.currentFrame
+= tweak
;
644 * Used to calculate Bezier splines for any number of control points.
646 * @namespace YAHOO.util
649 YAHOO
.util
.Bezier
= new function() {
651 * Get the current position of the animated element based on t.
652 * Each point is an array of "x" and "y" values (0 = x, 1 = y)
653 * At least 2 points are required (start and end).
654 * First point is start. Last point is end.
655 * Additional control points are optional.
656 * @method getPosition
657 * @param {Array} points An array containing Bezier points
658 * @param {Number} t A number between 0 and 1 which is the basis for determining current position
659 * @return {Array} An array containing int x and y member data
661 this.getPosition = function(points
, t
) {
662 var n
= points
.length
;
665 for (var i
= 0; i
< n
; ++i
){
666 tmp
[i
] = [points
[i
][0], points
[i
][1]]; // save input
669 for (var j
= 1; j
< n
; ++j
) {
670 for (i
= 0; i
< n
- j
; ++i
) {
671 tmp
[i
][0] = (1 - t
) * tmp
[i
][0] + t
* tmp
[parseInt(i
+ 1, 10)][0];
672 tmp
[i
][1] = (1 - t
) * tmp
[i
][1] + t
* tmp
[parseInt(i
+ 1, 10)][1];
676 return [ tmp
[0][0], tmp
[0][1] ];
682 * Anim subclass for color transitions.
683 * <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,
684 * [255,255,255], or rgb(255,255,255)</p>
686 * @namespace YAHOO.util
687 * @requires YAHOO.util.Anim
688 * @requires YAHOO.util.AnimMgr
689 * @requires YAHOO.util.Easing
690 * @requires YAHOO.util.Bezier
691 * @requires YAHOO.util.Dom
692 * @requires YAHOO.util.Event
694 * @extends YAHOO.util.Anim
695 * @param {HTMLElement | String} el Reference to the element that will be animated
696 * @param {Object} attributes The attribute(s) to be animated.
697 * Each attribute is an object with at minimum a "to" or "by" member defined.
698 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
699 * All attribute names use camelCase.
700 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
701 * @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)
703 var ColorAnim = function(el
, attributes
, duration
, method
) {
704 ColorAnim
.superclass
.constructor.call(this, el
, attributes
, duration
, method
);
707 ColorAnim
.NAME
= 'ColorAnim';
711 YAHOO
.extend(ColorAnim
, Y
.Anim
);
713 var superclass
= ColorAnim
.superclass
;
714 var proto
= ColorAnim
.prototype;
716 proto
.patterns
.color
= /color$/i;
717 proto
.patterns
.rgb
= /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
718 proto
.patterns
.hex
= /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
719 proto
.patterns
.hex3
= /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;
720 proto
.patterns
.transparent
= /^transparent|rgba\(0, 0, 0, 0\)$/; // need rgba for safari
723 * Attempts to parse the given string and return a 3-tuple.
725 * @param {String} s The string to parse.
726 * @return {Array} The 3-tuple of rgb values.
728 proto
.parseColor = function(s
) {
729 if (s
.length
== 3) { return s
; }
731 var c
= this.patterns
.hex
.exec(s
);
732 if (c
&& c
.length
== 4) {
733 return [ parseInt(c
[1], 16), parseInt(c
[2], 16), parseInt(c
[3], 16) ];
736 c
= this.patterns
.rgb
.exec(s
);
737 if (c
&& c
.length
== 4) {
738 return [ parseInt(c
[1], 10), parseInt(c
[2], 10), parseInt(c
[3], 10) ];
741 c
= this.patterns
.hex3
.exec(s
);
742 if (c
&& c
.length
== 4) {
743 return [ parseInt(c
[1] + c
[1], 16), parseInt(c
[2] + c
[2], 16), parseInt(c
[3] + c
[3], 16) ];
749 proto
.getAttribute = function(attr
) {
750 var el
= this.getEl();
751 if ( this.patterns
.color
.test(attr
) ) {
752 var val
= YAHOO
.util
.Dom
.getStyle(el
, attr
);
754 if (this.patterns
.transparent
.test(val
)) { // bgcolor default
755 var parent
= el
.parentNode
; // try and get from an ancestor
756 val
= Y
.Dom
.getStyle(parent
, attr
);
758 while (parent
&& this.patterns
.transparent
.test(val
)) {
759 parent
= parent
.parentNode
;
760 val
= Y
.Dom
.getStyle(parent
, attr
);
761 if (parent
.tagName
.toUpperCase() == 'HTML') {
767 val
= superclass
.getAttribute
.call(this, attr
);
773 proto
.doMethod = function(attr
, start
, end
) {
776 if ( this.patterns
.color
.test(attr
) ) {
778 for (var i
= 0, len
= start
.length
; i
< len
; ++i
) {
779 val
[i
] = superclass
.doMethod
.call(this, attr
, start
[i
], end
[i
]);
782 val
= 'rgb('+Math
.floor(val
[0])+','+Math
.floor(val
[1])+','+Math
.floor(val
[2])+')';
785 val
= superclass
.doMethod
.call(this, attr
, start
, end
);
791 proto
.setRuntimeAttribute = function(attr
) {
792 superclass
.setRuntimeAttribute
.call(this, attr
);
794 if ( this.patterns
.color
.test(attr
) ) {
795 var attributes
= this.attributes
;
796 var start
= this.parseColor(this.runtimeAttributes
[attr
].start
);
797 var end
= this.parseColor(this.runtimeAttributes
[attr
].end
);
798 // fix colors if going "by"
799 if ( typeof attributes
[attr
]['to'] === 'undefined' && typeof attributes
[attr
]['by'] !== 'undefined' ) {
800 end
= this.parseColor(attributes
[attr
].by
);
802 for (var i
= 0, len
= start
.length
; i
< len
; ++i
) {
803 end
[i
] = start
[i
] + end
[i
];
807 this.runtimeAttributes
[attr
].start
= start
;
808 this.runtimeAttributes
[attr
].end
= end
;
812 Y
.ColorAnim
= ColorAnim
;
815 TERMS OF USE - EASING EQUATIONS
816 Open source under the BSD License.
817 Copyright 2001 Robert Penner All rights reserved.
819 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
821 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
822 * 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.
823 * 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.
825 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.
829 * Singleton that determines how an animation proceeds from start to end.
831 * @namespace YAHOO.util
834 YAHOO
.util
.Easing
= {
837 * Uniform speed between points.
839 * @param {Number} t Time value used to compute current value
840 * @param {Number} b Starting value
841 * @param {Number} c Delta between start and end values
842 * @param {Number} d Total length of animation
843 * @return {Number} The computed value for the current animation frame
845 easeNone: function (t
, b
, c
, d
) {
850 * Begins slowly and accelerates towards end. (quadratic)
852 * @param {Number} t Time value used to compute current value
853 * @param {Number} b Starting value
854 * @param {Number} c Delta between start and end values
855 * @param {Number} d Total length of animation
856 * @return {Number} The computed value for the current animation frame
858 easeIn: function (t
, b
, c
, d
) {
859 return c
*(t
/=d
)*t
+ b
;
863 * Begins quickly and decelerates towards end. (quadratic)
865 * @param {Number} t Time value used to compute current value
866 * @param {Number} b Starting value
867 * @param {Number} c Delta between start and end values
868 * @param {Number} d Total length of animation
869 * @return {Number} The computed value for the current animation frame
871 easeOut: function (t
, b
, c
, d
) {
872 return -c
*(t
/=d
)*(t
-2) + b
;
876 * Begins slowly and decelerates towards end. (quadratic)
878 * @param {Number} t Time value used to compute current value
879 * @param {Number} b Starting value
880 * @param {Number} c Delta between start and end values
881 * @param {Number} d Total length of animation
882 * @return {Number} The computed value for the current animation frame
884 easeBoth: function (t
, b
, c
, d
) {
889 return -c
/2 * ((--t
)*(t
-2) - 1) + b
;
893 * Begins slowly and accelerates towards end. (quartic)
894 * @method easeInStrong
895 * @param {Number} t Time value used to compute current value
896 * @param {Number} b Starting value
897 * @param {Number} c Delta between start and end values
898 * @param {Number} d Total length of animation
899 * @return {Number} The computed value for the current animation frame
901 easeInStrong: function (t
, b
, c
, d
) {
902 return c
*(t
/=d
)*t
*t
*t
+ b
;
906 * Begins quickly and decelerates towards end. (quartic)
907 * @method easeOutStrong
908 * @param {Number} t Time value used to compute current value
909 * @param {Number} b Starting value
910 * @param {Number} c Delta between start and end values
911 * @param {Number} d Total length of animation
912 * @return {Number} The computed value for the current animation frame
914 easeOutStrong: function (t
, b
, c
, d
) {
915 return -c
* ((t
=t
/d
-1)*t
*t
*t
- 1) + b
;
919 * Begins slowly and decelerates towards end. (quartic)
920 * @method easeBothStrong
921 * @param {Number} t Time value used to compute current value
922 * @param {Number} b Starting value
923 * @param {Number} c Delta between start and end values
924 * @param {Number} d Total length of animation
925 * @return {Number} The computed value for the current animation frame
927 easeBothStrong: function (t
, b
, c
, d
) {
929 return c
/2*t
*t
*t
*t
+ b
;
932 return -c
/2 * ((t
-=2)*t
*t
*t
- 2) + b
;
936 * Snap in elastic effect.
938 * @param {Number} t Time value used to compute current value
939 * @param {Number} b Starting value
940 * @param {Number} c Delta between start and end values
941 * @param {Number} d Total length of animation
942 * @param {Number} a Amplitude (optional)
943 * @param {Number} p Period (optional)
944 * @return {Number} The computed value for the current animation frame
947 elasticIn: function (t
, b
, c
, d
, a
, p
) {
951 if ( (t
/= d
) == 1 ) {
958 if (!a
|| a
< Math
.abs(c
)) {
963 var s
= p
/(2*Math.PI) * Math.asin (c/a);
966 return -(a
*Math
.pow(2,10*(t
-=1)) * Math
.sin( (t
*d
-s
)*(2*Math
.PI
)/p
)) + b
;
970 * Snap out elastic effect.
972 * @param {Number} t Time value used to compute current value
973 * @param {Number} b Starting value
974 * @param {Number} c Delta between start and end values
975 * @param {Number} d Total length of animation
976 * @param {Number} a Amplitude (optional)
977 * @param {Number} p Period (optional)
978 * @return {Number} The computed value for the current animation frame
980 elasticOut: function (t
, b
, c
, d
, a
, p
) {
984 if ( (t
/= d
) == 1 ) {
991 if (!a
|| a
< Math
.abs(c
)) {
996 var s
= p
/(2*Math.PI) * Math.asin (c/a);
999 return a
*Math
.pow(2,-10*t
) * Math
.sin( (t
*d
-s
)*(2*Math
.PI
)/p
) + c
+ b
;
1003 * Snap both elastic effect.
1004 * @method elasticBoth
1005 * @param {Number} t Time value used to compute current value
1006 * @param {Number} b Starting value
1007 * @param {Number} c Delta between start and end values
1008 * @param {Number} d Total length of animation
1009 * @param {Number} a Amplitude (optional)
1010 * @param {Number} p Period (optional)
1011 * @return {Number} The computed value for the current animation frame
1013 elasticBoth: function (t
, b
, c
, d
, a
, p
) {
1018 if ( (t
/= d/2) == 2 ) {
1026 if ( !a
|| a
< Math
.abs(c
) ) {
1031 var s
= p
/(2*Math.PI) * Math.asin (c/a);
1035 return -.5*(a
*Math
.pow(2,10*(t
-=1)) *
1036 Math
.sin( (t
*d
-s
)*(2*Math
.PI
)/p
)) + b
;
1038 return a
*Math
.pow(2,-10*(t
-=1)) *
1039 Math
.sin( (t
*d
-s
)*(2*Math
.PI
)/p
)*.5 + c
+ b
;
1044 * Backtracks slightly, then reverses direction and moves to end.
1046 * @param {Number} t Time value used to compute current value
1047 * @param {Number} b Starting value
1048 * @param {Number} c Delta between start and end values
1049 * @param {Number} d Total length of animation
1050 * @param {Number} s Overshoot (optional)
1051 * @return {Number} The computed value for the current animation frame
1053 backIn: function (t
, b
, c
, d
, s
) {
1054 if (typeof s
== 'undefined') {
1057 return c
*(t
/=d
)*t
*((s
+1)*t
- s
) + b
;
1061 * Overshoots end, then reverses and comes back to end.
1063 * @param {Number} t Time value used to compute current value
1064 * @param {Number} b Starting value
1065 * @param {Number} c Delta between start and end values
1066 * @param {Number} d Total length of animation
1067 * @param {Number} s Overshoot (optional)
1068 * @return {Number} The computed value for the current animation frame
1070 backOut: function (t
, b
, c
, d
, s
) {
1071 if (typeof s
== 'undefined') {
1074 return c
*((t
=t
/d
-1)*t
*((s
+1)*t
+ s
) + 1) + b
;
1078 * Backtracks slightly, then reverses direction, overshoots end,
1079 * then reverses and comes back to end.
1081 * @param {Number} t Time value used to compute current value
1082 * @param {Number} b Starting value
1083 * @param {Number} c Delta between start and end values
1084 * @param {Number} d Total length of animation
1085 * @param {Number} s Overshoot (optional)
1086 * @return {Number} The computed value for the current animation frame
1088 backBoth: function (t
, b
, c
, d
, s
) {
1089 if (typeof s
== 'undefined') {
1093 if ((t
/= d/2 ) < 1) {
1094 return c
/2*(t
*t
*(((s
*=(1.525))+1)*t
- s
)) + b
;
1096 return c
/2*((t
-=2)*t
*(((s
*=(1.525))+1)*t
+ s
) + 2) + b
;
1100 * Bounce off of start.
1102 * @param {Number} t Time value used to compute current value
1103 * @param {Number} b Starting value
1104 * @param {Number} c Delta between start and end values
1105 * @param {Number} d Total length of animation
1106 * @return {Number} The computed value for the current animation frame
1108 bounceIn: function (t
, b
, c
, d
) {
1109 return c
- YAHOO
.util
.Easing
.bounceOut(d
-t
, 0, c
, d
) + b
;
1115 * @param {Number} t Time value used to compute current value
1116 * @param {Number} b Starting value
1117 * @param {Number} c Delta between start and end values
1118 * @param {Number} d Total length of animation
1119 * @return {Number} The computed value for the current animation frame
1121 bounceOut: function (t
, b
, c
, d
) {
1122 if ((t
/=d) < (1/2.75)) {
1123 return c
*(7.5625*t
*t
) + b
;
1124 } else if (t
< (2/2.75)) {
1125 return c
*(7.5625*(t
-=(1.5/2.75))*t
+ .75) + b
;
1126 } else if (t
< (2.5/2.75)) {
1127 return c
*(7.5625*(t
-=(2.25/2.75))*t
+ .9375) + b
;
1129 return c
*(7.5625*(t
-=(2.625/2.75))*t
+ .984375) + b
;
1133 * Bounces off start and end.
1134 * @method bounceBoth
1135 * @param {Number} t Time value used to compute current value
1136 * @param {Number} b Starting value
1137 * @param {Number} c Delta between start and end values
1138 * @param {Number} d Total length of animation
1139 * @return {Number} The computed value for the current animation frame
1141 bounceBoth: function (t
, b
, c
, d
) {
1143 return YAHOO
.util
.Easing
.bounceIn(t
*2, 0, c
, d
) * .5 + b
;
1145 return YAHOO
.util
.Easing
.bounceOut(t
*2-d
, 0, c
, d
) * .5 + c
*.5 + b
;
1151 * Anim subclass for moving elements along a path defined by the "points"
1152 * member of "attributes". All "points" are arrays with x, y coordinates.
1153 * <p>Usage: <code>var myAnim = new YAHOO.util.Motion(el, { points: { to: [800, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
1155 * @namespace YAHOO.util
1156 * @requires YAHOO.util.Anim
1157 * @requires YAHOO.util.AnimMgr
1158 * @requires YAHOO.util.Easing
1159 * @requires YAHOO.util.Bezier
1160 * @requires YAHOO.util.Dom
1161 * @requires YAHOO.util.Event
1162 * @requires YAHOO.util.CustomEvent
1164 * @extends YAHOO.util.ColorAnim
1165 * @param {String | HTMLElement} el Reference to the element that will be animated
1166 * @param {Object} attributes The attribute(s) to be animated.
1167 * Each attribute is an object with at minimum a "to" or "by" member defined.
1168 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
1169 * All attribute names use camelCase.
1170 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
1171 * @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)
1173 var Motion = function(el
, attributes
, duration
, method
) {
1174 if (el
) { // dont break existing subclasses not using YAHOO.extend
1175 Motion
.superclass
.constructor.call(this, el
, attributes
, duration
, method
);
1180 Motion
.NAME
= 'Motion';
1184 YAHOO
.extend(Motion
, Y
.ColorAnim
);
1186 var superclass
= Motion
.superclass
;
1187 var proto
= Motion
.prototype;
1189 proto
.patterns
.points
= /^points$/i;
1191 proto
.setAttribute = function(attr
, val
, unit
) {
1192 if ( this.patterns
.points
.test(attr
) ) {
1193 unit
= unit
|| 'px';
1194 superclass
.setAttribute
.call(this, 'left', val
[0], unit
);
1195 superclass
.setAttribute
.call(this, 'top', val
[1], unit
);
1197 superclass
.setAttribute
.call(this, attr
, val
, unit
);
1201 proto
.getAttribute = function(attr
) {
1202 if ( this.patterns
.points
.test(attr
) ) {
1204 superclass
.getAttribute
.call(this, 'left'),
1205 superclass
.getAttribute
.call(this, 'top')
1208 val
= superclass
.getAttribute
.call(this, attr
);
1214 proto
.doMethod = function(attr
, start
, end
) {
1217 if ( this.patterns
.points
.test(attr
) ) {
1218 var t
= this.method(this.currentFrame
, 0, 100, this.totalFrames
) / 100;
1219 val
= Y
.Bezier
.getPosition(this.runtimeAttributes
[attr
], t
);
1221 val
= superclass
.doMethod
.call(this, attr
, start
, end
);
1226 proto
.setRuntimeAttribute = function(attr
) {
1227 if ( this.patterns
.points
.test(attr
) ) {
1228 var el
= this.getEl();
1229 var attributes
= this.attributes
;
1231 var control
= attributes
['points']['control'] || [];
1235 if (control
.length
> 0 && !(control
[0] instanceof Array
) ) { // could be single point or array of points
1236 control
= [control
];
1237 } else { // break reference to attributes.points.control
1239 for (i
= 0, len
= control
.length
; i
< len
; ++i
) {
1240 tmp
[i
] = control
[i
];
1245 if (Y
.Dom
.getStyle(el
, 'position') == 'static') { // default to relative
1246 Y
.Dom
.setStyle(el
, 'position', 'relative');
1249 if ( isset(attributes
['points']['from']) ) {
1250 Y
.Dom
.setXY(el
, attributes
['points']['from']); // set position to from point
1252 else { Y
.Dom
.setXY( el
, Y
.Dom
.getXY(el
) ); } // set it to current position
1254 start
= this.getAttribute('points'); // get actual top & left
1256 // TO beats BY, per SMIL 2.1 spec
1257 if ( isset(attributes
['points']['to']) ) {
1258 end
= translateValues
.call(this, attributes
['points']['to'], start
);
1260 var pageXY
= Y
.Dom
.getXY(this.getEl());
1261 for (i
= 0, len
= control
.length
; i
< len
; ++i
) {
1262 control
[i
] = translateValues
.call(this, control
[i
], start
);
1266 } else if ( isset(attributes
['points']['by']) ) {
1267 end
= [ start
[0] + attributes
['points']['by'][0], start
[1] + attributes
['points']['by'][1] ];
1269 for (i
= 0, len
= control
.length
; i
< len
; ++i
) {
1270 control
[i
] = [ start
[0] + control
[i
][0], start
[1] + control
[i
][1] ];
1274 this.runtimeAttributes
[attr
] = [start
];
1276 if (control
.length
> 0) {
1277 this.runtimeAttributes
[attr
] = this.runtimeAttributes
[attr
].concat(control
);
1280 this.runtimeAttributes
[attr
][this.runtimeAttributes
[attr
].length
] = end
;
1283 superclass
.setRuntimeAttribute
.call(this, attr
);
1287 var translateValues = function(val
, start
) {
1288 var pageXY
= Y
.Dom
.getXY(this.getEl());
1289 val
= [ val
[0] - pageXY
[0] + start
[0], val
[1] - pageXY
[1] + start
[1] ];
1294 var isset = function(prop
) {
1295 return (typeof prop
!== 'undefined');
1302 * Anim subclass for scrolling elements to a position defined by the "scroll"
1303 * member of "attributes". All "scroll" members are arrays with x, y scroll positions.
1304 * <p>Usage: <code>var myAnim = new YAHOO.util.Scroll(el, { scroll: { to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
1306 * @namespace YAHOO.util
1307 * @requires YAHOO.util.Anim
1308 * @requires YAHOO.util.AnimMgr
1309 * @requires YAHOO.util.Easing
1310 * @requires YAHOO.util.Bezier
1311 * @requires YAHOO.util.Dom
1312 * @requires YAHOO.util.Event
1313 * @requires YAHOO.util.CustomEvent
1314 * @extends YAHOO.util.ColorAnim
1316 * @param {String or HTMLElement} el Reference to the element that will be animated
1317 * @param {Object} attributes The attribute(s) to be animated.
1318 * Each attribute is an object with at minimum a "to" or "by" member defined.
1319 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
1320 * All attribute names use camelCase.
1321 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
1322 * @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)
1324 var Scroll = function(el
, attributes
, duration
, method
) {
1325 if (el
) { // dont break existing subclasses not using YAHOO.extend
1326 Scroll
.superclass
.constructor.call(this, el
, attributes
, duration
, method
);
1330 Scroll
.NAME
= 'Scroll';
1334 YAHOO
.extend(Scroll
, Y
.ColorAnim
);
1336 var superclass
= Scroll
.superclass
;
1337 var proto
= Scroll
.prototype;
1339 proto
.doMethod = function(attr
, start
, end
) {
1342 if (attr
== 'scroll') {
1344 this.method(this.currentFrame
, start
[0], end
[0] - start
[0], this.totalFrames
),
1345 this.method(this.currentFrame
, start
[1], end
[1] - start
[1], this.totalFrames
)
1349 val
= superclass
.doMethod
.call(this, attr
, start
, end
);
1354 proto
.getAttribute = function(attr
) {
1356 var el
= this.getEl();
1358 if (attr
== 'scroll') {
1359 val
= [ el
.scrollLeft
, el
.scrollTop
];
1361 val
= superclass
.getAttribute
.call(this, attr
);
1367 proto
.setAttribute = function(attr
, val
, unit
) {
1368 var el
= this.getEl();
1370 if (attr
== 'scroll') {
1371 el
.scrollLeft
= val
[0];
1372 el
.scrollTop
= val
[1];
1374 superclass
.setAttribute
.call(this, attr
, val
, unit
);
1380 YAHOO
.register("animation", YAHOO
.util
.Anim
, {version
: "2.5.2", build
: "1076"});