/** JS版逐帧动画,功能演示:http://cms.oa.com/demo/Animate/ 安凌志 2015.12.25*/var Animate = function(p){ var I = this, $i = 0, $ed = 0, c = { obj: '', //用于播放的jq对象 src: '', //合并图片地址 step: 1, //单步播放帧 (1顺放)或(-1倒放) max: 0, //若动画需要移动,表示最大的left值 w: 100, //默认宽 h: 100, //默认高 len: 10, //帧数 times: 0, //动画每执行times次,会调用callback callback: '', //回调方法 speed: 30, //单帧播放时间间隔ms replay: 0 //循环播放起点帧 }; //若有多个动画状态,请使用c[0] c[1]下标配置的方法配置,参照http://cms.oa.com/demo/Animate/ if(p) $.extend(c, p); I.$id = 'A'+ Math.random().toString().replace('.',''); c.obj.append('<p id="'+ I.$id +'" style="position:absolute;left:0;margin:0;padding:0;overflow:hidden"></p>'); I.$obj = $o('#'+I.$id); if(!c.max) c.max = c.obj.outerWidth(); //播放 (状态,更新参数) var $sta = -1; I.play = function(sta, p){//sta是当前动画状态,p是当前动画扩展参数 sta = _int(sta); $sta = sta; _reset(p); if($ed){//资源已经加载完 _play(); }else{ if($i) return;//已经在加载资源中 $i = 1; var img = new Image(); img.onload = function(){ $ed = 1; I.$obj.css('background-image','url('+ c.src +')'); _play(); }; img.src = c.src; } }; //移动 var _move; I.$pos = {left:0, top:0}; I.move = function(x, y, speed){ if(speed > 10 || x === 'stop') clearTimeout(_move); if(x === 'stop') return; var css = {}; css.left = _int(I.$obj.css('left')) + _int(x); css.top = _int(I.$obj.css('top')) + _int(y); I.$obj.css(css); I.$pos = css; if(speed > 10){ var fn = function(){ if(!I.$obj[0]) return; if(x) css.left += x; if(y) css.top += y; I.$obj.css(css); I.$pos = css; if(css.left >= c.max) return I.die(); _move = setTimeout(fn, speed); }; fn(); } return css; }; //死亡 I.die = function(){ if(!I.$obj[0]) return; if(_t)clearTimeout(_t); I.$obj.remove(); I.$obj[0] = null; }; /**以下为私有方法 ******************************************************/ var $c = {}, $frame, $def, $top = 0, _reset = function(p){//重置动画状态属性 if($c.x || $c.y) I.move(-$c.x, -$c.y);//若上一个状态有坐标偏移,在此处还原回去 $c = c[$sta] ? clone(c[$sta]) : {}; $.each(['w','h','len','speed','replay','times'], function(i,k){ if(!$c[k]) $c[k] = c[k]; }); if(p) $.extend($c, p); if($c.x !== 0 || $c.y !== 0) I.move($c.x||0, $c.y||0);//坐标偏移 $def = c.step > 0 ? 0 : $c.len; $frame = $def; $top = 0; for(var i=0; i<$sta; i++){ var o = c[i] || {}; $top -= o.h || c.h; } I.$obj.css({width:$c.w, height:$c.h,'background-position':'0 '+ $top +'px'}); }, _int = function(v){//取整 return parseInt(v) || 0; }, _t, _play = function(){ var n = 0,//播放次数 f = function(){ if(!I.$obj[0]) return; I.$obj.css('background-position', '-'+ ($c.w*$frame) +'px '+ $top +'px'); $frame += c.step; if(c.step > 0 ? $frame >= $c.len : $frame <= 0){ $frame = $c.replay || c.replay || $def; I.$obj = $o('#'+I.$id);//防止dom不存在的时候,动画不消失 n++; if($c.times > 0 && n % $c.times === 0 && typeof c.callback == 'function'){ c.callback(I, {n:n,sta:$sta}); } } _t = setTimeout(f, $c.speed); }; if(_t) clearTimeout(_t); f(); };};