<html>
<head>
<title>Animation</title>
<meta http-equiv="X-UA-Compatible" content="edge" />
<meta http-equiv="X-UA-Compatible" content="IE=10">
<meta http-equiv="X-UA-Compatible" content="IE=9">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="box1" style="position: absolute;top:100px;left:100px;width:100px;height:100px;background: #FF8D40"></div>
<div id="box2" style="position: absolute;top:100px;left:100px;width:100px;height:100px;background: #FF4400"></div>
<script>
/**
* 线性运动插件
* @type type
*/
var LinearInterpolate={
getPosRate:function(timeRate){
return timeRate>1?1:(timeRate<0?0:timeRate);
}
};
/**
* 先慢后快
* @type type
*/
var AccelerateDecelerateInterpolator={
/**
* 将路程分成100份 前50份 走了0.6 0.5/0.6 后期 0.5/0.4
* @param {type} elem
* @param {type} styleName
* @returns {getStyle.s}
*/
getPosRate:function(timeRate){
var v=0.5/0.6;
if(timeRate<0.6){
return timeRate*v;
}else{
v=0.5/0.4;
var endPos=0.5+(timeRate-0.6)*v;
return endPos>1?1:endPos;
}
}
};
/**
* 重力加速度公式
* @type type
*/
var AccelerateInterpolator={
getPosRate:function(timeRate){
timeRate=timeRate*1.417;
var endPos=0.5*timeRate*timeRate;
return endPos>1?1:endPos;
}
};
/**
* 先后退一下段 然后前进
* @type type
*/
var AnticipateInterpolator={
/**
* 开始速度-0.2 每次加0.1
* @param {type} elem
* @param {type} styleName
* @returns {getStyle.s}
*/
getPosRate:function(timeRate){
timeRate=timeRate*6.92;//(时间修正)
var endPos=timeRate*(-0.2+timeRate*0.1-0.2)*0.5;
return endPos>1?1:endPos;
}
};
/**
* css属性获取
* @returns {undefined}
*/
function getStyle(elem,styleName){
if(elem.style[styleName]){//内联样式
return elem.style[styleName];
}
else if(elem.currentStyle){//IE
return elem.currentStyle[styleName];
}
else if(document.defaultView && document.defaultView.getComputedStyle){//DOM
styleName = styleName.replace(/([A-Z])/g,'-$1').toLowerCase();
var s = document.defaultView.getComputedStyle(elem,'');
return s&&s.getPropertyValue(styleName);
}else{//other,for example, Safari
return null;
}
}
/**
* animation对象
* @param {type} div
* @returns {Animation}
*/
function Animation(div){
var self=this;
this.interpolate=AnticipateInterpolator;
this.list=[];
var runFunc=function(){
var now=new Date().getTime();
var timeRate=(now-self.startTime)/self.time;
var posRate=self.interpolate.getPosRate(timeRate);
for(var i in self.startPos){
div.style[i]=self.startPos[i]+self.offsetPos[i]*posRate+"px";
}
if(posRate===1){
if(self.haveNext()){
if(self.callback instanceof Function){
self.callback(timeRate);
}
setTimeout(runFunc,1);
return;
}
}else{
setTimeout(runFunc,1);
}
};
this.haveNext=function(){
if(this.list.length){
var animData=this.list.shift();
this.interpolate=animData.interpolate;
this.time=animData.time;
this.startTime=new Date().getTime();
this.offsetPos={};
this.startPos={};
for(var i in animData.opt){
var val=getStyle(div,i);
if(val&&animData.opt[i]){
this.startPos[i]=parseInt(val);
this.offsetPos[i]=parseInt(animData.opt[i])-parseInt(val);
}
}
return true;
}
return false;
};
this.addNext=function(opt,time,interpolate,callback){
if(!opt)return this;
this.list.push({opt:opt,time:time||1000,callback:callback,interpolate:interpolate||AnticipateInterpolator});
return this;
};
this.start=function(){
if(this.haveNext()){
setTimeout(runFunc,1);
}
};
}
var anim=new Animation(document.getElementById("box1"))
.addNext({left:300,top:400,width:50,height:50},1000,AccelerateInterpolator)
.addNext({left:600},1000,AnticipateInterpolator,function(timeRate){
alert(timeRate);
}).addNext({top:100,width:100,height:100},1000,AccelerateDecelerateInterpolator)
.addNext({left:100,width:10,height:10},1000,LinearInterpolate);
var anim2=new Animation(document.getElementById("box2"))
.addNext({left:300,width:50,height:50},500,AccelerateInterpolator)
.addNext({left:600},500,AnticipateInterpolator,function(timeRate){
alert(timeRate);
}).addNext({top:100,width:100,height:100},1500,AccelerateDecelerateInterpolator)
.addNext({left:100,width:10,height:10},1500,LinearInterpolate);
anim.start();
anim2.start();
</script>
</body>
</html>