一个简单的js动画

 

前段时间为了做动画,学习了一下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;
  }

 

 功能实现:

/* 简单动画方法
 * 未实现单位换算
 
*/
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

posted on 2010-07-19 21:25  zhangle  阅读(727)  评论(1编辑  收藏  举报