animation.js

来自「国外很不错的一个开源OA系统Group-Office」· JavaScript 代码 · 共 1,273 行 · 第 1/3 页

JS
1,273
字号
/*Copyright (c) 2006, Yahoo! Inc. All rights reserved.Code licensed under the BSD License:http://developer.yahoo.net/yui/license.txtversion: 0.12.0*//** * The animation module provides allows effects to be added to HTMLElements. * @module animation *//** * * Base animation class that provides the interface for building animated effects. * <p>Usage: var myAnim = new YAHOO.util.Anim(el, { width: { from: 10, to: 100 } }, 1, YAHOO.util.Easing.easeOut);</p> * @class Anim * @namespace YAHOO.util * @requires YAHOO.util.AnimMgr * @requires YAHOO.util.Easing * @requires YAHOO.util.Dom * @requires YAHOO.util.Event * @requires YAHOO.util.CustomEvent * @constructor * @param {String | HTMLElement} el Reference to the element that will be animated * @param {Object} attributes The attribute(s) to be animated. * Each attribute is an object with at minimum a "to" or "by" member defined. * Additional optional members are "from" (defaults to current value), "units" (defaults to "px"). * All attribute names use camelCase. * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based * @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) */YAHOO.util.Anim = function(el, attributes, duration, method) {   if (el) {      this.init(el, attributes, duration, method);   }};YAHOO.util.Anim.prototype = {   /**    * Provides a readable name for the Anim instance.    * @method toString    * @return {String}    */   toString: function() {      var el = this.getEl();      var id = el.id || el.tagName;      return ("Anim " + id);   },   patterns: { // cached for performance      noNegatives:      /width|height|opacity|padding/i, // keep at zero or above      offsetAttribute:  /^((width|height)|(top|left))$/, // use offsetValue as default      defaultUnit:      /width|height|top$|bottom$|left$|right$/i, // use 'px' by default      offsetUnit:       /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i // IE may return these, so convert these to offset   },   /**    * Returns the value computed by the animation's "method".    * @method doMethod    * @param {String} attr The name of the attribute.    * @param {Number} start The value this attribute should start from for this animation.    * @param {Number} end  The value this attribute should end at for this animation.    * @return {Number} The Value to be applied to the attribute.    */   doMethod: function(attr, start, end) {      return this.method(this.currentFrame, start, end - start, this.totalFrames);   },   /**    * Applies a value to an attribute.    * @method setAttribute    * @param {String} attr The name of the attribute.    * @param {Number} val The value to be applied to the attribute.    * @param {String} unit The unit ('px', '%', etc.) of the value.    */   setAttribute: function(attr, val, unit) {      if ( this.patterns.noNegatives.test(attr) ) {         val = (val > 0) ? val : 0;      }      YAHOO.util.Dom.setStyle(this.getEl(), attr, val + unit);   },   /**    * Returns current value of the attribute.    * @method getAttribute    * @param {String} attr The name of the attribute.    * @return {Number} val The current value of the attribute.    */   getAttribute: function(attr) {      var el = this.getEl();      var val = YAHOO.util.Dom.getStyle(el, attr);      if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {         return parseFloat(val);      }      var a = this.patterns.offsetAttribute.exec(attr) || [];      var pos = !!( a[3] ); // top or left      var box = !!( a[2] ); // width or height      // use offsets for width/height and abs pos top/left      if ( box || (YAHOO.util.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {         val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];      } else { // default to zero for other 'auto'         val = 0;      }      return val;   },   /**    * Returns the unit to use when none is supplied.    * @method getDefaultUnit    * @param {attr} attr The name of the attribute.    * @return {String} The default unit to be used.    */   getDefaultUnit: function(attr) {       if ( this.patterns.defaultUnit.test(attr) ) {         return 'px';       }       return '';   },   /**    * Sets the actual values to be used during the animation.    * @method setRuntimeAttribute    * Should only be needed for subclass use.    * @param {Object} attr The attribute object    * @private    */   setRuntimeAttribute: function(attr) {      var start;      var end;      var attributes = this.attributes;      this.runtimeAttributes[attr] = {};      var isset = function(prop) {         return (typeof prop !== 'undefined');      };      if ( !isset(attributes[attr]['to']) && !isset(attributes[attr]['by']) ) {         return false; // note return; nothing to animate to      }      start = ( isset(attributes[attr]['from']) ) ? attributes[attr]['from'] : this.getAttribute(attr);      // To beats by, per SMIL 2.1 spec      if ( isset(attributes[attr]['to']) ) {         end = attributes[attr]['to'];      } else if ( isset(attributes[attr]['by']) ) {         if (start.constructor == Array) {            end = [];            for (var i = 0, len = start.length; i < len; ++i) {               end[i] = start[i] + attributes[attr]['by'][i];            }         } else {            end = start + attributes[attr]['by'];         }      }      this.runtimeAttributes[attr].start = start;      this.runtimeAttributes[attr].end = end;      // set units if needed      this.runtimeAttributes[attr].unit = ( isset(attributes[attr].unit) ) ? attributes[attr]['unit'] : this.getDefaultUnit(attr);   },   /**    * Constructor for Anim instance.    * @method init    * @param {String | HTMLElement} el Reference to the element that will be animated    * @param {Object} attributes The attribute(s) to be animated.    * Each attribute is an object with at minimum a "to" or "by" member defined.    * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").    * All attribute names use camelCase.    * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based    * @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)    */   init: function(el, attributes, duration, method) {      /**       * Whether or not the animation is running.       * @property isAnimated       * @private       * @type Boolean       */      var isAnimated = false;      /**       * A Date object that is created when the animation begins.       * @property startTime       * @private       * @type Date       */      var startTime = null;      /**       * The number of frames this animation was able to execute.       * @property actualFrames       * @private       * @type Int       */      var actualFrames = 0;      /**       * The element to be animated.       * @property el       * @private       * @type HTMLElement       */      el = YAHOO.util.Dom.get(el);      /**       * The collection of attributes to be animated.       * Each attribute must have at least a "to" or "by" defined in order to animate.       * If "to" is supplied, the animation will end with the attribute at that value.       * If "by" is supplied, the animation will end at that value plus its starting value.       * If both are supplied, "to" is used, and "by" is ignored.       * 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).       * @property attributes       * @type Object       */      this.attributes = attributes || {};      /**       * The length of the animation.  Defaults to "1" (second).       * @property duration       * @type Number       */      this.duration = duration || 1;      /**       * The method that will provide values to the attribute(s) during the animation.       * Defaults to "YAHOO.util.Easing.easeNone".       * @property method       * @type Function       */      this.method = method || YAHOO.util.Easing.easeNone;      /**       * Whether or not the duration should be treated as seconds.       * Defaults to true.       * @property useSeconds       * @type Boolean       */      this.useSeconds = true; // default to seconds      /**       * The location of the current animation on the timeline.       * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.       * @property currentFrame       * @type Int       */      this.currentFrame = 0;      /**       * The total number of frames to be executed.       * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.       * @property totalFrames       * @type Int       */      this.totalFrames = YAHOO.util.AnimMgr.fps;      /**       * Returns a reference to the animated element.       * @method getEl       * @return {HTMLElement}       */      this.getEl = function() { return el; };      /**       * Checks whether the element is currently animated.       * @method isAnimated       * @return {Boolean} current value of isAnimated.       */      this.isAnimated = function() {         return isAnimated;      };      /**       * Returns the animation start time.       * @method getStartTime       * @return {Date} current value of startTime.       */      this.getStartTime = function() {         return startTime;      };      this.runtimeAttributes = {};      /**       * Starts the animation by registering it with the animation manager.       * @method animate       */      this.animate = function() {         if ( this.isAnimated() ) { return false; }         this.currentFrame = 0;         this.totalFrames = ( this.useSeconds ) ? Math.ceil(YAHOO.util.AnimMgr.fps * this.duration) : this.duration;         YAHOO.util.AnimMgr.registerElement(this);      };      /**       * Stops the animation.  Normally called by AnimMgr when animation completes.       * @method stop       * @param {Boolean} finish (optional) If true, animation will jump to final frame.       */      this.stop = function(finish) {         if (finish) {             this.currentFrame = this.totalFrames;             this._onTween.fire();         }         YAHOO.util.AnimMgr.stop(this);      };      var onStart = function() {         this.onStart.fire();         this.runtimeAttributes = {};         for (var attr in this.attributes) {            this.setRuntimeAttribute(attr);         }         isAnimated = true;         actualFrames = 0;         startTime = new Date();      };      /**       * Feeds the starting and ending values for each animated attribute to doMethod once per frame, then applies the resulting value to the attribute(s).       * @private       */      var onTween = function() {         var data = {            duration: new Date() - this.getStartTime(),            currentFrame: this.currentFrame         };         data.toString = function() {            return (               'duration: ' + data.duration +               ', currentFrame: ' + data.currentFrame            );         };         this.onTween.fire(data);         var runtimeAttributes = this.runtimeAttributes;         for (var attr in runtimeAttributes) {            this.setAttribute(attr, this.doMethod(attr, runtimeAttributes[attr].start, runtimeAttributes[attr].end), runtimeAttributes[attr].unit);         }         actualFrames += 1;      };      var onComplete = function() {         var actual_duration = (new Date() - startTime) / 1000 ;         var data = {            duration: actual_duration,            frames: actualFrames,            fps: actualFrames / actual_duration         };         data.toString = function() {            return (               'duration: ' + data.duration +               ', frames: ' + data.frames +               ', fps: ' + data.fps            );         };         isAnimated = false;         actualFrames = 0;         this.onComplete.fire(data);      };      /**       * Custom event that fires after onStart, useful in subclassing       * @private       */      this._onStart = new YAHOO.util.CustomEvent('_start', this, true);      /**       * Custom event that fires when animation begins       * Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)       * @event onStart       */      this.onStart = new YAHOO.util.CustomEvent('start', this);      /**       * Custom event that fires between each frame       * Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)       * @event onTween       */      this.onTween = new YAHOO.util.CustomEvent('tween', this);      /**       * Custom event that fires after onTween       * @private       */      this._onTween = new YAHOO.util.CustomEvent('_tween', this, true);      /**       * Custom event that fires when animation ends       * Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)       * @event onComplete       */      this.onComplete = new YAHOO.util.CustomEvent('complete', this);      /**       * Custom event that fires after onComplete       * @private       */      this._onComplete = new YAHOO.util.CustomEvent('_complete', this, true);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?