/* * 动画类 * elem 动画dom对象 * prop 目标样式集合 * duration 总用时长 * callback 回调函数 * 原生JS */var Animation = function(elem, prop, duration, callback){ if(!elem || elem.nodeType != 1) return; this.elem = elem; this.duration = duration; this.callback = callback && typeof callback == 'function' ? callback : function(){}; this.interval = 13; this.timer = null; this.propStyle = {}; this.curStyle = {}; this.initStyle(elem, prop);}Animation.prototype = { /* * 格式化动画两极样式 * elem 动画dom对象 * prop 目标样式集合 * return this.curStyle:初始样式集合 this.propStyle:目标样式集合 * 支持opacity/width/height/left/top/marginLeft...等,单位px */ initStyle: function(elem, prop){ var isIE = /*@cc_on!@*/!1; var currentStyle = elem.currentStyle || window.getComputedStyle(elem, null); //当前对象样式集合,包括css及style内样式 for(var o in prop){ var curVal = o=='opacity' && isIE ? currentStyle['filter'] : currentStyle[o]; if(o=='opacity' && isIE){ var match = curVal.match(/opacity=(\d+)/i); curVal = match ? parseFloat(match[1]) / 100 : 1; }else{ curVal = parseFloat(curVal); } if(typeof curVal == 'number'){ this.curStyle[o] = curVal; //this.propStyle[o] = curVal + parseFloat(prop[o]); this.propStyle[o] = parseFloat(prop[o]); } } }, /* * 执行函数 * 13ms为一帧 this.interval = 13 */ run: function(){ var queue = parseInt(this.elem.getAttribute('animating')) || 0; this.elem.setAttribute('animating', queue + 1); this.startTime = this.now(); this.timer = setInterval(this.tick.bind(this), this.interval); }, /* * 结束动画并执行回调函数 */ stop: function(){ clearInterval(this.timer); this.timer = null; var elem = this.elem; var queue = parseInt(elem.getAttribute('animating')) || 0; if(queue <= 1){ elem.removeAttribute('animating'); }else{ elem.setAttribute('animating', queue - 1); } this.callback.call(elem); }, /* * 返回对象当前动画数 */ queue: function(){ return parseInt(this.elem.getAttribute('animating')) || 0; }, /* * 进度计算 * percent为当前进度,1时结束动画 */ tick: function(){ var currentTime = this.now(), remaining = Math.max( 0, this.startTime + this.duration - currentTime ), //剩余时间 temp = remaining / this.duration || 0, //剩余时间所占比例 percent = 1- temp; //当前进度 if(percent <= 1){ this.tweens(percent); }else{ this.stop(); } }, /* * 动画 */ tweens: function(percent){ var isIE = /*@cc_on!@*/!1; var style = this.elem.style; for(var o in this.propStyle){ var start = this.curStyle[o], end = this.propStyle[o]; var now = start + ((end - start) * percent); //计算当前值 if(o == 'opacity'){ if(isIE){ style.filter = 'alpha(opacity='+ parseInt(now * 100) +')'; }else{ style.opacity = now; } }else{ style[o] = now + 'px'; } } if(percent == 1){ this.stop(); } }, /* * 返回当前时间戳 */ now: function(){ return ( new Date() ).getTime(); }}var anim = new Animation(elem, {'height': 0}, 3000, function(){});anim.run();