【分享】2.5KB-打造jquery的animate。(自定义动画)

第一篇文章是前几天写的。当时也不知道是不是发神经了。就模仿jquery的animate写了一个简单的动画实现方法。
后来发现还不错。不如继续写下去。这个版本基本上跟jquery的animate一样了。我是说效果基本上一样了。(效率还没测试过。);
如果有专业测试人员 帮我测试下。

第一篇文章是前几天写的。当时也不知道是不是发神经了。就模仿jquery的animate写了一个简单的动画实现方法。

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

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

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

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

演示

id:cc

 

jelle('cc').animate({width:'100px',height:'100px',opacity:0.1},2000,function(){this.style.backgroundColor='#000'}).delay(500).animate({width:'500px',opacity:1},2000);
jelle('cc').stop();
jelle('cc').animate({width:'+=150px'},500,function(){this.style.backgroundColor='#666'});

 

 

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秒执行。

 

 

我会一直把他完善下去。


点击下载源码和压缩后的JS

 

 
   
ContractedBlock.gif ExpandedBlockStart.gif 压缩过的源码
 
      
var jelle = function (h){ var a = document.getElementById(h),o = 0 ,e = {},l = 10 ,k = function (b,c,g,d){ return - g * (b / =d)*(b-2)+c},n=function(b,c){var g,d= / ^ ([ +- \\ * \ / ]=)([-]?[\d.]+) / ; if (d.test(b)){d = b.match(d);d[ 2 ] = parseFloat(d[ 2 ]); switch (d[ 1 ]){ case " += " :g = d[ 2 ]; break ; case " -= " :g =- d[ 2 ]; break ; case " *= " :g = c * d[ 2 ] - c; break ; case " /= " :g = c / d[2]-c;break}return g}return parseFloat(b)-c};a.animate=a.animate||[];jelle[h]={};jelle[h].stop=true;e.entrance=function(b,c,g){setTimeout(function(){b(c[0],c[1],c[2])},g||0)};e.stop=function(){jelle[h].stop=
false ;a.animate.length = 0 ;document.getElementById(h).animate.length = 0 ; return e};e.queue = function (){ if (a.animate &&++ o == a.animate[ 0 ].length){o = 0 ;a.animate[ 0 ].callback && a.animate[ 0 ].callback.apply(a); if (a.animate.length > 1 ){a.animate[ 0 ].callback = a.animate[ 1 ].callback;a.animate = document.getElementById(h).animate || [];a.animate.shift();document.getElementById(h).animate = a.animate; for ( var b = a.animate[ 0 ],c = 0 ;c < b.length;c ++ )b[c][ 0 ] === " opacity " ? e.entrance(e.alpha,[b[c][ 1 ],b[c][ 2 ]],l):e.entrance(e.execution,[b[c][ 0 ],
b[c][
1 ],b[c][ 2 ]],l)} else {a.animate.length = 0 ;document.getElementById(h).animate.length = 0 }}};e.delay = function (b){l = b; return e};e.execution = function (b,c,g){ var d = ( new Date).getTime(),f = g || 500 ,j = parseFloat(a.style[b]) || 0 ,i = n(c,j),p = c.match( / \d+(.+) / )[ 1 ];( function (){ var m = ( new Date).getTime() - d; if (m > f){m = f;a.style[b] = parseInt(k(m,j,i,f)) + p;e.queue(); return e}a.style[b] = parseInt(k(m,j,i,f)) + p;jelle[h].stop && setTimeout(arguments.callee, 10 )})()};e.animate = function (b,c,g){ var d = a.animate.length;a.animate[d] =
[];a.animate[d].callback
= g; for ( var f in b){a.animate[d].push([f,b[f],c]); if (d == 0 )f == " opacity " ? e.entrance(e.alpha,[b[f],c],l):e.entrance(e.execution,[f,b[f],c],l)}document.getElementById(h).animate = a.animate; return e};e.alpha = function (b,c){ var g = ( new Date).getTime(),d = c || 500 ,f,j; if (document.defaultView){f = document.defaultView.getComputedStyle(a, null ).opacity || 1 ;j = n(b,f) * 100 ;( function (){ var i = ( new Date).getTime() - g; if (i > d){i = d;a.style.opacity = k(i, 100 * f,j,d) / 100;e.queue();return e}a.style.opacity=k(i,
100 * f,j,d) / 100;jelle[h].stop&&setTimeout(arguments.callee,10)})()}else{f=a.currentStyle.filter?a.currentStyle.filter.match( / ^ alpha\(opacity = ([\d\.] + )\)$ / )[1] / 100 : 1 ;j = n(b,f) * 100 ;( function (){ var i = ( new Date).getTime() - g; if (i > d){i = d;a.style.filter = " alpha(opacity= " + k(i, 100 * f,j,d) + " ) " ;e.queue(); return e}a.style.filter = " alpha(opacity= " + k(i, 100 * f,j,d) + " ) " ;jelle[h].stop && setTimeout(arguments.callee, 10 )})()}}; return e};

 


 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
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/

转载请注明。

转载于:https://www.cnblogs.com/idche/archive/2010/06/17/1759605.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值