2 Copyright (c) 2009, 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 var el = this.getEl();
92 if ( this.patterns.noNegatives.test(attr) ) {
93 val = (val > 0) ? val : 0;
97 Y.Dom.setStyle(el, attr, val + unit);
98 } else if (attr in el) {
104 * Returns current value of the attribute.
105 * @method getAttribute
106 * @param {String} attr The name of the attribute.
107 * @return {Number} val The current value of the attribute.
109 getAttribute: function(attr) {
110 var el = this.getEl();
111 var val = Y.Dom.getStyle(el, attr);
113 if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
114 return parseFloat(val);
117 var a = this.patterns.offsetAttribute.exec(attr) || [];
118 var pos = !!( a[3] ); // top or left
119 var box = !!( a[2] ); // width or height
122 // use offsets for width/height and abs pos top/left
123 if ( box || (Y.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
124 val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
125 } else { // default to zero for other 'auto'
128 } else if (attr in el) {
136 * Returns the unit to use when none is supplied.
137 * @method getDefaultUnit
138 * @param {attr} attr The name of the attribute.
139 * @return {String} The default unit to be used.
141 getDefaultUnit: function(attr) {
142 if ( this.patterns.defaultUnit.test(attr) ) {
150 * Sets the actual values to be used during the animation. Should only be needed for subclass use.
151 * @method setRuntimeAttribute
152 * @param {Object} attr The attribute object
155 setRuntimeAttribute: function(attr) {
158 var attributes = this.attributes;
160 this.runtimeAttributes[attr] = {};
162 var isset = function(prop) {
163 return (typeof prop !== 'undefined');
166 if ( !isset(attributes[attr]['to']) && !isset(attributes[attr]['by']) ) {
167 return false; // note return; nothing to animate to
170 start = ( isset(attributes[attr]['from']) ) ? attributes[attr]['from'] : this.getAttribute(attr);
172 // To beats by, per SMIL 2.1 spec
173 if ( isset(attributes[attr]['to']) ) {
174 end = attributes[attr]['to'];
175 } else if ( isset(attributes[attr]['by']) ) {
176 if (start.constructor == Array) {
178 for (var i = 0, len = start.length; i < len; ++i) {
179 end[i] = start[i] + attributes[attr]['by'][i] * 1; // times 1 to cast "by"
182 end = start + attributes[attr]['by'] * 1;
186 this.runtimeAttributes[attr].start = start;
187 this.runtimeAttributes[attr].end = end;
189 // set units if needed
190 this.runtimeAttributes[attr].unit = ( isset(attributes[attr].unit) ) ?
191 attributes[attr]['unit'] : this.getDefaultUnit(attr);
196 * Constructor for Anim instance.
198 * @param {String | HTMLElement} el Reference to the element that will be animated
199 * @param {Object} attributes The attribute(s) to be animated.
200 * Each attribute is an object with at minimum a "to" or "by" member defined.
201 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
202 * All attribute names use camelCase.
203 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
204 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
206 init: function(el, attributes, duration, method) {
208 * Whether or not the animation is running.
209 * @property isAnimated
213 var isAnimated = false;
216 * A Date object that is created when the animation begins.
217 * @property startTime
221 var startTime = null;
224 * The number of frames this animation was able to execute.
225 * @property actualFrames
229 var actualFrames = 0;
232 * The element to be animated.
240 * The collection of attributes to be animated.
241 * Each attribute must have at least a "to" or "by" defined in order to animate.
242 * If "to" is supplied, the animation will end with the attribute at that value.
243 * If "by" is supplied, the animation will end at that value plus its starting value.
244 * If both are supplied, "to" is used, and "by" is ignored.
245 * Optional additional member include "from" (the value the attribute should start animating from, defaults to current value), and "unit" (the units to apply to the values).
246 * @property attributes
249 this.attributes = attributes || {};
252 * The length of the animation. Defaults to "1" (second).
256 this.duration = !YAHOO.lang.isUndefined(duration) ? duration : 1;
259 * The method that will provide values to the attribute(s) during the animation.
260 * Defaults to "YAHOO.util.Easing.easeNone".
264 this.method = method || Y.Easing.easeNone;
267 * Whether or not the duration should be treated as seconds.
269 * @property useSeconds
272 this.useSeconds = true; // default to seconds
275 * The location of the current animation on the timeline.
276 * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
277 * @property currentFrame
280 this.currentFrame = 0;
283 * The total number of frames to be executed.
284 * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
285 * @property totalFrames
288 this.totalFrames = Y.AnimMgr.fps;
291 * Changes the animated element
294 this.setEl = function(element) {
295 el = Y.Dom.get(element);
299 * Returns a reference to the animated element.
301 * @return {HTMLElement}
303 this.getEl = function() { return el; };
306 * Checks whether the element is currently animated.
308 * @return {Boolean} current value of isAnimated.
310 this.isAnimated = function() {
315 * Returns the animation start time.
316 * @method getStartTime
317 * @return {Date} current value of startTime.
319 this.getStartTime = function() {
323 this.runtimeAttributes = {};
328 * Starts the animation by registering it with the animation manager.
331 this.animate = function() {
332 if ( this.isAnimated() ) {
336 this.currentFrame = 0;
338 this.totalFrames = ( this.useSeconds ) ? Math.ceil(Y.AnimMgr.fps * this.duration) : this.duration;
340 if (this.duration === 0 && this.useSeconds) { // jump to last frame if zero second duration
341 this.totalFrames = 1;
343 Y.AnimMgr.registerElement(this);
348 * Stops the animation. Normally called by AnimMgr when animation completes.
350 * @param {Boolean} finish (optional) If true, animation will jump to final frame.
352 this.stop = function(finish) {
353 if (!this.isAnimated()) { // nothing to stop
358 this.currentFrame = this.totalFrames;
359 this._onTween.fire();
361 Y.AnimMgr.stop(this);
364 var onStart = function() {
367 this.runtimeAttributes = {};
368 for (var attr in this.attributes) {
369 this.setRuntimeAttribute(attr);
374 startTime = new Date();
378 * Feeds the starting and ending values for each animated attribute to doMethod once per frame, then applies the resulting value to the attribute(s).
382 var onTween = function() {
384 duration: new Date() - this.getStartTime(),
385 currentFrame: this.currentFrame
388 data.toString = function() {
390 'duration: ' + data.duration +
391 ', currentFrame: ' + data.currentFrame
395 this.onTween.fire(data);
397 var runtimeAttributes = this.runtimeAttributes;
399 for (var attr in runtimeAttributes) {
400 this.setAttribute(attr, this.doMethod(attr, runtimeAttributes[attr].start, runtimeAttributes[attr].end), runtimeAttributes[attr].unit);
406 var onComplete = function() {
407 var actual_duration = (new Date() - startTime) / 1000 ;
410 duration: actual_duration,
411 frames: actualFrames,
412 fps: actualFrames / actual_duration
415 data.toString = function() {
417 'duration: ' + data.duration +
418 ', frames: ' + data.frames +
425 this.onComplete.fire(data);
429 * Custom event that fires after onStart, useful in subclassing
432 this._onStart = new Y.CustomEvent('_start', this, true);
435 * Custom event that fires when animation begins
436 * Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)
439 this.onStart = new Y.CustomEvent('start', this);
442 * Custom event that fires between each frame
443 * Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)
446 this.onTween = new Y.CustomEvent('tween', this);
449 * Custom event that fires after onTween
452 this._onTween = new Y.CustomEvent('_tween', this, true);
455 * Custom event that fires when animation ends
456 * Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)
459 this.onComplete = new Y.CustomEvent('complete', this);
461 * Custom event that fires after onComplete
464 this._onComplete = new Y.CustomEvent('_complete', this, true);
466 this._onStart.subscribe(onStart);
467 this._onTween.subscribe(onTween);
468 this._onComplete.subscribe(onComplete);
475 * Handles animation queueing and threading.
476 * Used by Anim and subclasses.
478 * @namespace YAHOO.util
480 YAHOO.util.AnimMgr = new function() {
482 * Reference to the animation Interval.
490 * The current queue of registered animation objects.
498 * The number of active animations.
499 * @property tweenCount
506 * Base frame rate (frames per second).
507 * Arbitrarily high for better x-browser calibration (slower browsers drop more frames).
515 * Interval delay in milliseconds, defaults to fastest possible.
523 * Adds an animation instance to the animation queue.
524 * All animation instances must be registered in order to animate.
525 * @method registerElement
526 * @param {object} tween The Anim instance to be be registered
528 this.registerElement = function(tween) {
529 queue[queue.length] = tween;
531 tween._onStart.fire();
536 * removes an animation instance from the animation queue.
537 * All animation instances must be registered in order to animate.
539 * @param {object} tween The Anim instance to be be registered
540 * @param {Int} index The index of the Anim instance
543 this.unRegister = function(tween, index) {
544 index = index || getIndex(tween);
545 if (!tween.isAnimated() || index == -1) {
549 tween._onComplete.fire();
550 queue.splice(index, 1);
553 if (tweenCount <= 0) {
561 * Starts the animation thread.
562 * Only one thread can run at a time.
565 this.start = function() {
566 if (thread === null) {
567 thread = setInterval(this.run, this.delay);
572 * Stops the animation thread or a specific animation instance.
574 * @param {object} tween A specific Anim instance to stop (optional)
575 * If no instance given, Manager stops thread and all animations.
577 this.stop = function(tween) {
579 clearInterval(thread);
581 for (var i = 0, len = queue.length; i < len; ++i) {
582 this.unRegister(queue[0], 0);
590 this.unRegister(tween);
595 * Called per Interval to handle each animation frame.
598 this.run = function() {
599 for (var i = 0, len = queue.length; i < len; ++i) {
600 var tween = queue[i];
601 if ( !tween || !tween.isAnimated() ) { continue; }
603 if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
605 tween.currentFrame += 1;
607 if (tween.useSeconds) {
610 tween._onTween.fire();
612 else { YAHOO.util.AnimMgr.stop(tween, i); }
616 var getIndex = function(anim) {
617 for (var i = 0, len = queue.length; i < len; ++i) {
618 if (queue[i] == anim) {
619 return i; // note return;
626 * On the fly frame correction to keep animation on time.
627 * @method correctFrame
629 * @param {Object} tween The Anim instance being corrected.
631 var correctFrame = function(tween) {
632 var frames = tween.totalFrames;
633 var frame = tween.currentFrame;
634 var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
635 var elapsed = (new Date() - tween.getStartTime());
638 if (elapsed < tween.duration * 1000) { // check if falling behind
639 tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
640 } else { // went over duration, so jump to end
641 tweak = frames - (frame + 1);
643 if (tweak > 0 && isFinite(tweak)) { // adjust if needed
644 if (tween.currentFrame + tweak >= frames) {// dont go past last frame
645 tweak = frames - (frame + 1);
648 tween.currentFrame += tweak;
653 * Used to calculate Bezier splines for any number of control points.
655 * @namespace YAHOO.util
658 YAHOO.util.Bezier = new function() {
660 * Get the current position of the animated element based on t.
661 * Each point is an array of "x" and "y" values (0 = x, 1 = y)
662 * At least 2 points are required (start and end).
663 * First point is start. Last point is end.
664 * Additional control points are optional.
665 * @method getPosition
666 * @param {Array} points An array containing Bezier points
667 * @param {Number} t A number between 0 and 1 which is the basis for determining current position
668 * @return {Array} An array containing int x and y member data
670 this.getPosition = function(points, t) {
671 var n = points.length;
674 for (var i = 0; i < n; ++i){
675 tmp[i] = [points[i][0], points[i][1]]; // save input
678 for (var j = 1; j < n; ++j) {
679 for (i = 0; i < n - j; ++i) {
680 tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
681 tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
685 return [ tmp[0][0], tmp[0][1] ];
691 * Anim subclass for color transitions.
692 * <p>Usage: <code>var myAnim = new Y.ColorAnim(el, { backgroundColor: { from: '#FF0000', to: '#FFFFFF' } }, 1, Y.Easing.easeOut);</code> Color values can be specified with either 112233, #112233,
693 * [255,255,255], or rgb(255,255,255)</p>
695 * @namespace YAHOO.util
696 * @requires YAHOO.util.Anim
697 * @requires YAHOO.util.AnimMgr
698 * @requires YAHOO.util.Easing
699 * @requires YAHOO.util.Bezier
700 * @requires YAHOO.util.Dom
701 * @requires YAHOO.util.Event
703 * @extends YAHOO.util.Anim
704 * @param {HTMLElement | String} el Reference to the element that will be animated
705 * @param {Object} attributes The attribute(s) to be animated.
706 * Each attribute is an object with at minimum a "to" or "by" member defined.
707 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
708 * All attribute names use camelCase.
709 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
710 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
712 var ColorAnim = function(el, attributes, duration, method) {
713 ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
716 ColorAnim.NAME = 'ColorAnim';
718 ColorAnim.DEFAULT_BGCOLOR = '#fff';
721 YAHOO.extend(ColorAnim, Y.Anim);
723 var superclass = ColorAnim.superclass;
724 var proto = ColorAnim.prototype;
726 proto.patterns.color = /color$/i;
727 proto.patterns.rgb = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
728 proto.patterns.hex = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
729 proto.patterns.hex3 = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;
730 proto.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/; // need rgba for safari
733 * Attempts to parse the given string and return a 3-tuple.
735 * @param {String} s The string to parse.
736 * @return {Array} The 3-tuple of rgb values.
738 proto.parseColor = function(s) {
739 if (s.length == 3) { return s; }
741 var c = this.patterns.hex.exec(s);
742 if (c && c.length == 4) {
743 return [ parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16) ];
746 c = this.patterns.rgb.exec(s);
747 if (c && c.length == 4) {
748 return [ parseInt(c[1], 10), parseInt(c[2], 10), parseInt(c[3], 10) ];
751 c = this.patterns.hex3.exec(s);
752 if (c && c.length == 4) {
753 return [ parseInt(c[1] + c[1], 16), parseInt(c[2] + c[2], 16), parseInt(c[3] + c[3], 16) ];
759 proto.getAttribute = function(attr) {
760 var el = this.getEl();
761 if (this.patterns.color.test(attr) ) {
762 var val = YAHOO.util.Dom.getStyle(el, attr);
765 if (this.patterns.transparent.test(val)) { // bgcolor default
766 var parent = YAHOO.util.Dom.getAncestorBy(el, function(node) {
767 return !that.patterns.transparent.test(val);
771 val = Y.Dom.getStyle(parent, attr);
773 val = ColorAnim.DEFAULT_BGCOLOR;
777 val = superclass.getAttribute.call(this, attr);
783 proto.doMethod = function(attr, start, end) {
786 if ( this.patterns.color.test(attr) ) {
788 for (var i = 0, len = start.length; i < len; ++i) {
789 val[i] = superclass.doMethod.call(this, attr, start[i], end[i]);
792 val = 'rgb('+Math.floor(val[0])+','+Math.floor(val[1])+','+Math.floor(val[2])+')';
795 val = superclass.doMethod.call(this, attr, start, end);
801 proto.setRuntimeAttribute = function(attr) {
802 superclass.setRuntimeAttribute.call(this, attr);
804 if ( this.patterns.color.test(attr) ) {
805 var attributes = this.attributes;
806 var start = this.parseColor(this.runtimeAttributes[attr].start);
807 var end = this.parseColor(this.runtimeAttributes[attr].end);
808 // fix colors if going "by"
809 if ( typeof attributes[attr]['to'] === 'undefined' && typeof attributes[attr]['by'] !== 'undefined' ) {
810 end = this.parseColor(attributes[attr].by);
812 for (var i = 0, len = start.length; i < len; ++i) {
813 end[i] = start[i] + end[i];
817 this.runtimeAttributes[attr].start = start;
818 this.runtimeAttributes[attr].end = end;
822 Y.ColorAnim = ColorAnim;
825 TERMS OF USE - EASING EQUATIONS
826 Open source under the BSD License.
827 Copyright 2001 Robert Penner All rights reserved.
829 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
831 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
832 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
833 * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
835 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
839 * Singleton that determines how an animation proceeds from start to end.
841 * @namespace YAHOO.util
844 YAHOO.util.Easing = {
847 * Uniform speed between points.
849 * @param {Number} t Time value used to compute current value
850 * @param {Number} b Starting value
851 * @param {Number} c Delta between start and end values
852 * @param {Number} d Total length of animation
853 * @return {Number} The computed value for the current animation frame
855 easeNone: function (t, b, c, d) {
860 * Begins slowly and accelerates towards end.
862 * @param {Number} t Time value used to compute current value
863 * @param {Number} b Starting value
864 * @param {Number} c Delta between start and end values
865 * @param {Number} d Total length of animation
866 * @return {Number} The computed value for the current animation frame
868 easeIn: function (t, b, c, d) {
869 return c*(t/=d)*t + b;
873 * Begins quickly and decelerates towards end.
875 * @param {Number} t Time value used to compute current value
876 * @param {Number} b Starting value
877 * @param {Number} c Delta between start and end values
878 * @param {Number} d Total length of animation
879 * @return {Number} The computed value for the current animation frame
881 easeOut: function (t, b, c, d) {
882 return -c *(t/=d)*(t-2) + b;
886 * Begins slowly and decelerates towards end.
888 * @param {Number} t Time value used to compute current value
889 * @param {Number} b Starting value
890 * @param {Number} c Delta between start and end values
891 * @param {Number} d Total length of animation
892 * @return {Number} The computed value for the current animation frame
894 easeBoth: function (t, b, c, d) {
899 return -c/2 * ((--t)*(t-2) - 1) + b;
903 * Begins slowly and accelerates towards end.
904 * @method easeInStrong
905 * @param {Number} t Time value used to compute current value
906 * @param {Number} b Starting value
907 * @param {Number} c Delta between start and end values
908 * @param {Number} d Total length of animation
909 * @return {Number} The computed value for the current animation frame
911 easeInStrong: function (t, b, c, d) {
912 return c*(t/=d)*t*t*t + b;
916 * Begins quickly and decelerates towards end.
917 * @method easeOutStrong
918 * @param {Number} t Time value used to compute current value
919 * @param {Number} b Starting value
920 * @param {Number} c Delta between start and end values
921 * @param {Number} d Total length of animation
922 * @return {Number} The computed value for the current animation frame
924 easeOutStrong: function (t, b, c, d) {
925 return -c * ((t=t/d-1)*t*t*t - 1) + b;
929 * Begins slowly and decelerates towards end.
930 * @method easeBothStrong
931 * @param {Number} t Time value used to compute current value
932 * @param {Number} b Starting value
933 * @param {Number} c Delta between start and end values
934 * @param {Number} d Total length of animation
935 * @return {Number} The computed value for the current animation frame
937 easeBothStrong: function (t, b, c, d) {
939 return c/2*t*t*t*t + b;
942 return -c/2 * ((t-=2)*t*t*t - 2) + b;
946 * Snap in elastic effect.
948 * @param {Number} t Time value used to compute current value
949 * @param {Number} b Starting value
950 * @param {Number} c Delta between start and end values
951 * @param {Number} d Total length of animation
952 * @param {Number} a Amplitude (optional)
953 * @param {Number} p Period (optional)
954 * @return {Number} The computed value for the current animation frame
957 elasticIn: function (t, b, c, d, a, p) {
961 if ( (t /= d) == 1 ) {
968 if (!a || a < Math.abs(c)) {
973 var s = p/(2*Math.PI) * Math.asin (c/a);
976 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
980 * Snap out elastic effect.
982 * @param {Number} t Time value used to compute current value
983 * @param {Number} b Starting value
984 * @param {Number} c Delta between start and end values
985 * @param {Number} d Total length of animation
986 * @param {Number} a Amplitude (optional)
987 * @param {Number} p Period (optional)
988 * @return {Number} The computed value for the current animation frame
990 elasticOut: function (t, b, c, d, a, p) {
994 if ( (t /= d) == 1 ) {
1001 if (!a || a < Math.abs(c)) {
1006 var s = p/(2*Math.PI) * Math.asin (c/a);
1009 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
1013 * Snap both elastic effect.
1014 * @method elasticBoth
1015 * @param {Number} t Time value used to compute current value
1016 * @param {Number} b Starting value
1017 * @param {Number} c Delta between start and end values
1018 * @param {Number} d Total length of animation
1019 * @param {Number} a Amplitude (optional)
1020 * @param {Number} p Period (optional)
1021 * @return {Number} The computed value for the current animation frame
1023 elasticBoth: function (t, b, c, d, a, p) {
1028 if ( (t /= d/2) == 2 ) {
1036 if ( !a || a < Math.abs(c) ) {
1041 var s = p/(2*Math.PI) * Math.asin (c/a);
1045 return -.5*(a*Math.pow(2,10*(t-=1)) *
1046 Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
1048 return a*Math.pow(2,-10*(t-=1)) *
1049 Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
1054 * Backtracks slightly, then reverses direction and moves to end.
1056 * @param {Number} t Time value used to compute current value
1057 * @param {Number} b Starting value
1058 * @param {Number} c Delta between start and end values
1059 * @param {Number} d Total length of animation
1060 * @param {Number} s Overshoot (optional)
1061 * @return {Number} The computed value for the current animation frame
1063 backIn: function (t, b, c, d, s) {
1064 if (typeof s == 'undefined') {
1067 return c*(t/=d)*t*((s+1)*t - s) + b;
1071 * Overshoots end, then reverses and comes back to end.
1073 * @param {Number} t Time value used to compute current value
1074 * @param {Number} b Starting value
1075 * @param {Number} c Delta between start and end values
1076 * @param {Number} d Total length of animation
1077 * @param {Number} s Overshoot (optional)
1078 * @return {Number} The computed value for the current animation frame
1080 backOut: function (t, b, c, d, s) {
1081 if (typeof s == 'undefined') {
1084 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
1088 * Backtracks slightly, then reverses direction, overshoots end,
1089 * then reverses and comes back to end.
1091 * @param {Number} t Time value used to compute current value
1092 * @param {Number} b Starting value
1093 * @param {Number} c Delta between start and end values
1094 * @param {Number} d Total length of animation
1095 * @param {Number} s Overshoot (optional)
1096 * @return {Number} The computed value for the current animation frame
1098 backBoth: function (t, b, c, d, s) {
1099 if (typeof s == 'undefined') {
1103 if ((t /= d/2 ) < 1) {
1104 return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
1106 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
1110 * Bounce off of start.
1112 * @param {Number} t Time value used to compute current value
1113 * @param {Number} b Starting value
1114 * @param {Number} c Delta between start and end values
1115 * @param {Number} d Total length of animation
1116 * @return {Number} The computed value for the current animation frame
1118 bounceIn: function (t, b, c, d) {
1119 return c - YAHOO.util.Easing.bounceOut(d-t, 0, c, d) + b;
1125 * @param {Number} t Time value used to compute current value
1126 * @param {Number} b Starting value
1127 * @param {Number} c Delta between start and end values
1128 * @param {Number} d Total length of animation
1129 * @return {Number} The computed value for the current animation frame
1131 bounceOut: function (t, b, c, d) {
1132 if ((t/=d) < (1/2.75)) {
1133 return c*(7.5625*t*t) + b;
1134 } else if (t < (2/2.75)) {
1135 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
1136 } else if (t < (2.5/2.75)) {
1137 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
1139 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
1143 * Bounces off start and end.
1144 * @method bounceBoth
1145 * @param {Number} t Time value used to compute current value
1146 * @param {Number} b Starting value
1147 * @param {Number} c Delta between start and end values
1148 * @param {Number} d Total length of animation
1149 * @return {Number} The computed value for the current animation frame
1151 bounceBoth: function (t, b, c, d) {
1153 return YAHOO.util.Easing.bounceIn(t*2, 0, c, d) * .5 + b;
1155 return YAHOO.util.Easing.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
1161 * Anim subclass for moving elements along a path defined by the "points"
1162 * member of "attributes". All "points" are arrays with x, y coordinates.
1163 * <p>Usage: <code>var myAnim = new YAHOO.util.Motion(el, { points: { to: [800, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
1165 * @namespace YAHOO.util
1166 * @requires YAHOO.util.Anim
1167 * @requires YAHOO.util.AnimMgr
1168 * @requires YAHOO.util.Easing
1169 * @requires YAHOO.util.Bezier
1170 * @requires YAHOO.util.Dom
1171 * @requires YAHOO.util.Event
1172 * @requires YAHOO.util.CustomEvent
1174 * @extends YAHOO.util.ColorAnim
1175 * @param {String | HTMLElement} el Reference to the element that will be animated
1176 * @param {Object} attributes The attribute(s) to be animated.
1177 * Each attribute is an object with at minimum a "to" or "by" member defined.
1178 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
1179 * All attribute names use camelCase.
1180 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
1181 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
1183 var Motion = function(el, attributes, duration, method) {
1184 if (el) { // dont break existing subclasses not using YAHOO.extend
1185 Motion.superclass.constructor.call(this, el, attributes, duration, method);
1190 Motion.NAME = 'Motion';
1194 YAHOO.extend(Motion, Y.ColorAnim);
1196 var superclass = Motion.superclass;
1197 var proto = Motion.prototype;
1199 proto.patterns.points = /^points$/i;
1201 proto.setAttribute = function(attr, val, unit) {
1202 if ( this.patterns.points.test(attr) ) {
1203 unit = unit || 'px';
1204 superclass.setAttribute.call(this, 'left', val[0], unit);
1205 superclass.setAttribute.call(this, 'top', val[1], unit);
1207 superclass.setAttribute.call(this, attr, val, unit);
1211 proto.getAttribute = function(attr) {
1212 if ( this.patterns.points.test(attr) ) {
1214 superclass.getAttribute.call(this, 'left'),
1215 superclass.getAttribute.call(this, 'top')
1218 val = superclass.getAttribute.call(this, attr);
1224 proto.doMethod = function(attr, start, end) {
1227 if ( this.patterns.points.test(attr) ) {
1228 var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;
1229 val = Y.Bezier.getPosition(this.runtimeAttributes[attr], t);
1231 val = superclass.doMethod.call(this, attr, start, end);
1236 proto.setRuntimeAttribute = function(attr) {
1237 if ( this.patterns.points.test(attr) ) {
1238 var el = this.getEl();
1239 var attributes = this.attributes;
1241 var control = attributes['points']['control'] || [];
1245 if (control.length > 0 && !(control[0] instanceof Array) ) { // could be single point or array of points
1246 control = [control];
1247 } else { // break reference to attributes.points.control
1249 for (i = 0, len = control.length; i< len; ++i) {
1250 tmp[i] = control[i];
1255 if (Y.Dom.getStyle(el, 'position') == 'static') { // default to relative
1256 Y.Dom.setStyle(el, 'position', 'relative');
1259 if ( isset(attributes['points']['from']) ) {
1260 Y.Dom.setXY(el, attributes['points']['from']); // set position to from point
1262 else { Y.Dom.setXY( el, Y.Dom.getXY(el) ); } // set it to current position
1264 start = this.getAttribute('points'); // get actual top & left
1266 // TO beats BY, per SMIL 2.1 spec
1267 if ( isset(attributes['points']['to']) ) {
1268 end = translateValues.call(this, attributes['points']['to'], start);
1270 var pageXY = Y.Dom.getXY(this.getEl());
1271 for (i = 0, len = control.length; i < len; ++i) {
1272 control[i] = translateValues.call(this, control[i], start);
1276 } else if ( isset(attributes['points']['by']) ) {
1277 end = [ start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1] ];
1279 for (i = 0, len = control.length; i < len; ++i) {
1280 control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
1284 this.runtimeAttributes[attr] = [start];
1286 if (control.length > 0) {
1287 this.runtimeAttributes[attr] = this.runtimeAttributes[attr].concat(control);
1290 this.runtimeAttributes[attr][this.runtimeAttributes[attr].length] = end;
1293 superclass.setRuntimeAttribute.call(this, attr);
1297 var translateValues = function(val, start) {
1298 var pageXY = Y.Dom.getXY(this.getEl());
1299 val = [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1] ];
1304 var isset = function(prop) {
1305 return (typeof prop !== 'undefined');
1312 * Anim subclass for scrolling elements to a position defined by the "scroll"
1313 * member of "attributes". All "scroll" members are arrays with x, y scroll positions.
1314 * <p>Usage: <code>var myAnim = new YAHOO.util.Scroll(el, { scroll: { to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
1316 * @namespace YAHOO.util
1317 * @requires YAHOO.util.Anim
1318 * @requires YAHOO.util.AnimMgr
1319 * @requires YAHOO.util.Easing
1320 * @requires YAHOO.util.Bezier
1321 * @requires YAHOO.util.Dom
1322 * @requires YAHOO.util.Event
1323 * @requires YAHOO.util.CustomEvent
1324 * @extends YAHOO.util.ColorAnim
1326 * @param {String or HTMLElement} el Reference to the element that will be animated
1327 * @param {Object} attributes The attribute(s) to be animated.
1328 * Each attribute is an object with at minimum a "to" or "by" member defined.
1329 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
1330 * All attribute names use camelCase.
1331 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
1332 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
1334 var Scroll = function(el, attributes, duration, method) {
1335 if (el) { // dont break existing subclasses not using YAHOO.extend
1336 Scroll.superclass.constructor.call(this, el, attributes, duration, method);
1340 Scroll.NAME = 'Scroll';
1344 YAHOO.extend(Scroll, Y.ColorAnim);
1346 var superclass = Scroll.superclass;
1347 var proto = Scroll.prototype;
1349 proto.doMethod = function(attr, start, end) {
1352 if (attr == 'scroll') {
1354 this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames),
1355 this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)
1359 val = superclass.doMethod.call(this, attr, start, end);
1364 proto.getAttribute = function(attr) {
1366 var el = this.getEl();
1368 if (attr == 'scroll') {
1369 val = [ el.scrollLeft, el.scrollTop ];
1371 val = superclass.getAttribute.call(this, attr);
1377 proto.setAttribute = function(attr, val, unit) {
1378 var el = this.getEl();
1380 if (attr == 'scroll') {
1381 el.scrollLeft = val[0];
1382 el.scrollTop = val[1];
1384 superclass.setAttribute.call(this, attr, val, unit);
1390 YAHOO.register("animation", YAHOO.util.Anim, {version: "2.7.0", build: "1799"});