用js实现的模拟jquery的animate自定义动画(2.5K)

  后来发现还不错。不如继续写下去。

  这个版本基本上跟jquery的animate一样了。

  我是说效果基本上一样了。(效率还没测试过。);

  如果有专业测试人员 帮我测试下。

  1:功能说明

  兼容主流浏览器。

  1:支持回调函数;

    2:支持级联动画调用;

  3:支持delay动画队列延迟;

    4:支持stop停止动画;

  5:支持opacity透明度变化;

  6:支持+= -= *= /=操作;

  7:支持单位操作(px, %);

  2:使用说明

  jelle(A).animate(B, C, D);

  A:需要执行动画的dom元素ID;

  B:动画的主要参数传递{key,val,key2,val2};比如{width:'100px',height:'+=100px',opacity:0.5},

  opacity--透明度变化 支持+= -= *= /=操作。

  C:动画执行用时,以毫秒为单位;[可选 默认500毫秒];

  D:回调函数;[可选]

  3:方法说明

  1:animate()方法

  jelle('cc').animate({width:'100px'},300,function(){alert('完成')});// 是 cc 的宽度在300毫秒的时间变化到100px 动画结束 弹出 ‘完成'

  2:stop()方法

  jelle('cc').stop();//停止正在 cc 对象上播放的动画。

  3:delay()方法

  jelle('cc').delay(1000).animate({width:'100px'});//cc 的宽度发生变化 将被延迟1秒执行。

  我会一直把他完善下去。

  

复制代码 代码如下:

  var jelle = function(id){

  var $ = function(id){ return document.getElementById(id); },

  elem = $(id),//对象

  f = 0, _this = {}, lazy = 10, lazyque = 10,// f动画计数器 lazy动画延迟 lazyque队列延迟

  // 算子你可以改变他来让你的动画不一样

  tween = function(t, b, c, d){ return - c * (t /= d) * (t - 2) + b},

  // adv 用于+= -= *= /=操作

  adv = function(val, b){

  var va, re= /^([+-\\*\/]=)([-]?[\d.]+)/ ;

  if (re.test(val)){

  var reg = val.match(re);

  reg[2] = parseFloat(reg[2]);

  switch ( reg[1] ){

  case '+=':

  va = reg[2];

  break;

  case '-=':

  va = -reg[2];

  break;

  case '*=':

  va = b*reg[2] - b;

  break;

  case '/=':

  va = b/reg[2] - b;

  break;

  }

  return va;

  }

  return parseFloat(val) - b;

  }

  // elem.animate 读取用于当前dom元素上的动画队列

  elem.animate = elem.animate || [];

  //stop 功能要使用的

  jelle[id]= {};

  jelle[id]['stop'] = true;

  //alert(jelle[id]['stop'])

  // 统一队列入口 用于方便设置延迟,与停止

  _this.entrance = function(fn, ags, lazytime){

  //fn 调用函数 ags 参数 lazytime 延迟时间

  setTimeout(function(){

  fn(ags[0], ags[1], ags[2]);

  }, (lazytime || 0));

  }

  // 停止动画 此方法还不能用

  _this.stop = function(){

  jelle[id]['stop'] = false;

  elem.animate.length=0;

  $(id).animate.length=0;

  return _this;

  }

  // 队列操作

  _this.queue = function(){

  if (elem.animate && ++f == elem.animate[0].length){

  f = 0;// 清空计数器

  elem.animate[0].callback ? elem.animate[0].callback.apply(elem) : false;

  // 判断是否有动画在等待执行

  if (elem.animate.length > 1){

  elem.animate[0].callback = elem.animate[1].callback;

  elem.animate = $(id).animate || [];// 从dom对象上获取最新动画队列

  elem.animate.shift();// 清除刚执行完的动画队列

  $(id).animate = elem.animate;// 把新的队列更新到dom

  var ea = elem.animate[0];

  // 循环播放队列动画

  for(var i = 0; i < ea.length; i++){

  ea[i][0] === 'opacity' ? _this.entrance(_this.alpha, [ea[i][1], ea[i][2]], lazyque):

  _this.entrance(_this.execution, [ea[i][0], ea[i][1], ea[i][2]], lazyque);

  }

  }else{

  elem.animate.length = 0; // 队列清楚

  $(id).animate.length = 0; // 队列清楚

  }

  }

  }

  //设置lazy方法,以后的队列动画延迟时间

  _this.delay = function(val){

  lazyque = val;

  return _this;

  }

  //动画变化

  _this.execution = function(key, val, t){

  //alert(val)

  var s = (new Date()).getTime(), d=t || 500 ,

  b = parseFloat(elem.style[key]) || 0 ,

  c = adv(val, b) ,// adv用于设置高级操作比如 += -= 等等

  un = val.match(/\d+(.+)/)[1];// 单位

  (function(){

  var t = (new Date()).getTime() - s;

  if (t > d){

  t = d;

  elem.style[key] = parseInt(tween(t, b, c, d)) + un;

  _this.queue(); // 操作队列

  return _this;

  }

  elem.style[key] = parseInt(tween(t, b, c, d)) + un;

  jelle[id]['stop'] && setTimeout(arguments.callee, lazy);

  // _this.entrance(arguments.callee,[1,1,1],lazy);

  // arguments.callee 匿名函数递归调用

  })();

  }

  // 入口

  _this.animate = function(sty, t, fn){

  // sty,t,fn 分别为 变化的参数key,val形式,动画用时,回调函数

  var len = elem.animate.length;// len查看动画队列长度

  elem.animate[len] = [];

  elem.animate[len].callback = fn;

  //多key 循环设置变化

  for(var i in sty){

  elem.animate[len].push([i, sty[i], t]);

  if(len == 0){

  i == 'opacity' ? _this.entrance(_this.alpha, [sty[i], t], lazyque) :

  _this.entrance(_this.execution, [i, sty[i], t], lazyque);

  }

  }

  $(id).animate = elem.animate;//把新的动画队列添加到dom元素上

  return _this;

  }

  // 透明度变化的代码

  _this.alpha = function(val, t){

  var s = (new Date()).getTime(),

  d = t || 500, b, c;

  if( document.defaultView ){

  b = document.defaultView.getComputedStyle(elem,null)['opacity'] || 1,

  c = adv(val,b) * 100;

  (function(){

  var t = (new Date()).getTime() - s;

  if(t > d){

  t = d;

  elem.style['opacity'] = tween(t, (100 * b), c, d) / 100;

  _this.queue(); // 队列控制

  return _this;

  }

  elem.style['opacity'] = tween(t, (100 * b), c, d) / 100;

  jelle[id]['stop'] && setTimeout(arguments.callee, lazy);

  })()

  }else{

  b = elem.currentStyle['filter'] ?

  (elem.currentStyle['filter'].match(/^alpha\(opacity=([\d\.]+)\)$/))[1]/100 : 1;

  c = adv(val, b) * 100;

  (function(){

  var t = (new Date()).getTime() - s;

  if (t > d){

  t = d;

  elem.style['filter']='alpha(opacity='+ tween(t, (100 * b), c, d) +')';

  _this.queue(); // 队列控制

  return _this;

  }

  elem.style['filter'] = 'alpha(opacity='+ tween(t, (100*b) , c, d) +')';

  jelle[id]['stop'] && setTimeout(arguments.callee, lazy);

  })()

  }

  }

  return _this;

  }

  代码打包下载

  程序可能每天都在修改。如果想要最新的ainimate 可以email联系我。

  上面的代码已经不是最新的了。

  这两天又修正了几个错误的地方。

  本文来自博客园 jelle 博客 http://www.cnblogs.com/idche/