前段时间为了做动画,学习了一下tween算法的使用,这几天根据tween算法,然后根据各种材料参考,做了一个简单的动画函数.
实现的功能:移动,暂停,恢复,停止.
未实现的功能:无法实现单位换算,不能实现颜色渐变(还有很多,有待完善...)
代码中的使用方法如下:
var
$m
=
$M(
"
divAnimate
"
);
_( " btnAnimate " ).onclick = function (){
this .disabled = true ;
var that = this ;
$m.animate({left: " 300px " ,top: " 100px " ,width: " 300px " , height: " 200px " ,opacity: 0.3 },{duration: 5000 ,easing:Tween.Back.easeInOut}).delay( 200 ).animate({left: " 50px " ,top: " 300px " ,width: " 150px " ,height: " 100px " ,opacity: 0.8 },{duration: 2000 ,easing:Tween.Elastic.easeInOut,callback: function (){
that.disabled = false ;
}
});
}
_( " btnPause " ).onclick = function (){
$m.pause();
this .disabled = true ;
_( " btnResume " ).disabled = false ;
}
_( " btnResume " ).disabled = true ;
_( " btnResume " ).onclick = function (){
$m.resume();
this .disabled = true ;
_( " btnPause " ).disabled = false ;
}
_( " btnStop " ).onclick = function (){
$m.stop();
_( " btnAnimate " ).disabled = false ;
}
_( " btnAnimate " ).onclick = function (){
this .disabled = true ;
var that = this ;
$m.animate({left: " 300px " ,top: " 100px " ,width: " 300px " , height: " 200px " ,opacity: 0.3 },{duration: 5000 ,easing:Tween.Back.easeInOut}).delay( 200 ).animate({left: " 50px " ,top: " 300px " ,width: " 150px " ,height: " 100px " ,opacity: 0.8 },{duration: 2000 ,easing:Tween.Elastic.easeInOut,callback: function (){
that.disabled = false ;
}
});
}
_( " btnPause " ).onclick = function (){
$m.pause();
this .disabled = true ;
_( " btnResume " ).disabled = false ;
}
_( " btnResume " ).disabled = true ;
_( " btnResume " ).onclick = function (){
$m.resume();
this .disabled = true ;
_( " btnPause " ).disabled = false ;
}
_( " btnStop " ).onclick = function (){
$m.stop();
_( " btnAnimate " ).disabled = false ;
}
功能实现:
/*
简单动画方法
* 未实现单位换算
*/
var $M = function (obj){
var elem = ( " string " === typeof obj ) ? document.getElementById(obj):obj;
var _this = {},props = {},timeId,isBusy = false ,isPause = false ;
var queue = [],_current;
// 直线运动算法
function Linear(t,b,c,d){ return c * t / d + b;}
function setCss(className,value){
if (className == " opacity " ){
if (document.defaultView){
elem.style[ " opacity " ] = value;
} else {
elem.style[ " filter " ] = ' alpha(opacity= ' + 100 * value + ' ) ' ;
}
} else {
elem.style[className] = value;
}
}
function getCss(className){
if (className == " opacity " ){
var ret = "" ;
if (document.defaultView){
ret = document.defaultView.getComputedStyle(elem, null )[ ' opacity ' ] || 1 ;
} else {
ret = elem.currentStyle[ ' filter ' ] ? (elem.currentStyle[ ' filter ' ].match( / ^alpha\(opacity=([\d\.]+)\)$ / ))[ 1 ] / 100 : 1;
}
return ret.toString();
} else {
return elem.style[className].toString();
}
}
function _move(params,easing,st,ht,callback){
var t = (( new Date()).getTime() - st);
_current.t = t;
if (isPause){ return ;}
easing = easing || Linear;
ht = ht || 500 ;
for ( var p in params){
if ( ! props[p]){
var iv = parseFloat(getCss(p)) || 0 ;
var ev = parseFloat(params[p]);
props[p] = {
iv:iv,
iu:iv ? getCss(p).substring(iv.toString().length): null ,
ev:ev,
eu:params[p].toString().substring(ev.toString().length)
}
// TODO(初始值的单位和目标值的单位不相同需要处理)
}
if (t >= ht){t = ht;}
var nv = easing(t,props[p].iv,(props[p].ev - props[p].iv),ht);
nv = parseFloat(nv);
setCss(p,nv + props[p].eu);
}
if (t < ht){
timeId = setTimeout( function (){
_move(params,easing,st,ht,callback);
}, 13 );
} else {
props = {};
isBusy = false ;
if (callback){
callback();
}
run();
}
}
function run(){
if ( ! isBusy && queue.length != 0 ){
var o = queue.shift();
var _delay = 0 ;
while (o && o.delay){
_delay += o.delay;
o = queue.shift();
}
if (o){
_current = o;
isBusy = true ;
setTimeout( function (){
var st = ( new Date()).getTime();
_move(o.params,o.options.easing,st,o.options.duration,o.options.callback);
},_delay);
}
}
}
var _this = {
animate: function (params,options){
queue.push({params:params,options:options});
isPause = false ;
run();
return _this;
},
delay: function (ms){
queue.push({delay:ms});
return _this;
},
pause: function (){
isPause = true ;
return _this;
},
resume: function (){
if (_current){
var o = _current;
isPause = false ;
var st = ( new Date()).getTime() - _current.t;
_move(o.params,o.options.easing,st,o.options.duration,o.options.callback);
return _this;
}
},
stop: function (){
isPause = true ;
isBusy = false ;
queue = [];
props = {};
return _this;
}
};
return _this;
}
* 未实现单位换算
*/
var $M = function (obj){
var elem = ( " string " === typeof obj ) ? document.getElementById(obj):obj;
var _this = {},props = {},timeId,isBusy = false ,isPause = false ;
var queue = [],_current;
// 直线运动算法
function Linear(t,b,c,d){ return c * t / d + b;}
function setCss(className,value){
if (className == " opacity " ){
if (document.defaultView){
elem.style[ " opacity " ] = value;
} else {
elem.style[ " filter " ] = ' alpha(opacity= ' + 100 * value + ' ) ' ;
}
} else {
elem.style[className] = value;
}
}
function getCss(className){
if (className == " opacity " ){
var ret = "" ;
if (document.defaultView){
ret = document.defaultView.getComputedStyle(elem, null )[ ' opacity ' ] || 1 ;
} else {
ret = elem.currentStyle[ ' filter ' ] ? (elem.currentStyle[ ' filter ' ].match( / ^alpha\(opacity=([\d\.]+)\)$ / ))[ 1 ] / 100 : 1;
}
return ret.toString();
} else {
return elem.style[className].toString();
}
}
function _move(params,easing,st,ht,callback){
var t = (( new Date()).getTime() - st);
_current.t = t;
if (isPause){ return ;}
easing = easing || Linear;
ht = ht || 500 ;
for ( var p in params){
if ( ! props[p]){
var iv = parseFloat(getCss(p)) || 0 ;
var ev = parseFloat(params[p]);
props[p] = {
iv:iv,
iu:iv ? getCss(p).substring(iv.toString().length): null ,
ev:ev,
eu:params[p].toString().substring(ev.toString().length)
}
// TODO(初始值的单位和目标值的单位不相同需要处理)
}
if (t >= ht){t = ht;}
var nv = easing(t,props[p].iv,(props[p].ev - props[p].iv),ht);
nv = parseFloat(nv);
setCss(p,nv + props[p].eu);
}
if (t < ht){
timeId = setTimeout( function (){
_move(params,easing,st,ht,callback);
}, 13 );
} else {
props = {};
isBusy = false ;
if (callback){
callback();
}
run();
}
}
function run(){
if ( ! isBusy && queue.length != 0 ){
var o = queue.shift();
var _delay = 0 ;
while (o && o.delay){
_delay += o.delay;
o = queue.shift();
}
if (o){
_current = o;
isBusy = true ;
setTimeout( function (){
var st = ( new Date()).getTime();
_move(o.params,o.options.easing,st,o.options.duration,o.options.callback);
},_delay);
}
}
}
var _this = {
animate: function (params,options){
queue.push({params:params,options:options});
isPause = false ;
run();
return _this;
},
delay: function (ms){
queue.push({delay:ms});
return _this;
},
pause: function (){
isPause = true ;
return _this;
},
resume: function (){
if (_current){
var o = _current;
isPause = false ;
var st = ( new Date()).getTime() - _current.t;
_move(o.params,o.options.easing,st,o.options.duration,o.options.callback);
return _this;
}
},
stop: function (){
isPause = true ;
isBusy = false ;
queue = [];
props = {};
return _this;
}
};
return _this;
}
参考地址:
http://www.cnblogs.com/idche/archive/2010/06/17/1759605.html