MDL-10604:
[moodle-linuxchix.git] / lib / yui / animation / animation-debug.js
blob7745b235b76e32a322ee2da1d23ee31b1a476584
1 /*
2 Copyright (c) 2006, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
5 version: 0.12.2
6 */
7 /**
8 * The animation module provides allows effects to be added to HTMLElements.
9 * @module animation
10 * @requires yahoo, event, dom
13 /**
15 * Base animation class that provides the interface for building animated effects.
16 * <p>Usage: var myAnim = new YAHOO.util.Anim(el, { width: { from: 10, to: 100 } }, 1, YAHOO.util.Easing.easeOut);</p>
17 * @class Anim
18 * @namespace YAHOO.util
19 * @requires YAHOO.util.AnimMgr
20 * @requires YAHOO.util.Easing
21 * @requires YAHOO.util.Dom
22 * @requires YAHOO.util.Event
23 * @requires YAHOO.util.CustomEvent
24 * @constructor
25 * @param {String | HTMLElement} el Reference to the element that will be animated
26 * @param {Object} attributes The attribute(s) to be animated.
27 * Each attribute is an object with at minimum a "to" or "by" member defined.
28 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
29 * All attribute names use camelCase.
30 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
31 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
34 YAHOO.util.Anim = function(el, attributes, duration, method) {
35 if (el) {
36 this.init(el, attributes, duration, method);
40 YAHOO.util.Anim.prototype = {
41 /**
42 * Provides a readable name for the Anim instance.
43 * @method toString
44 * @return {String}
46 toString: function() {
47 var el = this.getEl();
48 var id = el.id || el.tagName;
49 return ("Anim " + id);
52 patterns: { // cached for performance
53 noNegatives: /width|height|opacity|padding/i, // keep at zero or above
54 offsetAttribute: /^((width|height)|(top|left))$/, // use offsetValue as default
55 defaultUnit: /width|height|top$|bottom$|left$|right$/i, // use 'px' by default
56 offsetUnit: /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i // IE may return these, so convert these to offset
59 /**
60 * Returns the value computed by the animation's "method".
61 * @method doMethod
62 * @param {String} attr The name of the attribute.
63 * @param {Number} start The value this attribute should start from for this animation.
64 * @param {Number} end The value this attribute should end at for this animation.
65 * @return {Number} The Value to be applied to the attribute.
67 doMethod: function(attr, start, end) {
68 return this.method(this.currentFrame, start, end - start, this.totalFrames);
71 /**
72 * Applies a value to an attribute.
73 * @method setAttribute
74 * @param {String} attr The name of the attribute.
75 * @param {Number} val The value to be applied to the attribute.
76 * @param {String} unit The unit ('px', '%', etc.) of the value.
78 setAttribute: function(attr, val, unit) {
79 if ( this.patterns.noNegatives.test(attr) ) {
80 val = (val > 0) ? val : 0;
83 YAHOO.util.Dom.setStyle(this.getEl(), attr, val + unit);
84 },
86 /**
87 * Returns current value of the attribute.
88 * @method getAttribute
89 * @param {String} attr The name of the attribute.
90 * @return {Number} val The current value of the attribute.
92 getAttribute: function(attr) {
93 var el = this.getEl();
94 var val = YAHOO.util.Dom.getStyle(el, attr);
96 if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
97 return parseFloat(val);
100 var a = this.patterns.offsetAttribute.exec(attr) || [];
101 var pos = !!( a[3] ); // top or left
102 var box = !!( a[2] ); // width or height
104 // use offsets for width/height and abs pos top/left
105 if ( box || (YAHOO.util.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
106 val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
107 } else { // default to zero for other 'auto'
108 val = 0;
111 return val;
115 * Returns the unit to use when none is supplied.
116 * @method getDefaultUnit
117 * @param {attr} attr The name of the attribute.
118 * @return {String} The default unit to be used.
120 getDefaultUnit: function(attr) {
121 if ( this.patterns.defaultUnit.test(attr) ) {
122 return 'px';
125 return '';
129 * Sets the actual values to be used during the animation. Should only be needed for subclass use.
130 * @method setRuntimeAttribute
131 * @param {Object} attr The attribute object
132 * @private
134 setRuntimeAttribute: function(attr) {
135 var start;
136 var end;
137 var attributes = this.attributes;
139 this.runtimeAttributes[attr] = {};
141 var isset = function(prop) {
142 return (typeof prop !== 'undefined');
145 if ( !isset(attributes[attr]['to']) && !isset(attributes[attr]['by']) ) {
146 return false; // note return; nothing to animate to
149 start = ( isset(attributes[attr]['from']) ) ? attributes[attr]['from'] : this.getAttribute(attr);
151 // To beats by, per SMIL 2.1 spec
152 if ( isset(attributes[attr]['to']) ) {
153 end = attributes[attr]['to'];
154 } else if ( isset(attributes[attr]['by']) ) {
155 if (start.constructor == Array) {
156 end = [];
157 for (var i = 0, len = start.length; i < len; ++i) {
158 end[i] = start[i] + attributes[attr]['by'][i];
160 } else {
161 end = start + attributes[attr]['by'];
165 this.runtimeAttributes[attr].start = start;
166 this.runtimeAttributes[attr].end = end;
168 // set units if needed
169 this.runtimeAttributes[attr].unit = ( isset(attributes[attr].unit) ) ? attributes[attr]['unit'] : this.getDefaultUnit(attr);
173 * Constructor for Anim instance.
174 * @method init
175 * @param {String | HTMLElement} el Reference to the element that will be animated
176 * @param {Object} attributes The attribute(s) to be animated.
177 * Each attribute is an object with at minimum a "to" or "by" member defined.
178 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
179 * All attribute names use camelCase.
180 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
181 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
183 init: function(el, attributes, duration, method) {
185 * Whether or not the animation is running.
186 * @property isAnimated
187 * @private
188 * @type Boolean
190 var isAnimated = false;
193 * A Date object that is created when the animation begins.
194 * @property startTime
195 * @private
196 * @type Date
198 var startTime = null;
201 * The number of frames this animation was able to execute.
202 * @property actualFrames
203 * @private
204 * @type Int
206 var actualFrames = 0;
209 * The element to be animated.
210 * @property el
211 * @private
212 * @type HTMLElement
214 el = YAHOO.util.Dom.get(el);
217 * The collection of attributes to be animated.
218 * Each attribute must have at least a "to" or "by" defined in order to animate.
219 * If "to" is supplied, the animation will end with the attribute at that value.
220 * If "by" is supplied, the animation will end at that value plus its starting value.
221 * If both are supplied, "to" is used, and "by" is ignored.
222 * Optional additional member include "from" (the value the attribute should start animating from, defaults to current value), and "unit" (the units to apply to the values).
223 * @property attributes
224 * @type Object
226 this.attributes = attributes || {};
229 * The length of the animation. Defaults to "1" (second).
230 * @property duration
231 * @type Number
233 this.duration = duration || 1;
236 * The method that will provide values to the attribute(s) during the animation.
237 * Defaults to "YAHOO.util.Easing.easeNone".
238 * @property method
239 * @type Function
241 this.method = method || YAHOO.util.Easing.easeNone;
244 * Whether or not the duration should be treated as seconds.
245 * Defaults to true.
246 * @property useSeconds
247 * @type Boolean
249 this.useSeconds = true; // default to seconds
252 * The location of the current animation on the timeline.
253 * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
254 * @property currentFrame
255 * @type Int
257 this.currentFrame = 0;
260 * The total number of frames to be executed.
261 * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
262 * @property totalFrames
263 * @type Int
265 this.totalFrames = YAHOO.util.AnimMgr.fps;
269 * Returns a reference to the animated element.
270 * @method getEl
271 * @return {HTMLElement}
273 this.getEl = function() { return el; };
276 * Checks whether the element is currently animated.
277 * @method isAnimated
278 * @return {Boolean} current value of isAnimated.
280 this.isAnimated = function() {
281 return isAnimated;
285 * Returns the animation start time.
286 * @method getStartTime
287 * @return {Date} current value of startTime.
289 this.getStartTime = function() {
290 return startTime;
293 this.runtimeAttributes = {};
295 var logger = {};
296 logger.log = function() {YAHOO.log.apply(window, arguments)};
298 logger.log('creating new instance of ' + this);
301 * Starts the animation by registering it with the animation manager.
302 * @method animate
304 this.animate = function() {
305 if ( this.isAnimated() ) {
306 return false;
309 this.currentFrame = 0;
311 this.totalFrames = ( this.useSeconds ) ? Math.ceil(YAHOO.util.AnimMgr.fps * this.duration) : this.duration;
313 YAHOO.util.AnimMgr.registerElement(this);
317 * Stops the animation. Normally called by AnimMgr when animation completes.
318 * @method stop
319 * @param {Boolean} finish (optional) If true, animation will jump to final frame.
321 this.stop = function(finish) {
322 if (finish) {
323 this.currentFrame = this.totalFrames;
324 this._onTween.fire();
326 YAHOO.util.AnimMgr.stop(this);
329 var onStart = function() {
330 this.onStart.fire();
332 this.runtimeAttributes = {};
333 for (var attr in this.attributes) {
334 this.setRuntimeAttribute(attr);
337 isAnimated = true;
338 actualFrames = 0;
339 startTime = new Date();
343 * Feeds the starting and ending values for each animated attribute to doMethod once per frame, then applies the resulting value to the attribute(s).
344 * @private
347 var onTween = function() {
348 var data = {
349 duration: new Date() - this.getStartTime(),
350 currentFrame: this.currentFrame
353 data.toString = function() {
354 return (
355 'duration: ' + data.duration +
356 ', currentFrame: ' + data.currentFrame
360 this.onTween.fire(data);
362 var runtimeAttributes = this.runtimeAttributes;
364 for (var attr in runtimeAttributes) {
365 this.setAttribute(attr, this.doMethod(attr, runtimeAttributes[attr].start, runtimeAttributes[attr].end), runtimeAttributes[attr].unit);
368 actualFrames += 1;
371 var onComplete = function() {
372 var actual_duration = (new Date() - startTime) / 1000 ;
374 var data = {
375 duration: actual_duration,
376 frames: actualFrames,
377 fps: actualFrames / actual_duration
380 data.toString = function() {
381 return (
382 'duration: ' + data.duration +
383 ', frames: ' + data.frames +
384 ', fps: ' + data.fps
388 isAnimated = false;
389 actualFrames = 0;
390 this.onComplete.fire(data);
394 * Custom event that fires after onStart, useful in subclassing
395 * @private
397 this._onStart = new YAHOO.util.CustomEvent('_start', this, true);
400 * Custom event that fires when animation begins
401 * Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)
402 * @event onStart
404 this.onStart = new YAHOO.util.CustomEvent('start', this);
407 * Custom event that fires between each frame
408 * Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)
409 * @event onTween
411 this.onTween = new YAHOO.util.CustomEvent('tween', this);
414 * Custom event that fires after onTween
415 * @private
417 this._onTween = new YAHOO.util.CustomEvent('_tween', this, true);
420 * Custom event that fires when animation ends
421 * Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)
422 * @event onComplete
424 this.onComplete = new YAHOO.util.CustomEvent('complete', this);
426 * Custom event that fires after onComplete
427 * @private
429 this._onComplete = new YAHOO.util.CustomEvent('_complete', this, true);
431 this._onStart.subscribe(onStart);
432 this._onTween.subscribe(onTween);
433 this._onComplete.subscribe(onComplete);
438 * Handles animation queueing and threading.
439 * Used by Anim and subclasses.
440 * @class AnimMgr
441 * @namespace YAHOO.util
443 YAHOO.util.AnimMgr = new function() {
444 /**
445 * Reference to the animation Interval.
446 * @property thread
447 * @private
448 * @type Int
450 var thread = null;
452 /**
453 * The current queue of registered animation objects.
454 * @property queue
455 * @private
456 * @type Array
458 var queue = [];
460 /**
461 * The number of active animations.
462 * @property tweenCount
463 * @private
464 * @type Int
466 var tweenCount = 0;
468 /**
469 * Base frame rate (frames per second).
470 * Arbitrarily high for better x-browser calibration (slower browsers drop more frames).
471 * @property fps
472 * @type Int
475 this.fps = 1000;
477 /**
478 * Interval delay in milliseconds, defaults to fastest possible.
479 * @property delay
480 * @type Int
483 this.delay = 1;
486 * Adds an animation instance to the animation queue.
487 * All animation instances must be registered in order to animate.
488 * @method registerElement
489 * @param {object} tween The Anim instance to be be registered
491 this.registerElement = function(tween) {
492 queue[queue.length] = tween;
493 tweenCount += 1;
494 tween._onStart.fire();
495 this.start();
499 * removes an animation instance from the animation queue.
500 * All animation instances must be registered in order to animate.
501 * @method unRegister
502 * @param {object} tween The Anim instance to be be registered
503 * @param {Int} index The index of the Anim instance
504 * @private
506 this.unRegister = function(tween, index) {
507 tween._onComplete.fire();
508 index = index || getIndex(tween);
509 if (index != -1) { queue.splice(index, 1); }
511 tweenCount -= 1;
512 if (tweenCount <= 0) { this.stop(); }
516 * Starts the animation thread.
517 * Only one thread can run at a time.
518 * @method start
520 this.start = function() {
521 if (thread === null) { thread = setInterval(this.run, this.delay); }
525 * Stops the animation thread or a specific animation instance.
526 * @method stop
527 * @param {object} tween A specific Anim instance to stop (optional)
528 * If no instance given, Manager stops thread and all animations.
530 this.stop = function(tween) {
531 if (!tween) {
532 clearInterval(thread);
533 for (var i = 0, len = queue.length; i < len; ++i) {
534 if (queue[i].isAnimated()) {
535 this.unRegister(tween, i);
538 queue = [];
539 thread = null;
540 tweenCount = 0;
542 else {
543 this.unRegister(tween);
548 * Called per Interval to handle each animation frame.
549 * @method run
551 this.run = function() {
552 for (var i = 0, len = queue.length; i < len; ++i) {
553 var tween = queue[i];
554 if ( !tween || !tween.isAnimated() ) { continue; }
556 if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
558 tween.currentFrame += 1;
560 if (tween.useSeconds) {
561 correctFrame(tween);
563 tween._onTween.fire();
565 else { YAHOO.util.AnimMgr.stop(tween, i); }
569 var getIndex = function(anim) {
570 for (var i = 0, len = queue.length; i < len; ++i) {
571 if (queue[i] == anim) {
572 return i; // note return;
575 return -1;
579 * On the fly frame correction to keep animation on time.
580 * @method correctFrame
581 * @private
582 * @param {Object} tween The Anim instance being corrected.
584 var correctFrame = function(tween) {
585 var frames = tween.totalFrames;
586 var frame = tween.currentFrame;
587 var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
588 var elapsed = (new Date() - tween.getStartTime());
589 var tweak = 0;
591 if (elapsed < tween.duration * 1000) { // check if falling behind
592 tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
593 } else { // went over duration, so jump to end
594 tweak = frames - (frame + 1);
596 if (tweak > 0 && isFinite(tweak)) { // adjust if needed
597 if (tween.currentFrame + tweak >= frames) {// dont go past last frame
598 tweak = frames - (frame + 1);
601 tween.currentFrame += tweak;
606 * Used to calculate Bezier splines for any number of control points.
607 * @class Bezier
608 * @namespace YAHOO.util
611 YAHOO.util.Bezier = new function() {
613 * Get the current position of the animated element based on t.
614 * Each point is an array of "x" and "y" values (0 = x, 1 = y)
615 * At least 2 points are required (start and end).
616 * First point is start. Last point is end.
617 * Additional control points are optional.
618 * @method getPosition
619 * @param {Array} points An array containing Bezier points
620 * @param {Number} t A number between 0 and 1 which is the basis for determining current position
621 * @return {Array} An array containing int x and y member data
623 this.getPosition = function(points, t) {
624 var n = points.length;
625 var tmp = [];
627 for (var i = 0; i < n; ++i){
628 tmp[i] = [points[i][0], points[i][1]]; // save input
631 for (var j = 1; j < n; ++j) {
632 for (i = 0; i < n - j; ++i) {
633 tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
634 tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
638 return [ tmp[0][0], tmp[0][1] ];
642 (function() {
644 * Anim subclass for color transitions.
645 * <p>Usage: <code>var myAnim = new Y.ColorAnim(el, { backgroundColor: { from: '#FF0000', to: '#FFFFFF' } }, 1, Y.Easing.easeOut);</code> Color values can be specified with either 112233, #112233,
646 * [255,255,255], or rgb(255,255,255)</p>
647 * @class ColorAnim
648 * @namespace YAHOO.util
649 * @requires YAHOO.util.Anim
650 * @requires YAHOO.util.AnimMgr
651 * @requires YAHOO.util.Easing
652 * @requires YAHOO.util.Bezier
653 * @requires YAHOO.util.Dom
654 * @requires YAHOO.util.Event
655 * @constructor
656 * @extends YAHOO.util.Anim
657 * @param {HTMLElement | String} el Reference to the element that will be animated
658 * @param {Object} attributes The attribute(s) to be animated.
659 * Each attribute is an object with at minimum a "to" or "by" member defined.
660 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
661 * All attribute names use camelCase.
662 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
663 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
665 YAHOO.util.ColorAnim = function(el, attributes, duration, method) {
666 YAHOO.util.ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
669 YAHOO.extend(YAHOO.util.ColorAnim, YAHOO.util.Anim);
671 // shorthand
672 var Y = YAHOO.util;
673 var superclass = Y.ColorAnim.superclass;
674 var proto = Y.ColorAnim.prototype;
676 proto.toString = function() {
677 var el = this.getEl();
678 var id = el.id || el.tagName;
679 return ("ColorAnim " + id);
682 proto.patterns.color = /color$/i;
683 proto.patterns.rgb = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
684 proto.patterns.hex = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
685 proto.patterns.hex3 = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;
686 proto.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/; // need rgba for safari
689 * Attempts to parse the given string and return a 3-tuple.
690 * @method parseColor
691 * @param {String} s The string to parse.
692 * @return {Array} The 3-tuple of rgb values.
694 proto.parseColor = function(s) {
695 if (s.length == 3) { return s; }
697 var c = this.patterns.hex.exec(s);
698 if (c && c.length == 4) {
699 return [ parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16) ];
702 c = this.patterns.rgb.exec(s);
703 if (c && c.length == 4) {
704 return [ parseInt(c[1], 10), parseInt(c[2], 10), parseInt(c[3], 10) ];
707 c = this.patterns.hex3.exec(s);
708 if (c && c.length == 4) {
709 return [ parseInt(c[1] + c[1], 16), parseInt(c[2] + c[2], 16), parseInt(c[3] + c[3], 16) ];
712 return null;
715 proto.getAttribute = function(attr) {
716 var el = this.getEl();
717 if ( this.patterns.color.test(attr) ) {
718 var val = YAHOO.util.Dom.getStyle(el, attr);
720 if (this.patterns.transparent.test(val)) { // bgcolor default
721 var parent = el.parentNode; // try and get from an ancestor
722 val = Y.Dom.getStyle(parent, attr);
724 while (parent && this.patterns.transparent.test(val)) {
725 parent = parent.parentNode;
726 val = Y.Dom.getStyle(parent, attr);
727 if (parent.tagName.toUpperCase() == 'HTML') {
728 val = '#fff';
732 } else {
733 val = superclass.getAttribute.call(this, attr);
736 return val;
739 proto.doMethod = function(attr, start, end) {
740 var val;
742 if ( this.patterns.color.test(attr) ) {
743 val = [];
744 for (var i = 0, len = start.length; i < len; ++i) {
745 val[i] = superclass.doMethod.call(this, attr, start[i], end[i]);
748 val = 'rgb('+Math.floor(val[0])+','+Math.floor(val[1])+','+Math.floor(val[2])+')';
750 else {
751 val = superclass.doMethod.call(this, attr, start, end);
754 return val;
757 proto.setRuntimeAttribute = function(attr) {
758 superclass.setRuntimeAttribute.call(this, attr);
760 if ( this.patterns.color.test(attr) ) {
761 var attributes = this.attributes;
762 var start = this.parseColor(this.runtimeAttributes[attr].start);
763 var end = this.parseColor(this.runtimeAttributes[attr].end);
764 // fix colors if going "by"
765 if ( typeof attributes[attr]['to'] === 'undefined' && typeof attributes[attr]['by'] !== 'undefined' ) {
766 end = this.parseColor(attributes[attr].by);
768 for (var i = 0, len = start.length; i < len; ++i) {
769 end[i] = start[i] + end[i];
773 this.runtimeAttributes[attr].start = start;
774 this.runtimeAttributes[attr].end = end;
777 })();/*
778 TERMS OF USE - EASING EQUATIONS
779 Open source under the BSD License.
780 Copyright 2001 Robert Penner All rights reserved.
782 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
784 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
785 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
786 * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
788 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
792 * Singleton that determines how an animation proceeds from start to end.
793 * @class Easing
794 * @namespace YAHOO.util
797 YAHOO.util.Easing = {
800 * Uniform speed between points.
801 * @method easeNone
802 * @param {Number} t Time value used to compute current value
803 * @param {Number} b Starting value
804 * @param {Number} c Delta between start and end values
805 * @param {Number} d Total length of animation
806 * @return {Number} The computed value for the current animation frame
808 easeNone: function (t, b, c, d) {
809 return c*t/d + b;
813 * Begins slowly and accelerates towards end. (quadratic)
814 * @method easeIn
815 * @param {Number} t Time value used to compute current value
816 * @param {Number} b Starting value
817 * @param {Number} c Delta between start and end values
818 * @param {Number} d Total length of animation
819 * @return {Number} The computed value for the current animation frame
821 easeIn: function (t, b, c, d) {
822 return c*(t/=d)*t + b;
826 * Begins quickly and decelerates towards end. (quadratic)
827 * @method easeOut
828 * @param {Number} t Time value used to compute current value
829 * @param {Number} b Starting value
830 * @param {Number} c Delta between start and end values
831 * @param {Number} d Total length of animation
832 * @return {Number} The computed value for the current animation frame
834 easeOut: function (t, b, c, d) {
835 return -c *(t/=d)*(t-2) + b;
839 * Begins slowly and decelerates towards end. (quadratic)
840 * @method easeBoth
841 * @param {Number} t Time value used to compute current value
842 * @param {Number} b Starting value
843 * @param {Number} c Delta between start and end values
844 * @param {Number} d Total length of animation
845 * @return {Number} The computed value for the current animation frame
847 easeBoth: function (t, b, c, d) {
848 if ((t/=d/2) < 1) {
849 return c/2*t*t + b;
852 return -c/2 * ((--t)*(t-2) - 1) + b;
856 * Begins slowly and accelerates towards end. (quartic)
857 * @method easeInStrong
858 * @param {Number} t Time value used to compute current value
859 * @param {Number} b Starting value
860 * @param {Number} c Delta between start and end values
861 * @param {Number} d Total length of animation
862 * @return {Number} The computed value for the current animation frame
864 easeInStrong: function (t, b, c, d) {
865 return c*(t/=d)*t*t*t + b;
869 * Begins quickly and decelerates towards end. (quartic)
870 * @method easeOutStrong
871 * @param {Number} t Time value used to compute current value
872 * @param {Number} b Starting value
873 * @param {Number} c Delta between start and end values
874 * @param {Number} d Total length of animation
875 * @return {Number} The computed value for the current animation frame
877 easeOutStrong: function (t, b, c, d) {
878 return -c * ((t=t/d-1)*t*t*t - 1) + b;
882 * Begins slowly and decelerates towards end. (quartic)
883 * @method easeBothStrong
884 * @param {Number} t Time value used to compute current value
885 * @param {Number} b Starting value
886 * @param {Number} c Delta between start and end values
887 * @param {Number} d Total length of animation
888 * @return {Number} The computed value for the current animation frame
890 easeBothStrong: function (t, b, c, d) {
891 if ((t/=d/2) < 1) {
892 return c/2*t*t*t*t + b;
895 return -c/2 * ((t-=2)*t*t*t - 2) + b;
899 * Snap in elastic effect.
900 * @method elasticIn
901 * @param {Number} t Time value used to compute current value
902 * @param {Number} b Starting value
903 * @param {Number} c Delta between start and end values
904 * @param {Number} d Total length of animation
905 * @param {Number} a Amplitude (optional)
906 * @param {Number} p Period (optional)
907 * @return {Number} The computed value for the current animation frame
910 elasticIn: function (t, b, c, d, a, p) {
911 if (t == 0) {
912 return b;
914 if ( (t /= d) == 1 ) {
915 return b+c;
917 if (!p) {
918 p=d*.3;
921 if (!a || a < Math.abs(c)) {
922 a = c;
923 var s = p/4;
925 else {
926 var s = p/(2*Math.PI) * Math.asin (c/a);
929 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
933 * Snap out elastic effect.
934 * @method elasticOut
935 * @param {Number} t Time value used to compute current value
936 * @param {Number} b Starting value
937 * @param {Number} c Delta between start and end values
938 * @param {Number} d Total length of animation
939 * @param {Number} a Amplitude (optional)
940 * @param {Number} p Period (optional)
941 * @return {Number} The computed value for the current animation frame
943 elasticOut: function (t, b, c, d, a, p) {
944 if (t == 0) {
945 return b;
947 if ( (t /= d) == 1 ) {
948 return b+c;
950 if (!p) {
951 p=d*.3;
954 if (!a || a < Math.abs(c)) {
955 a = c;
956 var s = p / 4;
958 else {
959 var s = p/(2*Math.PI) * Math.asin (c/a);
962 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
966 * Snap both elastic effect.
967 * @method elasticBoth
968 * @param {Number} t Time value used to compute current value
969 * @param {Number} b Starting value
970 * @param {Number} c Delta between start and end values
971 * @param {Number} d Total length of animation
972 * @param {Number} a Amplitude (optional)
973 * @param {Number} p Period (optional)
974 * @return {Number} The computed value for the current animation frame
976 elasticBoth: function (t, b, c, d, a, p) {
977 if (t == 0) {
978 return b;
981 if ( (t /= d/2) == 2 ) {
982 return b+c;
985 if (!p) {
986 p = d*(.3*1.5);
989 if ( !a || a < Math.abs(c) ) {
990 a = c;
991 var s = p/4;
993 else {
994 var s = p/(2*Math.PI) * Math.asin (c/a);
997 if (t < 1) {
998 return -.5*(a*Math.pow(2,10*(t-=1)) *
999 Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
1001 return a*Math.pow(2,-10*(t-=1)) *
1002 Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
1007 * Backtracks slightly, then reverses direction and moves to end.
1008 * @method backIn
1009 * @param {Number} t Time value used to compute current value
1010 * @param {Number} b Starting value
1011 * @param {Number} c Delta between start and end values
1012 * @param {Number} d Total length of animation
1013 * @param {Number} s Overshoot (optional)
1014 * @return {Number} The computed value for the current animation frame
1016 backIn: function (t, b, c, d, s) {
1017 if (typeof s == 'undefined') {
1018 s = 1.70158;
1020 return c*(t/=d)*t*((s+1)*t - s) + b;
1024 * Overshoots end, then reverses and comes back to end.
1025 * @method backOut
1026 * @param {Number} t Time value used to compute current value
1027 * @param {Number} b Starting value
1028 * @param {Number} c Delta between start and end values
1029 * @param {Number} d Total length of animation
1030 * @param {Number} s Overshoot (optional)
1031 * @return {Number} The computed value for the current animation frame
1033 backOut: function (t, b, c, d, s) {
1034 if (typeof s == 'undefined') {
1035 s = 1.70158;
1037 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
1041 * Backtracks slightly, then reverses direction, overshoots end,
1042 * then reverses and comes back to end.
1043 * @method backBoth
1044 * @param {Number} t Time value used to compute current value
1045 * @param {Number} b Starting value
1046 * @param {Number} c Delta between start and end values
1047 * @param {Number} d Total length of animation
1048 * @param {Number} s Overshoot (optional)
1049 * @return {Number} The computed value for the current animation frame
1051 backBoth: function (t, b, c, d, s) {
1052 if (typeof s == 'undefined') {
1053 s = 1.70158;
1056 if ((t /= d/2 ) < 1) {
1057 return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
1059 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
1063 * Bounce off of start.
1064 * @method bounceIn
1065 * @param {Number} t Time value used to compute current value
1066 * @param {Number} b Starting value
1067 * @param {Number} c Delta between start and end values
1068 * @param {Number} d Total length of animation
1069 * @return {Number} The computed value for the current animation frame
1071 bounceIn: function (t, b, c, d) {
1072 return c - YAHOO.util.Easing.bounceOut(d-t, 0, c, d) + b;
1076 * Bounces off end.
1077 * @method bounceOut
1078 * @param {Number} t Time value used to compute current value
1079 * @param {Number} b Starting value
1080 * @param {Number} c Delta between start and end values
1081 * @param {Number} d Total length of animation
1082 * @return {Number} The computed value for the current animation frame
1084 bounceOut: function (t, b, c, d) {
1085 if ((t/=d) < (1/2.75)) {
1086 return c*(7.5625*t*t) + b;
1087 } else if (t < (2/2.75)) {
1088 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
1089 } else if (t < (2.5/2.75)) {
1090 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
1092 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
1096 * Bounces off start and end.
1097 * @method bounceBoth
1098 * @param {Number} t Time value used to compute current value
1099 * @param {Number} b Starting value
1100 * @param {Number} c Delta between start and end values
1101 * @param {Number} d Total length of animation
1102 * @return {Number} The computed value for the current animation frame
1104 bounceBoth: function (t, b, c, d) {
1105 if (t < d/2) {
1106 return YAHOO.util.Easing.bounceIn(t*2, 0, c, d) * .5 + b;
1108 return YAHOO.util.Easing.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
1112 (function() {
1114 * Anim subclass for moving elements along a path defined by the "points"
1115 * member of "attributes". All "points" are arrays with x, y coordinates.
1116 * <p>Usage: <code>var myAnim = new YAHOO.util.Motion(el, { points: { to: [800, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
1117 * @class Motion
1118 * @namespace YAHOO.util
1119 * @requires YAHOO.util.Anim
1120 * @requires YAHOO.util.AnimMgr
1121 * @requires YAHOO.util.Easing
1122 * @requires YAHOO.util.Bezier
1123 * @requires YAHOO.util.Dom
1124 * @requires YAHOO.util.Event
1125 * @requires YAHOO.util.CustomEvent
1126 * @constructor
1127 * @extends YAHOO.util.Anim
1128 * @param {String | HTMLElement} el Reference to the element that will be animated
1129 * @param {Object} attributes The attribute(s) to be animated.
1130 * Each attribute is an object with at minimum a "to" or "by" member defined.
1131 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
1132 * All attribute names use camelCase.
1133 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
1134 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
1136 YAHOO.util.Motion = function(el, attributes, duration, method) {
1137 if (el) { // dont break existing subclasses not using YAHOO.extend
1138 YAHOO.util.Motion.superclass.constructor.call(this, el, attributes, duration, method);
1142 YAHOO.extend(YAHOO.util.Motion, YAHOO.util.ColorAnim);
1144 // shorthand
1145 var Y = YAHOO.util;
1146 var superclass = Y.Motion.superclass;
1147 var proto = Y.Motion.prototype;
1149 proto.toString = function() {
1150 var el = this.getEl();
1151 var id = el.id || el.tagName;
1152 return ("Motion " + id);
1155 proto.patterns.points = /^points$/i;
1157 proto.setAttribute = function(attr, val, unit) {
1158 if ( this.patterns.points.test(attr) ) {
1159 unit = unit || 'px';
1160 superclass.setAttribute.call(this, 'left', val[0], unit);
1161 superclass.setAttribute.call(this, 'top', val[1], unit);
1162 } else {
1163 superclass.setAttribute.call(this, attr, val, unit);
1167 proto.getAttribute = function(attr) {
1168 if ( this.patterns.points.test(attr) ) {
1169 var val = [
1170 superclass.getAttribute.call(this, 'left'),
1171 superclass.getAttribute.call(this, 'top')
1173 } else {
1174 val = superclass.getAttribute.call(this, attr);
1177 return val;
1180 proto.doMethod = function(attr, start, end) {
1181 var val = null;
1183 if ( this.patterns.points.test(attr) ) {
1184 var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;
1185 val = Y.Bezier.getPosition(this.runtimeAttributes[attr], t);
1186 } else {
1187 val = superclass.doMethod.call(this, attr, start, end);
1189 return val;
1192 proto.setRuntimeAttribute = function(attr) {
1193 if ( this.patterns.points.test(attr) ) {
1194 var el = this.getEl();
1195 var attributes = this.attributes;
1196 var start;
1197 var control = attributes['points']['control'] || [];
1198 var end;
1199 var i, len;
1201 if (control.length > 0 && !(control[0] instanceof Array) ) { // could be single point or array of points
1202 control = [control];
1203 } else { // break reference to attributes.points.control
1204 var tmp = [];
1205 for (i = 0, len = control.length; i< len; ++i) {
1206 tmp[i] = control[i];
1208 control = tmp;
1211 if (Y.Dom.getStyle(el, 'position') == 'static') { // default to relative
1212 Y.Dom.setStyle(el, 'position', 'relative');
1215 if ( isset(attributes['points']['from']) ) {
1216 Y.Dom.setXY(el, attributes['points']['from']); // set position to from point
1218 else { Y.Dom.setXY( el, Y.Dom.getXY(el) ); } // set it to current position
1220 start = this.getAttribute('points'); // get actual top & left
1222 // TO beats BY, per SMIL 2.1 spec
1223 if ( isset(attributes['points']['to']) ) {
1224 end = translateValues.call(this, attributes['points']['to'], start);
1226 var pageXY = Y.Dom.getXY(this.getEl());
1227 for (i = 0, len = control.length; i < len; ++i) {
1228 control[i] = translateValues.call(this, control[i], start);
1232 } else if ( isset(attributes['points']['by']) ) {
1233 end = [ start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1] ];
1235 for (i = 0, len = control.length; i < len; ++i) {
1236 control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
1240 this.runtimeAttributes[attr] = [start];
1242 if (control.length > 0) {
1243 this.runtimeAttributes[attr] = this.runtimeAttributes[attr].concat(control);
1246 this.runtimeAttributes[attr][this.runtimeAttributes[attr].length] = end;
1248 else {
1249 superclass.setRuntimeAttribute.call(this, attr);
1253 var translateValues = function(val, start) {
1254 var pageXY = Y.Dom.getXY(this.getEl());
1255 val = [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1] ];
1257 return val;
1260 var isset = function(prop) {
1261 return (typeof prop !== 'undefined');
1263 })();
1264 (function() {
1266 * Anim subclass for scrolling elements to a position defined by the "scroll"
1267 * member of "attributes". All "scroll" members are arrays with x, y scroll positions.
1268 * <p>Usage: <code>var myAnim = new YAHOO.util.Scroll(el, { scroll: { to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
1269 * @class Scroll
1270 * @namespace YAHOO.util
1271 * @requires YAHOO.util.Anim
1272 * @requires YAHOO.util.AnimMgr
1273 * @requires YAHOO.util.Easing
1274 * @requires YAHOO.util.Bezier
1275 * @requires YAHOO.util.Dom
1276 * @requires YAHOO.util.Event
1277 * @requires YAHOO.util.CustomEvent
1278 * @extends YAHOO.util.Anim
1279 * @constructor
1280 * @param {String or HTMLElement} el Reference to the element that will be animated
1281 * @param {Object} attributes The attribute(s) to be animated.
1282 * Each attribute is an object with at minimum a "to" or "by" member defined.
1283 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
1284 * All attribute names use camelCase.
1285 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
1286 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
1288 YAHOO.util.Scroll = function(el, attributes, duration, method) {
1289 if (el) { // dont break existing subclasses not using YAHOO.extend
1290 YAHOO.util.Scroll.superclass.constructor.call(this, el, attributes, duration, method);
1294 YAHOO.extend(YAHOO.util.Scroll, YAHOO.util.ColorAnim);
1296 // shorthand
1297 var Y = YAHOO.util;
1298 var superclass = Y.Scroll.superclass;
1299 var proto = Y.Scroll.prototype;
1301 proto.toString = function() {
1302 var el = this.getEl();
1303 var id = el.id || el.tagName;
1304 return ("Scroll " + id);
1307 proto.doMethod = function(attr, start, end) {
1308 var val = null;
1310 if (attr == 'scroll') {
1311 val = [
1312 this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames),
1313 this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)
1316 } else {
1317 val = superclass.doMethod.call(this, attr, start, end);
1319 return val;
1322 proto.getAttribute = function(attr) {
1323 var val = null;
1324 var el = this.getEl();
1326 if (attr == 'scroll') {
1327 val = [ el.scrollLeft, el.scrollTop ];
1328 } else {
1329 val = superclass.getAttribute.call(this, attr);
1332 return val;
1335 proto.setAttribute = function(attr, val, unit) {
1336 var el = this.getEl();
1338 if (attr == 'scroll') {
1339 el.scrollLeft = val[0];
1340 el.scrollTop = val[1];
1341 } else {
1342 superclass.setAttribute.call(this, attr, val, unit);
1345 })();