JAVASCRIPT   39

animation.js

Guest on 2nd June 2021 05:59:43 AM

  1. /*
  2. Copyright (c) Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.com/yui/license.html
  5. version: 2.8.2r1
  6. */
  7. (function() {
  8.  
  9. var Y = YAHOO.util;
  10.  
  11. /*
  12. Copyright (c)  Yahoo! Inc. All rights reserved.
  13. Code licensed under the BSD License:
  14. http://developer.yahoo.net/yui/license.txt
  15. */
  16.  
  17. /**
  18.  * The animation module provides allows effects to be added to HTMLElements.
  19.  * @module animation
  20.  * @requires yahoo, event, dom
  21.  */
  22.  
  23. /**
  24.  *
  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>
  27.  * @class Anim
  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
  34.  * @constructor
  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)
  42.  */
  43.  
  44. var Anim = function(el, attributes, duration, method) {
  45.     if (!el) {
  46.     }
  47.     this.init(el, attributes, duration, method);
  48. };
  49.  
  50. Anim.NAME = 'Anim';
  51.  
  52. Anim.prototype = {
  53.     /**
  54.      * Provides a readable name for the Anim instance.
  55.      * @method toString
  56.      * @return {String}
  57.      */
  58.     toString: function() {
  59.         var el = this.getEl() || {};
  60.         var id = el.id || el.tagName;
  61.         return (this.constructor.NAME + ': ' + id);
  62.     },
  63.    
  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
  69.     },
  70.    
  71.     /**
  72.      * Returns the value computed by the animation's "method".
  73.      * @method doMethod
  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.
  78.      */
  79.     doMethod: function(attr, start, end) {
  80.         return this.method(this.currentFrame, start, end - start, this.totalFrames);
  81.     },
  82.    
  83.     /**
  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.
  89.      */
  90.     setAttribute: function(attr, val, unit) {
  91.         var el = this.getEl();
  92.         if ( this.patterns.noNegatives.test(attr) ) {
  93.             val = (val > 0) ? val : 0;
  94.         }
  95.  
  96.         if (attr in el && !('style' in el && attr in el.style)) {
  97.             el[attr] = val;
  98.         } else {
  99.             Y.Dom.setStyle(el, attr, val + unit);
  100.         }
  101.     },                        
  102.    
  103.     /**
  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.
  108.      */
  109.     getAttribute: function(attr) {
  110.         var el = this.getEl();
  111.         var val = Y.Dom.getStyle(el, attr);
  112.  
  113.         if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
  114.             return parseFloat(val);
  115.         }
  116.        
  117.         var a = this.patterns.offsetAttribute.exec(attr) || [];
  118.         var pos = !!( a[3] ); // top or left
  119.         var box = !!( a[2] ); // width or height
  120.        
  121.         if ('style' in el) {
  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'
  126.                 val = 0;
  127.             }
  128.         } else if (attr in el) {
  129.             val = el[attr];
  130.         }
  131.  
  132.         return val;
  133.     },
  134.    
  135.     /**
  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.
  140.      */
  141.     getDefaultUnit: function(attr) {
  142.          if ( this.patterns.defaultUnit.test(attr) ) {
  143.             return 'px';
  144.          }
  145.          
  146.          return '';
  147.     },
  148.        
  149.     /**
  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
  153.      * @private
  154.      */
  155.     setRuntimeAttribute: function(attr) {
  156.         var start;
  157.         var end;
  158.         var attributes = this.attributes;
  159.  
  160.         this.runtimeAttributes[attr] = {};
  161.        
  162.         var isset = function(prop) {
  163.             return (typeof prop !== 'undefined');
  164.         };
  165.        
  166.         if ( !isset(attributes[attr]['to']) && !isset(attributes[attr]['by']) ) {
  167.             return false; // note return; nothing to animate to
  168.         }
  169.        
  170.         start = ( isset(attributes[attr]['from']) ) ? attributes[attr]['from'] : this.getAttribute(attr);
  171.  
  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) {
  177.                 end = [];
  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"
  180.                 }
  181.             } else {
  182.                 end = start + attributes[attr]['by'] * 1;
  183.             }
  184.         }
  185.        
  186.         this.runtimeAttributes[attr].start = start;
  187.         this.runtimeAttributes[attr].end = end;
  188.  
  189.         // set units if needed
  190.         this.runtimeAttributes[attr].unit = ( isset(attributes[attr].unit) ) ?
  191.                 attributes[attr]['unit'] : this.getDefaultUnit(attr);
  192.         return true;
  193.     },
  194.  
  195.     /**
  196.      * Constructor for Anim instance.
  197.      * @method init
  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)
  205.      */
  206.     init: function(el, attributes, duration, method) {
  207.         /**
  208.          * Whether or not the animation is running.
  209.          * @property isAnimated
  210.          * @private
  211.          * @type Boolean
  212.          */
  213.         var isAnimated = false;
  214.        
  215.         /**
  216.          * A Date object that is created when the animation begins.
  217.          * @property startTime
  218.          * @private
  219.          * @type Date
  220.          */
  221.         var startTime = null;
  222.        
  223.         /**
  224.          * The number of frames this animation was able to execute.
  225.          * @property actualFrames
  226.          * @private
  227.          * @type Int
  228.          */
  229.         var actualFrames = 0;
  230.  
  231.         /**
  232.          * The element to be animated.
  233.          * @property el
  234.          * @private
  235.          * @type HTMLElement
  236.          */
  237.         el = Y.Dom.get(el);
  238.        
  239.         /**
  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
  247.          * @type Object
  248.          */
  249.         this.attributes = attributes || {};
  250.        
  251.         /**
  252.          * The length of the animation.  Defaults to "1" (second).
  253.          * @property duration
  254.          * @type Number
  255.          */
  256.         this.duration = !YAHOO.lang.isUndefined(duration) ? duration : 1;
  257.        
  258.         /**
  259.          * The method that will provide values to the attribute(s) during the animation.
  260.          * Defaults to "YAHOO.util.Easing.easeNone".
  261.          * @property method
  262.          * @type Function
  263.          */
  264.         this.method = method || Y.Easing.easeNone;
  265.  
  266.         /**
  267.          * Whether or not the duration should be treated as seconds.
  268.          * Defaults to true.
  269.          * @property useSeconds
  270.          * @type Boolean
  271.          */
  272.         this.useSeconds = true; // default to seconds
  273.        
  274.         /**
  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
  278.          * @type Int
  279.          */
  280.         this.currentFrame = 0;
  281.        
  282.         /**
  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
  286.          * @type Int
  287.          */
  288.         this.totalFrames = Y.AnimMgr.fps;
  289.        
  290.         /**
  291.          * Changes the animated element
  292.          * @method setEl
  293.          */
  294.         this.setEl = function(element) {
  295.             el = Y.Dom.get(element);
  296.         };
  297.        
  298.         /**
  299.          * Returns a reference to the animated element.
  300.          * @method getEl
  301.          * @return {HTMLElement}
  302.          */
  303.         this.getEl = function() { return el; };
  304.        
  305.         /**
  306.          * Checks whether the element is currently animated.
  307.          * @method isAnimated
  308.          * @return {Boolean} current value of isAnimated.    
  309.          */
  310.         this.isAnimated = function() {
  311.             return isAnimated;
  312.         };
  313.        
  314.         /**
  315.          * Returns the animation start time.
  316.          * @method getStartTime
  317.          * @return {Date} current value of startTime.      
  318.          */
  319.         this.getStartTime = function() {
  320.             return startTime;
  321.         };        
  322.        
  323.         this.runtimeAttributes = {};
  324.        
  325.        
  326.        
  327.         /**
  328.          * Starts the animation by registering it with the animation manager.
  329.          * @method animate  
  330.          */
  331.         this.animate = function() {
  332.             if ( this.isAnimated() ) {
  333.                 return false;
  334.             }
  335.            
  336.             this.currentFrame = 0;
  337.            
  338.             this.totalFrames = ( this.useSeconds ) ? Math.ceil(Y.AnimMgr.fps * this.duration) : this.duration;
  339.    
  340.             if (this.duration === 0 && this.useSeconds) { // jump to last frame if zero second duration
  341.                 this.totalFrames = 1;
  342.             }
  343.             Y.AnimMgr.registerElement(this);
  344.             return true;
  345.         };
  346.          
  347.         /**
  348.          * Stops the animation.  Normally called by AnimMgr when animation completes.
  349.          * @method stop
  350.          * @param {Boolean} finish (optional) If true, animation will jump to final frame.
  351.          */
  352.         this.stop = function(finish) {
  353.             if (!this.isAnimated()) { // nothing to stop
  354.                 return false;
  355.             }
  356.  
  357.             if (finish) {
  358.                  this.currentFrame = this.totalFrames;
  359.                  this._onTween.fire();
  360.             }
  361.             Y.AnimMgr.stop(this);
  362.         };
  363.        
  364.         var onStart = function() {            
  365.             this.onStart.fire();
  366.            
  367.             this.runtimeAttributes = {};
  368.             for (var attr in this.attributes) {
  369.                 this.setRuntimeAttribute(attr);
  370.             }
  371.            
  372.             isAnimated = true;
  373.             actualFrames = 0;
  374.             startTime = new Date();
  375.         };
  376.        
  377.         /**
  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).
  379.          * @private
  380.          */
  381.          
  382.         var onTween = function() {
  383.             var data = {
  384.                 duration: new Date() - this.getStartTime(),
  385.                 currentFrame: this.currentFrame
  386.             };
  387.            
  388.             data.toString = function() {
  389.                 return (
  390.                     'duration: ' + data.duration +
  391.                     ', currentFrame: ' + data.currentFrame
  392.                 );
  393.             };
  394.            
  395.             this.onTween.fire(data);
  396.            
  397.             var runtimeAttributes = this.runtimeAttributes;
  398.            
  399.             for (var attr in runtimeAttributes) {
  400.                 this.setAttribute(attr, this.doMethod(attr, runtimeAttributes[attr].start, runtimeAttributes[attr].end), runtimeAttributes[attr].unit);
  401.             }
  402.            
  403.             actualFrames += 1;
  404.         };
  405.        
  406.         var onComplete = function() {
  407.             var actual_duration = (new Date() - startTime) / 1000 ;
  408.            
  409.             var data = {
  410.                 duration: actual_duration,
  411.                 frames: actualFrames,
  412.                 fps: actualFrames / actual_duration
  413.             };
  414.            
  415.             data.toString = function() {
  416.                 return (
  417.                     'duration: ' + data.duration +
  418.                     ', frames: ' + data.frames +
  419.                     ', fps: ' + data.fps
  420.                 );
  421.             };
  422.            
  423.             isAnimated = false;
  424.             actualFrames = 0;
  425.             this.onComplete.fire(data);
  426.         };
  427.        
  428.         /**
  429.          * Custom event that fires after onStart, useful in subclassing
  430.          * @private
  431.          */    
  432.         this._onStart = new Y.CustomEvent('_start', this, true);
  433.  
  434.         /**
  435.          * Custom event that fires when animation begins
  436.          * Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)
  437.          * @event onStart
  438.          */    
  439.         this.onStart = new Y.CustomEvent('start', this);
  440.        
  441.         /**
  442.          * Custom event that fires between each frame
  443.          * Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)
  444.          * @event onTween
  445.          */
  446.         this.onTween = new Y.CustomEvent('tween', this);
  447.        
  448.         /**
  449.          * Custom event that fires after onTween
  450.          * @private
  451.          */
  452.         this._onTween = new Y.CustomEvent('_tween', this, true);
  453.        
  454.         /**
  455.          * Custom event that fires when animation ends
  456.          * Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)
  457.          * @event onComplete
  458.          */
  459.         this.onComplete = new Y.CustomEvent('complete', this);
  460.         /**
  461.          * Custom event that fires after onComplete
  462.          * @private
  463.          */
  464.         this._onComplete = new Y.CustomEvent('_complete', this, true);
  465.  
  466.         this._onStart.subscribe(onStart);
  467.         this._onTween.subscribe(onTween);
  468.         this._onComplete.subscribe(onComplete);
  469.     }
  470. };
  471.  
  472.     Y.Anim = Anim;
  473. })();
  474. /**
  475.  * Handles animation queueing and threading.
  476.  * Used by Anim and subclasses.
  477.  * @class AnimMgr
  478.  * @namespace YAHOO.util
  479.  */
  480. YAHOO.util.AnimMgr = new function() {
  481.     /**
  482.      * Reference to the animation Interval.
  483.      * @property thread
  484.      * @private
  485.      * @type Int
  486.      */
  487.     var thread = null;
  488.    
  489.     /**
  490.      * The current queue of registered animation objects.
  491.      * @property queue
  492.      * @private
  493.      * @type Array
  494.      */    
  495.     var queue = [];
  496.  
  497.     /**
  498.      * The number of active animations.
  499.      * @property tweenCount
  500.      * @private
  501.      * @type Int
  502.      */        
  503.     var tweenCount = 0;
  504.  
  505.     /**
  506.      * Base frame rate (frames per second).
  507.      * Arbitrarily high for better x-browser calibration (slower browsers drop more frames).
  508.      * @property fps
  509.      * @type Int
  510.      *
  511.      */
  512.     this.fps = 1000;
  513.  
  514.     /**
  515.      * Interval delay in milliseconds, defaults to fastest possible.
  516.      * @property delay
  517.      * @type Int
  518.      *
  519.      */
  520.     this.delay = 1;
  521.  
  522.     /**
  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
  527.      */
  528.     this.registerElement = function(tween) {
  529.         queue[queue.length] = tween;
  530.         tweenCount += 1;
  531.         tween._onStart.fire();
  532.         this.start();
  533.     };
  534.    
  535.     /**
  536.      * removes an animation instance from the animation queue.
  537.      * All animation instances must be registered in order to animate.
  538.      * @method unRegister
  539.      * @param {object} tween The Anim instance to be be registered
  540.      * @param {Int} index The index of the Anim instance
  541.      * @private
  542.      */
  543.     this.unRegister = function(tween, index) {
  544.         index = index || getIndex(tween);
  545.         if (!tween.isAnimated() || index === -1) {
  546.             return false;
  547.         }
  548.        
  549.         tween._onComplete.fire();
  550.         queue.splice(index, 1);
  551.  
  552.         tweenCount -= 1;
  553.         if (tweenCount <= 0) {
  554.             this.stop();
  555.         }
  556.  
  557.         return true;
  558.     };
  559.    
  560.     /**
  561.      * Starts the animation thread.
  562.       * Only one thread can run at a time.
  563.      * @method start
  564.      */    
  565.     this.start = function() {
  566.         if (thread === null) {
  567.             thread = setInterval(this.run, this.delay);
  568.         }
  569.     };
  570.  
  571.     /**
  572.      * Stops the animation thread or a specific animation instance.
  573.      * @method stop
  574.      * @param {object} tween A specific Anim instance to stop (optional)
  575.      * If no instance given, Manager stops thread and all animations.
  576.      */    
  577.     this.stop = function(tween) {
  578.         if (!tween) {
  579.             clearInterval(thread);
  580.            
  581.             for (var i = 0, len = queue.length; i < len; ++i) {
  582.                 this.unRegister(queue[0], 0);  
  583.             }
  584.  
  585.             queue = [];
  586.             thread = null;
  587.             tweenCount = 0;
  588.         }
  589.         else {
  590.             this.unRegister(tween);
  591.         }
  592.     };
  593.    
  594.     /**
  595.      * Called per Interval to handle each animation frame.
  596.      * @method run
  597.      */    
  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; }
  602.  
  603.             if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
  604.             {
  605.                 tween.currentFrame += 1;
  606.                
  607.                 if (tween.useSeconds) {
  608.                     correctFrame(tween);
  609.                 }
  610.                 tween._onTween.fire();          
  611.             }
  612.             else { YAHOO.util.AnimMgr.stop(tween, i); }
  613.         }
  614.     };
  615.    
  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;
  620.             }
  621.         }
  622.         return -1;
  623.     };
  624.    
  625.     /**
  626.      * On the fly frame correction to keep animation on time.
  627.      * @method correctFrame
  628.      * @private
  629.      * @param {Object} tween The Anim instance being corrected.
  630.      */
  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());
  636.         var tweak = 0;
  637.        
  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);
  642.         }
  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);
  646.             }
  647.            
  648.             tween.currentFrame += tweak;      
  649.         }
  650.     };
  651.     this._queue = queue;
  652.     this._getIndex = getIndex;
  653. };
  654. /**
  655.  * Used to calculate Bezier splines for any number of control points.
  656.  * @class Bezier
  657.  * @namespace YAHOO.util
  658.  *
  659.  */
  660. YAHOO.util.Bezier = new function() {
  661.     /**
  662.      * Get the current position of the animated element based on t.
  663.      * Each point is an array of "x" and "y" values (0 = x, 1 = y)
  664.      * At least 2 points are required (start and end).
  665.      * First point is start. Last point is end.
  666.      * Additional control points are optional.    
  667.      * @method getPosition
  668.      * @param {Array} points An array containing Bezier points
  669.      * @param {Number} t A number between 0 and 1 which is the basis for determining current position
  670.      * @return {Array} An array containing int x and y member data
  671.      */
  672.     this.getPosition = function(points, t) {  
  673.         var n = points.length;
  674.         var tmp = [];
  675.  
  676.         for (var i = 0; i < n; ++i){
  677.             tmp[i] = [points[i][0], points[i][1]]; // save input
  678.         }
  679.        
  680.         for (var j = 1; j < n; ++j) {
  681.             for (i = 0; i < n - j; ++i) {
  682.                 tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
  683.                 tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
  684.             }
  685.         }
  686.    
  687.         return [ tmp[0][0], tmp[0][1] ];
  688.    
  689.     };
  690. };
  691. (function() {
  692. /**
  693.  * Anim subclass for color transitions.
  694.  * <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,
  695.  * [255,255,255], or rgb(255,255,255)</p>
  696.  * @class ColorAnim
  697.  * @namespace YAHOO.util
  698.  * @requires YAHOO.util.Anim
  699.  * @requires YAHOO.util.AnimMgr
  700.  * @requires YAHOO.util.Easing
  701.  * @requires YAHOO.util.Bezier
  702.  * @requires YAHOO.util.Dom
  703.  * @requires YAHOO.util.Event
  704.  * @constructor
  705.  * @extends YAHOO.util.Anim
  706.  * @param {HTMLElement | String} el Reference to the element that will be animated
  707.  * @param {Object} attributes The attribute(s) to be animated.
  708.  * Each attribute is an object with at minimum a "to" or "by" member defined.
  709.  * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
  710.  * All attribute names use camelCase.
  711.  * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
  712.  * @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)
  713.  */
  714.     var ColorAnim = function(el, attributes, duration,  method) {
  715.         ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
  716.     };
  717.    
  718.     ColorAnim.NAME = 'ColorAnim';
  719.  
  720.     ColorAnim.DEFAULT_BGCOLOR = '#fff';
  721.     // shorthand
  722.     var Y = YAHOO.util;
  723.     YAHOO.extend(ColorAnim, Y.Anim);
  724.  
  725.     var superclass = ColorAnim.superclass;
  726.     var proto = ColorAnim.prototype;
  727.    
  728.     proto.patterns.color = /color$/i;
  729.     proto.patterns.rgb            = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
  730.     proto.patterns.hex            = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
  731.     proto.patterns.hex3          = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;
  732.     proto.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/; // need rgba for safari
  733.    
  734.     /**
  735.      * Attempts to parse the given string and return a 3-tuple.
  736.      * @method parseColor
  737.      * @param {String} s The string to parse.
  738.      * @return {Array} The 3-tuple of rgb values.
  739.      */
  740.     proto.parseColor = function(s) {
  741.         if (s.length == 3) { return s; }
  742.    
  743.         var c = this.patterns.hex.exec(s);
  744.         if (c && c.length == 4) {
  745.             return [ parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16) ];
  746.         }
  747.    
  748.         c = this.patterns.rgb.exec(s);
  749.         if (c && c.length == 4) {
  750.             return [ parseInt(c[1], 10), parseInt(c[2], 10), parseInt(c[3], 10) ];
  751.         }
  752.    
  753.         c = this.patterns.hex3.exec(s);
  754.         if (c && c.length == 4) {
  755.             return [ parseInt(c[1] + c[1], 16), parseInt(c[2] + c[2], 16), parseInt(c[3] + c[3], 16) ];
  756.         }
  757.        
  758.         return null;
  759.     };
  760.  
  761.     proto.getAttribute = function(attr) {
  762.         var el = this.getEl();
  763.         if (this.patterns.color.test(attr) ) {
  764.             var val = YAHOO.util.Dom.getStyle(el, attr);
  765.            
  766.             var that = this;
  767.             if (this.patterns.transparent.test(val)) { // bgcolor default
  768.                 var parent = YAHOO.util.Dom.getAncestorBy(el, function(node) {
  769.                     return !that.patterns.transparent.test(val);
  770.                 });
  771.  
  772.                 if (parent) {
  773.                     val = Y.Dom.getStyle(parent, attr);
  774.                 } else {
  775.                     val = ColorAnim.DEFAULT_BGCOLOR;
  776.                 }
  777.             }
  778.         } else {
  779.             val = superclass.getAttribute.call(this, attr);
  780.         }
  781.  
  782.         return val;
  783.     };
  784.    
  785.     proto.doMethod = function(attr, start, end) {
  786.         var val;
  787.    
  788.         if ( this.patterns.color.test(attr) ) {
  789.             val = [];
  790.             for (var i = 0, len = start.length; i < len; ++i) {
  791.                 val[i] = superclass.doMethod.call(this, attr, start[i], end[i]);
  792.             }
  793.            
  794.             val = 'rgb('+Math.floor(val[0])+','+Math.floor(val[1])+','+Math.floor(val[2])+')';
  795.         }
  796.         else {
  797.             val = superclass.doMethod.call(this, attr, start, end);
  798.         }
  799.  
  800.         return val;
  801.     };
  802.  
  803.     proto.setRuntimeAttribute = function(attr) {
  804.         superclass.setRuntimeAttribute.call(this, attr);
  805.        
  806.         if ( this.patterns.color.test(attr) ) {
  807.             var attributes = this.attributes;
  808.             var start = this.parseColor(this.runtimeAttributes[attr].start);
  809.             var end = this.parseColor(this.runtimeAttributes[attr].end);
  810.             // fix colors if going "by"
  811.             if ( typeof attributes[attr]['to'] === 'undefined' && typeof attributes[attr]['by'] !== 'undefined' ) {
  812.                 end = this.parseColor(attributes[attr].by);
  813.            
  814.                 for (var i = 0, len = start.length; i < len; ++i) {
  815.                     end[i] = start[i] + end[i];
  816.                 }
  817.             }
  818.            
  819.             this.runtimeAttributes[attr].start = start;
  820.             this.runtimeAttributes[attr].end = end;
  821.         }
  822.     };
  823.  
  824.     Y.ColorAnim = ColorAnim;
  825. })();
  826. /*!
  827. TERMS OF USE - EASING EQUATIONS
  828. Open source under the BSD License.
  829. Copyright 2001 Robert Penner All rights reserved.
  830.  
  831. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  832.  
  833.  * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  834.  * 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.
  835.  * 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.
  836.  
  837. 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.
  838. */
  839.  
  840. /**
  841.  * Singleton that determines how an animation proceeds from start to end.
  842.  * @class Easing
  843.  * @namespace YAHOO.util
  844. */
  845.  
  846. YAHOO.util.Easing = {
  847.  
  848.     /**
  849.      * Uniform speed between points.
  850.      * @method easeNone
  851.      * @param {Number} t Time value used to compute current value
  852.      * @param {Number} b Starting value
  853.      * @param {Number} c Delta between start and end values
  854.      * @param {Number} d Total length of animation
  855.      * @return {Number} The computed value for the current animation frame
  856.      */
  857.     easeNone: function (t, b, c, d) {
  858.       return c*t/d + b;
  859.     },
  860.    
  861.     /**
  862.      * Begins slowly and accelerates towards end.
  863.      * @method easeIn
  864.      * @param {Number} t Time value used to compute current value
  865.      * @param {Number} b Starting value
  866.      * @param {Number} c Delta between start and end values
  867.      * @param {Number} d Total length of animation
  868.      * @return {Number} The computed value for the current animation frame
  869.      */
  870.     easeIn: function (t, b, c, d) {
  871.       return c*(t/=d)*t + b;
  872.     },
  873.  
  874.     /**
  875.      * Begins quickly and decelerates towards end.
  876.      * @method easeOut
  877.      * @param {Number} t Time value used to compute current value
  878.      * @param {Number} b Starting value
  879.      * @param {Number} c Delta between start and end values
  880.      * @param {Number} d Total length of animation
  881.      * @return {Number} The computed value for the current animation frame
  882.      */
  883.     easeOut: function (t, b, c, d) {
  884.       return -c *(t/=d)*(t-2) + b;
  885.     },
  886.    
  887.     /**
  888.      * Begins slowly and decelerates towards end.
  889.      * @method easeBoth
  890.      * @param {Number} t Time value used to compute current value
  891.      * @param {Number} b Starting value
  892.      * @param {Number} c Delta between start and end values
  893.      * @param {Number} d Total length of animation
  894.      * @return {Number} The computed value for the current animation frame
  895.      */
  896.     easeBoth: function (t, b, c, d) {
  897.       if ((t/=d/2) < 1) {
  898.             return c/2*t*t + b;
  899.         }
  900.        
  901.       return -c/2 * ((--t)*(t-2) - 1) + b;
  902.     },
  903.    
  904.     /**
  905.      * Begins slowly and accelerates towards end.
  906.      * @method easeInStrong
  907.      * @param {Number} t Time value used to compute current value
  908.      * @param {Number} b Starting value
  909.      * @param {Number} c Delta between start and end values
  910.      * @param {Number} d Total length of animation
  911.      * @return {Number} The computed value for the current animation frame
  912.      */
  913.     easeInStrong: function (t, b, c, d) {
  914.       return c*(t/=d)*t*t*t + b;
  915.     },
  916.    
  917.     /**
  918.      * Begins quickly and decelerates towards end.
  919.      * @method easeOutStrong
  920.      * @param {Number} t Time value used to compute current value
  921.      * @param {Number} b Starting value
  922.      * @param {Number} c Delta between start and end values
  923.      * @param {Number} d Total length of animation
  924.      * @return {Number} The computed value for the current animation frame
  925.      */
  926.     easeOutStrong: function (t, b, c, d) {
  927.       return -c * ((t=t/d-1)*t*t*t - 1) + b;
  928.     },
  929.    
  930.     /**
  931.      * Begins slowly and decelerates towards end.
  932.      * @method easeBothStrong
  933.      * @param {Number} t Time value used to compute current value
  934.      * @param {Number} b Starting value
  935.      * @param {Number} c Delta between start and end values
  936.      * @param {Number} d Total length of animation
  937.      * @return {Number} The computed value for the current animation frame
  938.      */
  939.     easeBothStrong: function (t, b, c, d) {
  940.       if ((t/=d/2) < 1) {
  941.             return c/2*t*t*t*t + b;
  942.         }
  943.        
  944.       return -c/2 * ((t-=2)*t*t*t - 2) + b;
  945.     },
  946.  
  947.     /**
  948.      * Snap in elastic effect.
  949.      * @method elasticIn
  950.      * @param {Number} t Time value used to compute current value
  951.      * @param {Number} b Starting value
  952.      * @param {Number} c Delta between start and end values
  953.      * @param {Number} d Total length of animation
  954.      * @param {Number} a Amplitude (optional)
  955.      * @param {Number} p Period (optional)
  956.      * @return {Number} The computed value for the current animation frame
  957.      */
  958.  
  959.     elasticIn: function (t, b, c, d, a, p) {
  960.       if (t == 0) {
  961.             return b;
  962.         }
  963.         if ( (t /= d) == 1 ) {
  964.             return b+c;
  965.         }
  966.         if (!p) {
  967.             p=d*.3;
  968.         }
  969.        
  970.       if (!a || a < Math.abs(c)) {
  971.             a = c;
  972.             var s = p/4;
  973.         }
  974.       else {
  975.             var s = p/(2*Math.PI) * Math.asin (c/a);
  976.         }
  977.        
  978.       return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
  979.     },
  980.  
  981.     /**
  982.      * Snap out elastic effect.
  983.      * @method elasticOut
  984.      * @param {Number} t Time value used to compute current value
  985.      * @param {Number} b Starting value
  986.      * @param {Number} c Delta between start and end values
  987.      * @param {Number} d Total length of animation
  988.      * @param {Number} a Amplitude (optional)
  989.      * @param {Number} p Period (optional)
  990.      * @return {Number} The computed value for the current animation frame
  991.      */
  992.     elasticOut: function (t, b, c, d, a, p) {
  993.       if (t == 0) {
  994.             return b;
  995.         }
  996.         if ( (t /= d) == 1 ) {
  997.             return b+c;
  998.         }
  999.         if (!p) {
  1000.             p=d*.3;
  1001.         }
  1002.        
  1003.       if (!a || a < Math.abs(c)) {
  1004.             a = c;
  1005.             var s = p / 4;
  1006.         }
  1007.       else {
  1008.             var s = p/(2*Math.PI) * Math.asin (c/a);
  1009.         }
  1010.        
  1011.       return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
  1012.     },
  1013.    
  1014.     /**
  1015.      * Snap both elastic effect.
  1016.      * @method elasticBoth
  1017.      * @param {Number} t Time value used to compute current value
  1018.      * @param {Number} b Starting value
  1019.      * @param {Number} c Delta between start and end values
  1020.      * @param {Number} d Total length of animation
  1021.      * @param {Number} a Amplitude (optional)
  1022.      * @param {Number} p Period (optional)
  1023.      * @return {Number} The computed value for the current animation frame
  1024.      */
  1025.     elasticBoth: function (t, b, c, d, a, p) {
  1026.       if (t == 0) {
  1027.             return b;
  1028.         }
  1029.        
  1030.         if ( (t /= d/2) == 2 ) {
  1031.             return b+c;
  1032.         }
  1033.        
  1034.         if (!p) {
  1035.             p = d*(.3*1.5);
  1036.         }
  1037.        
  1038.       if ( !a || a < Math.abs(c) ) {
  1039.             a = c;
  1040.             var s = p/4;
  1041.         }
  1042.       else {
  1043.             var s = p/(2*Math.PI) * Math.asin (c/a);
  1044.         }
  1045.        
  1046.       if (t < 1) {
  1047.             return -.5*(a*Math.pow(2,10*(t-=1)) *
  1048.                     Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
  1049.         }
  1050.       return a*Math.pow(2,-10*(t-=1)) *
  1051.                 Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
  1052.     },
  1053.  
  1054.  
  1055.     /**
  1056.      * Backtracks slightly, then reverses direction and moves to end.
  1057.      * @method backIn
  1058.      * @param {Number} t Time value used to compute current value
  1059.      * @param {Number} b Starting value
  1060.      * @param {Number} c Delta between start and end values
  1061.      * @param {Number} d Total length of animation
  1062.      * @param {Number} s Overshoot (optional)
  1063.      * @return {Number} The computed value for the current animation frame
  1064.      */
  1065.     backIn: function (t, b, c, d, s) {
  1066.       if (typeof s == 'undefined') {
  1067.             s = 1.70158;
  1068.         }
  1069.       return c*(t/=d)*t*((s+1)*t - s) + b;
  1070.     },
  1071.  
  1072.     /**
  1073.      * Overshoots end, then reverses and comes back to end.
  1074.      * @method backOut
  1075.      * @param {Number} t Time value used to compute current value
  1076.      * @param {Number} b Starting value
  1077.      * @param {Number} c Delta between start and end values
  1078.      * @param {Number} d Total length of animation
  1079.      * @param {Number} s Overshoot (optional)
  1080.      * @return {Number} The computed value for the current animation frame
  1081.      */
  1082.     backOut: function (t, b, c, d, s) {
  1083.       if (typeof s == 'undefined') {
  1084.             s = 1.70158;
  1085.         }
  1086.       return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
  1087.     },
  1088.    
  1089.     /**
  1090.      * Backtracks slightly, then reverses direction, overshoots end,
  1091.      * then reverses and comes back to end.
  1092.      * @method backBoth
  1093.      * @param {Number} t Time value used to compute current value
  1094.      * @param {Number} b Starting value
  1095.      * @param {Number} c Delta between start and end values
  1096.      * @param {Number} d Total length of animation
  1097.      * @param {Number} s Overshoot (optional)
  1098.      * @return {Number} The computed value for the current animation frame
  1099.      */
  1100.     backBoth: function (t, b, c, d, s) {
  1101.       if (typeof s == 'undefined') {
  1102.             s = 1.70158;
  1103.         }
  1104.        
  1105.       if ((t /= d/2 ) < 1) {
  1106.             return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
  1107.         }
  1108.       return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
  1109.     },
  1110.  
  1111.     /**
  1112.      * Bounce off of start.
  1113.      * @method bounceIn
  1114.      * @param {Number} t Time value used to compute current value
  1115.      * @param {Number} b Starting value
  1116.      * @param {Number} c Delta between start and end values
  1117.      * @param {Number} d Total length of animation
  1118.      * @return {Number} The computed value for the current animation frame
  1119.      */
  1120.     bounceIn: function (t, b, c, d) {
  1121.       return c - YAHOO.util.Easing.bounceOut(d-t, 0, c, d) + b;
  1122.     },
  1123.    
  1124.     /**
  1125.      * Bounces off end.
  1126.      * @method bounceOut
  1127.      * @param {Number} t Time value used to compute current value
  1128.      * @param {Number} b Starting value
  1129.      * @param {Number} c Delta between start and end values
  1130.      * @param {Number} d Total length of animation
  1131.      * @return {Number} The computed value for the current animation frame
  1132.      */
  1133.     bounceOut: function (t, b, c, d) {
  1134.       if ((t/=d) < (1/2.75)) {
  1135.             return c*(7.5625*t*t) + b;
  1136.       } else if (t < (2/2.75)) {
  1137.             return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
  1138.       } else if (t < (2.5/2.75)) {
  1139.             return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
  1140.       }
  1141.         return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
  1142.     },
  1143.    
  1144.     /**
  1145.      * Bounces off start and end.
  1146.      * @method bounceBoth
  1147.      * @param {Number} t Time value used to compute current value
  1148.      * @param {Number} b Starting value
  1149.      * @param {Number} c Delta between start and end values
  1150.      * @param {Number} d Total length of animation
  1151.      * @return {Number} The computed value for the current animation frame
  1152.      */
  1153.     bounceBoth: function (t, b, c, d) {
  1154.       if (t < d/2) {
  1155.             return YAHOO.util.Easing.bounceIn(t*2, 0, c, d) * .5 + b;
  1156.         }
  1157.       return YAHOO.util.Easing.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
  1158.     }
  1159. };
  1160.  
  1161. (function() {
  1162. /**
  1163.  * Anim subclass for moving elements along a path defined by the "points"
  1164.  * member of "attributes".  All "points" are arrays with x, y coordinates.
  1165.  * <p>Usage: <code>var myAnim = new YAHOO.util.Motion(el, { points: { to: [800, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
  1166.  * @class Motion
  1167.  * @namespace YAHOO.util
  1168.  * @requires YAHOO.util.Anim
  1169.  * @requires YAHOO.util.AnimMgr
  1170.  * @requires YAHOO.util.Easing
  1171.  * @requires YAHOO.util.Bezier
  1172.  * @requires YAHOO.util.Dom
  1173.  * @requires YAHOO.util.Event
  1174.  * @requires YAHOO.util.CustomEvent
  1175.  * @constructor
  1176.  * @extends YAHOO.util.ColorAnim
  1177.  * @param {String | HTMLElement} el Reference to the element that will be animated
  1178.  * @param {Object} attributes The attribute(s) to be animated.  
  1179.  * Each attribute is an object with at minimum a "to" or "by" member defined.  
  1180.  * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
  1181.  * All attribute names use camelCase.
  1182.  * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
  1183.  * @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)
  1184.  */
  1185.     var Motion = function(el, attributes, duration,  method) {
  1186.         if (el) { // dont break existing subclasses not using YAHOO.extend
  1187.             Motion.superclass.constructor.call(this, el, attributes, duration, method);
  1188.         }
  1189.     };
  1190.  
  1191.  
  1192.     Motion.NAME = 'Motion';
  1193.  
  1194.     // shorthand
  1195.     var Y = YAHOO.util;
  1196.     YAHOO.extend(Motion, Y.ColorAnim);
  1197.    
  1198.     var superclass = Motion.superclass;
  1199.     var proto = Motion.prototype;
  1200.  
  1201.     proto.patterns.points = /^points$/i;
  1202.    
  1203.     proto.setAttribute = function(attr, val, unit) {
  1204.         if (  this.patterns.points.test(attr) ) {
  1205.             unit = unit || 'px';
  1206.             superclass.setAttribute.call(this, 'left', val[0], unit);
  1207.             superclass.setAttribute.call(this, 'top', val[1], unit);
  1208.         } else {
  1209.             superclass.setAttribute.call(this, attr, val, unit);
  1210.         }
  1211.     };
  1212.  
  1213.     proto.getAttribute = function(attr) {
  1214.         if (  this.patterns.points.test(attr) ) {
  1215.             var val = [
  1216.                 superclass.getAttribute.call(this, 'left'),
  1217.                 superclass.getAttribute.call(this, 'top')
  1218.             ];
  1219.         } else {
  1220.             val = superclass.getAttribute.call(this, attr);
  1221.         }
  1222.  
  1223.         return val;
  1224.     };
  1225.  
  1226.     proto.doMethod = function(attr, start, end) {
  1227.         var val = null;
  1228.  
  1229.         if ( this.patterns.points.test(attr) ) {
  1230.             var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;                  
  1231.             val = Y.Bezier.getPosition(this.runtimeAttributes[attr], t);
  1232.         } else {
  1233.             val = superclass.doMethod.call(this, attr, start, end);
  1234.         }
  1235.         return val;
  1236.     };
  1237.  
  1238.     proto.setRuntimeAttribute = function(attr) {
  1239.         if ( this.patterns.points.test(attr) ) {
  1240.             var el = this.getEl();
  1241.             var attributes = this.attributes;
  1242.             var start;
  1243.             var control = attributes['points']['control'] || [];
  1244.             var end;
  1245.             var i, len;
  1246.            
  1247.             if (control.length > 0 && !(control[0] instanceof Array) ) { // could be single point or array of points
  1248.                 control = [control];
  1249.             } else { // break reference to attributes.points.control
  1250.                 var tmp = [];
  1251.                 for (i = 0, len = control.length; i< len; ++i) {
  1252.                     tmp[i] = control[i];
  1253.                 }
  1254.                 control = tmp;
  1255.             }
  1256.  
  1257.             if (Y.Dom.getStyle(el, 'position') == 'static') { // default to relative
  1258.                 Y.Dom.setStyle(el, 'position', 'relative');
  1259.             }
  1260.    
  1261.             if ( isset(attributes['points']['from']) ) {
  1262.                 Y.Dom.setXY(el, attributes['points']['from']); // set position to from point
  1263.             }
  1264.             else { Y.Dom.setXY( el, Y.Dom.getXY(el) ); } // set it to current position
  1265.            
  1266.             start = this.getAttribute('points'); // get actual top & left
  1267.            
  1268.             // TO beats BY, per SMIL 2.1 spec
  1269.             if ( isset(attributes['points']['to']) ) {
  1270.                 end = translateValues.call(this, attributes['points']['to'], start);
  1271.                
  1272.                 var pageXY = Y.Dom.getXY(this.getEl());
  1273.                 for (i = 0, len = control.length; i < len; ++i) {
  1274.                     control[i] = translateValues.call(this, control[i], start);
  1275.                 }
  1276.  
  1277.                
  1278.             } else if ( isset(attributes['points']['by']) ) {
  1279.                 end = [ start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1] ];
  1280.                
  1281.                 for (i = 0, len = control.length; i < len; ++i) {
  1282.                     control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
  1283.                 }
  1284.             }
  1285.  
  1286.             this.runtimeAttributes[attr] = [start];
  1287.            
  1288.             if (control.length > 0) {
  1289.                 this.runtimeAttributes[attr] = this.runtimeAttributes[attr].concat(control);
  1290.             }
  1291.  
  1292.             this.runtimeAttributes[attr][this.runtimeAttributes[attr].length] = end;
  1293.         }
  1294.         else {
  1295.             superclass.setRuntimeAttribute.call(this, attr);
  1296.         }
  1297.     };
  1298.    
  1299.     var translateValues = function(val, start) {
  1300.         var pageXY = Y.Dom.getXY(this.getEl());
  1301.         val = [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1] ];
  1302.  
  1303.         return val;
  1304.     };
  1305.    
  1306.     var isset = function(prop) {
  1307.         return (typeof prop !== 'undefined');
  1308.     };
  1309.  
  1310.     Y.Motion = Motion;
  1311. })();
  1312. (function() {
  1313. /**
  1314.  * Anim subclass for scrolling elements to a position defined by the "scroll"
  1315.  * member of "attributes".  All "scroll" members are arrays with x, y scroll positions.
  1316.  * <p>Usage: <code>var myAnim = new YAHOO.util.Scroll(el, { scroll: { to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
  1317.  * @class Scroll
  1318.  * @namespace YAHOO.util
  1319.  * @requires YAHOO.util.Anim
  1320.  * @requires YAHOO.util.AnimMgr
  1321.  * @requires YAHOO.util.Easing
  1322.  * @requires YAHOO.util.Bezier
  1323.  * @requires YAHOO.util.Dom
  1324.  * @requires YAHOO.util.Event
  1325.  * @requires YAHOO.util.CustomEvent
  1326.  * @extends YAHOO.util.ColorAnim
  1327.  * @constructor
  1328.  * @param {String or HTMLElement} el Reference to the element that will be animated
  1329.  * @param {Object} attributes The attribute(s) to be animated.  
  1330.  * Each attribute is an object with at minimum a "to" or "by" member defined.  
  1331.  * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
  1332.  * All attribute names use camelCase.
  1333.  * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
  1334.  * @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)
  1335.  */
  1336.     var Scroll = function(el, attributes, duration,  method) {
  1337.         if (el) { // dont break existing subclasses not using YAHOO.extend
  1338.             Scroll.superclass.constructor.call(this, el, attributes, duration, method);
  1339.         }
  1340.     };
  1341.  
  1342.     Scroll.NAME = 'Scroll';
  1343.  
  1344.     // shorthand
  1345.     var Y = YAHOO.util;
  1346.     YAHOO.extend(Scroll, Y.ColorAnim);
  1347.    
  1348.     var superclass = Scroll.superclass;
  1349.     var proto = Scroll.prototype;
  1350.  
  1351.     proto.doMethod = function(attr, start, end) {
  1352.         var val = null;
  1353.    
  1354.         if (attr == 'scroll') {
  1355.             val = [
  1356.                 this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames),
  1357.                 this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)
  1358.             ];
  1359.            
  1360.         } else {
  1361.             val = superclass.doMethod.call(this, attr, start, end);
  1362.         }
  1363.         return val;
  1364.     };
  1365.  
  1366.     proto.getAttribute = function(attr) {
  1367.         var val = null;
  1368.         var el = this.getEl();
  1369.        
  1370.         if (attr == 'scroll') {
  1371.             val = [ el.scrollLeft, el.scrollTop ];
  1372.         } else {
  1373.             val = superclass.getAttribute.call(this, attr);
  1374.         }
  1375.        
  1376.         return val;
  1377.     };
  1378.  
  1379.     proto.setAttribute = function(attr, val, unit) {
  1380.         var el = this.getEl();
  1381.        
  1382.         if (attr == 'scroll') {
  1383.             el.scrollLeft = val[0];
  1384.             el.scrollTop = val[1];
  1385.         } else {
  1386.             superclass.setAttribute.call(this, attr, val, unit);
  1387.         }
  1388.     };
  1389.  
  1390.     Y.Scroll = Scroll;
  1391. })();
  1392. YAHOO.register("animation", YAHOO.util.Anim, {version: "2.8.2r1", build: "7"});

Raw Paste


Login or Register to edit or fork this paste. It's free.