/** * @ignore * animate on single property * @author yiminghe@gmail.com */ KISSY.add('anim/fx', function (S, DOM, undefined) { /** * basic animation about single css property or element attribute * @class KISSY.Anim.Fx * @private */ function Fx(cfg) { this.load(cfg); } Fx.prototype = { constructor: Fx, /** * reset config. * @param cfg */ load: function (cfg) { var self = this; S.mix(self, cfg); self.pos = 0; self.unit = self.unit || ''; }, /** * process current anim frame. * @param {Boolean} end whether this anim is ended * @return {Number} * */ frame: function (end) { var self = this, anim = self.anim, endFlag = 0, elapsedTime; if (self.finished) { return 1; } var t = S.now(), _startTime = anim._startTime, duration = anim._duration; if (end || t >= duration + _startTime) { self.pos = 1; endFlag = 1; } else { elapsedTime = t - _startTime; self.pos = self.easing(elapsedTime / duration); } self.update(); self.finished = self.finished || endFlag; return endFlag; }, /** * interpolate function * * @param {Number} from current css value * @param {Number} to end css value * @param {Number} pos current position from easing 0~1 * @return {Number} value corresponding to position */ interpolate: function (from, to, pos) { // 默认只对数字进行 easing if (S.isNumber(from) && S.isNumber(to)) { return (from + (to - from) * pos).toFixed(3); } else { return undefined; } }, /** * update dom according to current frame css value. * */ update: function () { var self = this, anim = self.anim, prop = self.prop, el = anim.config.el, from = self.from, to = self.to, val = self.interpolate(from, to, self.pos); if (val === undefined) { // 插值出错,直接设置为最终值 if (!self.finished) { self.finished = 1; DOM.css(el, prop, to); S.log(prop + ' update directly ! : ' + val + ' : ' + from + ' : ' + to); } } else { val += self.unit; if (isAttr(el, prop)) { DOM.attr(el, prop, val, 1); } else { // S.log(self.prop + ' update: ' + val); DOM.css(el, prop, val); } } }, /** * current value * */ cur: function () { var self = this, prop = self.prop, el = self.anim.config.el; if (isAttr(el, prop)) { return DOM.attr(el, prop, undefined, 1); } var parsed, r = DOM.css(el, prop); // Empty strings, null, undefined and 'auto' are converted to 0, // complex values such as 'rotate(1rad)' or '0px 10px' are returned as is, // simple values such as '10px' are parsed to Float. return isNaN(parsed = parseFloat(r)) ? !r || r === 'auto' ? 0 : r : parsed; } }; function isAttr(el, prop) { // support scrollTop/Left now! if ((!el.style || el.style[ prop ] == null) && DOM.attr(el, prop, undefined, 1) != null) { return 1; } return 0; } Fx.Factories = {}; Fx.getFx = function (cfg) { var Constructor = Fx.Factories[cfg.prop] || Fx; return new Constructor(cfg); }; return Fx; }, { requires: ['dom'] }); /* TODO 支持 transform ,ie 使用 matrix - http://shawphy.com/2011/01/transformation-matrix-in-front-end.html - http://www.cnblogs.com/winter-cn/archive/2010/12/29/1919266.html - 标准:http://www.zenelements.com/blog/css3-transform/ - ie: http://www.useragentman.com/IETransformsTranslator/ - wiki: http://en.wikipedia.org/wiki/Transformation_matrix - jq 插件: http://plugins.jquery.com/project/2d-transform */