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

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

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

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

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

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

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

演示

id:cc



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};比如{'100px',height:'+=100px',opacity:0.5},

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

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

D:回调函数;[可选]

3:方法说明

   1:animate()方法

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

   2:stop()方法

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

  3:delay()方法

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

我会一直把他完善下去。


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

压缩过的源码
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};

代码
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/p/1759605.html