87407607 2010-07-19
代码如下:
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; }