1 /**
  2  * @fileOverview animate on single property
  3  * @author yiminghe@gmail.com
  4  */
  5 KISSY.add("anim/fx", function (S, DOM, undefined) {
  6 
  7     /**
  8      * basic animation about single css property or element attribute
  9      * @param cfg
 10      */
 11     function Fx(cfg) {
 12         this.load(cfg);
 13     }
 14 
 15     S.augment(Fx, {
 16 
 17         load:function (cfg) {
 18             var self = this;
 19             S.mix(self, cfg);
 20             self.pos = 0;
 21             self.unit = self.unit || "";
 22         },
 23 
 24         frame:function (end) {
 25             var self = this,
 26                 anim = self.anim,
 27                 endFlag = 0,
 28                 elapsedTime;
 29             if (self.finished) {
 30                 return 1;
 31             }
 32             var t = S.now(),
 33                 _startTime = anim._startTime,
 34                 duration = anim.config.duration;
 35             if (end || t >= duration + _startTime) {
 36                 self.pos = 1;
 37                 endFlag = 1;
 38             } else {
 39                 elapsedTime = t - _startTime;
 40                 self.pos = self.easing(elapsedTime / duration);
 41             }
 42             self.update();
 43             self.finished = self.finished || endFlag;
 44             return endFlag;
 45         },
 46 
 47         /**
 48          * 数值插值函数
 49          * @param {Number} from 源值
 50          * @param {Number} to 目的值
 51          * @param {Number} pos 当前位置,从 easing 得到 0~1
 52          * @return {Number} 当前值
 53          */
 54         interpolate:function (from, to, pos) {
 55             // 默认只对数字进行 easing
 56             if (S.isNumber(from) &&
 57                 S.isNumber(to)) {
 58                 return (from + (to - from) * pos).toFixed(3);
 59             } else {
 60                 return undefined;
 61             }
 62         },
 63 
 64         update:function () {
 65             var self = this,
 66                 anim = self.anim,
 67                 prop = self.prop,
 68                 elem = anim.elem,
 69                 from = self.from,
 70                 to = self.to,
 71                 val = self.interpolate(from, to, self.pos);
 72 
 73             if (val === undefined) {
 74                 // 插值出错,直接设置为最终值
 75                 if (!self.finished) {
 76                     self.finished = 1;
 77                     DOM.css(elem, prop, to);
 78                     S.log(self.prop + " update directly ! : " + val + " : " + from + " : " + to);
 79                 }
 80             } else {
 81                 val += self.unit;
 82                 if (isAttr(elem, prop)) {
 83                     DOM.attr(elem, prop, val, 1);
 84                 } else {
 85                     DOM.css(elem, prop, val);
 86                 }
 87             }
 88         },
 89 
 90         /**
 91          * current value
 92          */
 93         cur:function () {
 94             var self = this,
 95                 prop = self.prop,
 96                 elem = self.anim.elem;
 97             if (isAttr(elem, prop)) {
 98                 return DOM.attr(elem, prop, undefined, 1);
 99             }
100             var parsed,
101                 r = DOM.css(elem, prop);
102             // Empty strings, null, undefined and "auto" are converted to 0,
103             // complex values such as "rotate(1rad)" or "0px 10px" are returned as is,
104             // simple values such as "10px" are parsed to Float.
105             return isNaN(parsed = parseFloat(r)) ?
106                 !r || r === "auto" ? 0 : r
107                 : parsed;
108         }
109     });
110 
111     function isAttr(elem, prop) {
112         // support scrollTop/Left now!
113         if ((!elem.style || elem.style[ prop ] == null) &&
114             DOM.attr(elem, prop, undefined, 1) != null) {
115             return 1;
116         }
117         return 0;
118     }
119 
120     Fx.Factories = {};
121 
122     Fx.getFx = function (cfg) {
123         var Constructor = Fx.Factories[cfg.prop] || Fx;
124         return new Constructor(cfg);
125     };
126 
127     return Fx;
128 
129 }, {
130     requires:['dom']
131 });
132 /**
133  * TODO
134  * 支持 transform ,ie 使用 matrix
135  *  - http://shawphy.com/2011/01/transformation-matrix-in-front-end.html
136  *  - http://www.cnblogs.com/winter-cn/archive/2010/12/29/1919266.html
137  *  - 标准:http://www.zenelements.com/blog/css3-transform/
138  *  - ie: http://www.useragentman.com/IETransformsTranslator/
139  *  - wiki: http://en.wikipedia.org/wiki/Transformation_matrix
140  *  - jq 插件: http://plugins.jquery.com/project/2d-transform
141  **/