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 **/