第一步: 首先要获取你要改变的那个div。 var oBox=document.getElementById('box'); //div对象
第二步: (1). 定义一个move函数。怎么定义? 首先我们要操作什么?怎么操作?操作结束后的收尾工作? -----> oBox (div对象) -----> 我们希望他变成什么样子的?例如left改变,例如top改变。这个肯定是json的形式. {left:200, top:400} ----->收尾工作?那就是一个function. 可选. move(obj, json, options)
第三步: 在move函数中的步骤: (1). 因为第三个参数options是可选的,所以我们首先需要对这个参数进行确定,如果有就使用,如果没有,就进行默认参数设置。 options=options||{}; options.duration=options.options||700; options.easing=options.easing||'liner';
(2)设置初始值和距离
因为我们的物体的运动结束后有一个结束位置,这个位置是move第二个参数json指定的,既然有结束位置,那我们需要确定起始位置,变化的范围就是结束位置减去开始位置,在这里我们指代的就是距离
var start={}; //初始值 var dis={}; //变化的值 for(var name in json){ start[name]=parseFloat(getStyle(obj,name)); //获得初始值 dis[name]=json[name]-start[name]; //变化的值等于结束值减去初始值 };
(3). 我们希望多久走完全程。这个是在第三个参数中指定的options.duration。并且总共需要运动count次。
var count=Math.floor(options.duration/30);
定义一个变量,存放当前已经运动的次数:
var n=0;
(4). 开定时器,每30ms运动一次
obj.timer=setInterval(function(){
n++;
for(var name in json){
switch(options.easing){
case 'liner':
var a=n/count;
var cur=start[name]+dis[name]*a;
break;
case 'ease-in':
var a=n/count;
var cur=start[name]+dis[name]*Math.pow(a,3);
break;
case 'ease-out':
var a=1-n/count;
var cur=start[name]+dis[name]*(1-Math.pow(a,3));
break;
};
if(name=='opacity'){
obj.style.opacity=cur;
obj.style.filter = 'alpha(opacity:'+cur*100+')';
}else{
obj.style[name]=cur+'px';
}
};
if(n==count){
clearInterval(obj.timer)
options.complete&&options.complete();
}
},30);
(a).第一次运动:
(1). n=n+1,此时n就是1了。
(2). 判断物体的运动方式,匀速,加速等。在这里,我们分析匀速运动。
此时我们走的总的全程是:n/count--------> 1/count, 运动的比例。
我们的全程运动距离是dis[name], 例如说我们现在分析的是left的运动,就是匀速向左运动,改变的就是left的值,那么这里的全程距离就是dis[left]。例如等于200px.
那么我们的第一次运动的距离就是:dis[left] * (1/count) ===200*(1/count).
那么我们的物体第一次运动结束后的结束距离是等于初始值加上第一次运动的距离: cur = start[left] + 200*(1/count)
那么第一次运动结束后,物体的所在位置:obj.style[left]=cur+'px';
(b).第二次运动:
(1). n=n+1,此时n就是2了。
(2). 判断物体的运动方式,匀速,加速等。在这里,我们分析匀速运动。
此时我们走的总的全程是:n/count--------> 2/count, 运动的比例。
我们的全程运动距离是dis[name], 例如说我们现在分析的是left的运动,就是匀速向左运动,改变的就是left的值,那么这里的全程距离就是dis[left]。例如等于200px.
那么我们的第一次运动的距离就是:dis[left] * (2/count) ===200*(2/count).
那么我们的物体第一次运动结束后的结束距离是等于初始值加上第一次运动的距离: cur = start[left] + 200*(2/count)
那么第一次运动结束后,物体的所在位置:obj.style[left]=cur+'px';
........后面依次类推
(5)当n==count运动结束
(a)关闭定时器,此次运动结束
(b)判断options中是否有传入回调函数,如果有传入回调函数,则执行此回调函数
if(n==count){
clearInterval(obj.timer)
options.complete&&options.complete();
}
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
*{
margin:0;
padding: 0;
}
#box{
150px;
height: 150px;
background: red;
position: absolute;
left: 0;
top:0;
}
</style>
<script>
function getStyle(obj,name){
return (obj.currentStyle||getComputedStyle(obj,false))[name];
}
function move(obj,json,options){
//设置默认值
options=options||{};
options.duration=options.options||700;
options.easing=options.easing||'liner';
//总次数
var count=Math.floor(options.duration/30);
//设置初始值和距离
var start={};
var dis={};
for(var name in json){
start[name]=parseFloat(getStyle(obj,name));
dis[name]=json[name]-start[name];
};
//当前走的次数
var n=0;
obj.timer=setInterval(function(){
n++;
for(var name in json){
switch(options.easing){
case 'liner':
var a=n/count;
var cur=start[name]+dis[name]*a;
break;
case 'ease-in':
var a=n/count;
var cur=start[name]+dis[name]*Math.pow(a,3);
break;
case 'ease-out':
var a=1-n/count;
var cur=start[name]+dis[name]*(1-Math.pow(a,3));
break;
};
if(name=='opacity'){
obj.style.opacity=cur;
obj.style.filter = 'alpha(opacity:'+cur*100+')';
}else{
obj.style[name]=cur+'px';
}
};
if(n==count){
clearInterval(obj.timer)
options.complete&&options.complete();
}
},30);
}
window.onload=function(){
var oBox=document.getElementById('box');
move(oBox,{left:300,300},{
complete:function(){
move(oBox,{top:200})
}
})
};
</script>
</head>
<body>
<div id="box"></div>
</body>
</html>