1. /**
    2. JS版逐帧动画,功能演示:http://cms.oa.com/demo/Animate/
    3. 安凌志 2015.12.25
    4. */
    5. var Animate = function(p){
    6. var I = this, $i = 0, $ed = 0, c = {
    7. obj: '', //用于播放的jq对象
    8. src: '', //合并图片地址
    9. step: 1, //单步播放帧 (1顺放)或(-1倒放)
    10. max: 0, //若动画需要移动,表示最大的left值
    11. w: 100, //默认宽
    12. h: 100, //默认高
    13. len: 10, //帧数
    14. times: 0, //动画每执行times次,会调用callback
    15. callback: '', //回调方法
    16. speed: 30, //单帧播放时间间隔ms
    17. replay: 0 //循环播放起点帧
    18. };
    19. //若有多个动画状态,请使用c[0] c[1]下标配置的方法配置,参照http://cms.oa.com/demo/Animate/
    20. if(p) $.extend(c, p);
    21. I.$id = 'A'+ Math.random().toString().replace('.','');
    22. c.obj.append('<p id="'+ I.$id +'" style="position:absolute;left:0;margin:0;padding:0;overflow:hidden"></p>');
    23. I.$obj = $o('#'+I.$id);
    24. if(!c.max) c.max = c.obj.outerWidth();
    25. //播放 (状态,更新参数)
    26. var $sta = -1;
    27. I.play = function(sta, p){//sta是当前动画状态,p是当前动画扩展参数
    28. sta = _int(sta);
    29. $sta = sta;
    30. _reset(p);
    31. if($ed){//资源已经加载完
    32. _play();
    33. }else{
    34. if($i) return;//已经在加载资源中
    35. $i = 1;
    36. var img = new Image();
    37. img.onload = function(){
    38. $ed = 1;
    39. I.$obj.css('background-image','url('+ c.src +')');
    40. _play();
    41. };
    42. img.src = c.src;
    43. }
    44. };
    45. //移动
    46. var _move;
    47. I.$pos = {left:0, top:0};
    48. I.move = function(x, y, speed){
    49. if(speed > 10 || x === 'stop') clearTimeout(_move);
    50. if(x === 'stop') return;
    51. var css = {};
    52. css.left = _int(I.$obj.css('left')) + _int(x);
    53. css.top = _int(I.$obj.css('top')) + _int(y);
    54. I.$obj.css(css);
    55. I.$pos = css;
    56. if(speed > 10){
    57. var fn = function(){
    58. if(!I.$obj[0]) return;
    59. if(x) css.left += x;
    60. if(y) css.top += y;
    61. I.$obj.css(css);
    62. I.$pos = css;
    63. if(css.left >= c.max) return I.die();
    64. _move = setTimeout(fn, speed);
    65. };
    66. fn();
    67. }
    68. return css;
    69. };
    70. //死亡
    71. I.die = function(){
    72. if(!I.$obj[0]) return;
    73. if(_t)clearTimeout(_t);
    74. I.$obj.remove();
    75. I.$obj[0] = null;
    76. };
    77. /**以下为私有方法 ******************************************************/
    78. var $c = {}, $frame, $def, $top = 0, _reset = function(p){//重置动画状态属性
    79. if($c.x || $c.y) I.move(-$c.x, -$c.y);//若上一个状态有坐标偏移,在此处还原回去
    80. $c = c[$sta] ? clone(c[$sta]) : {};
    81. $.each(['w','h','len','speed','replay','times'], function(i,k){
    82. if(!$c[k]) $c[k] = c[k];
    83. });
    84. if(p) $.extend($c, p);
    85. if($c.x !== 0 || $c.y !== 0) I.move($c.x||0, $c.y||0);//坐标偏移
    86. $def = c.step > 0 ? 0 : $c.len;
    87. $frame = $def;
    88. $top = 0;
    89. for(var i=0; i<$sta; i++){
    90. var o = c[i] || {};
    91. $top -= o.h || c.h;
    92. }
    93. I.$obj.css({width:$c.w, height:$c.h,'background-position':'0 '+ $top +'px'});
    94. },
    95. _int = function(v){//取整
    96. return parseInt(v) || 0;
    97. }, _t,
    98. _play = function(){
    99. var n = 0,//播放次数
    100. f = function(){
    101. if(!I.$obj[0]) return;
    102. I.$obj.css('background-position', '-'+ ($c.w*$frame) +'px '+ $top +'px');
    103. $frame += c.step;
    104. if(c.step > 0 ? $frame >= $c.len : $frame <= 0){
    105. $frame = $c.replay || c.replay || $def;
    106. I.$obj = $o('#'+I.$id);//防止dom不存在的时候,动画不消失
    107. n++;
    108. if($c.times > 0 && n % $c.times === 0 && typeof c.callback == 'function'){
    109. c.callback(I, {n:n,sta:$sta});
    110. }
    111. }
    112. _t = setTimeout(f, $c.speed);
    113. };
    114. if(_t) clearTimeout(_t);
    115. f();
    116. };
    117. };