- 实例1:左右按钮点击运动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>左右按钮点击运动</title>
<style>
*{
margin: 0;
padding: 0;
}
button{
margin: 5px;
width: 100px;
height: 30px;
line-height: 30px;
cursor: pointer;
}
#but{
width:230px;
height: 50px;
margin: 0 auto;
}
#div1{
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
font-size: 30px;
color: blue;
border-radius: 50%;
background-color: red;
position: absolute;
left: 500px;
top: 100px;
}
.div2{
width: 10px;
height: 500px;
position: absolute;
top: 50px;
background-color: blue;
}
#div2{
left: 240px;
}
#div3{
left: 1250px;
}
</style>
</head>
<body>
<div id="but"><button>向左</button><button>向右</button></div>
<div id="div1">太阳</div>
<div class="div2" id="div2"></div>
<div class="div2" id="div3"></div>
<script>
var oDiv=document.getElementById("div1");
var aBtn=document.getElementsByTagName("button");
aBtn[0].onclick=function () {
moveBat(250);
};
aBtn[1].onclick=function () {
moveBat(1150);
};
function moveBat(target) {
_moveBat();//执行一次;
function _moveBat(){//添加函数,利于优化
var cur=oDiv.offsetLeft;
if(cur>target){
if(cur-5<=target){//提前加减步长进行比较,如果满足条件就设置目标值;
oDiv.style.left=target+"px";
return;
}
cur-=5;
}else{
if(cur+5>=target){
oDiv.style.left=target+"px";
return;
}
cur+=5;
}
oDiv.style.left=cur+"px";
clearTimeout(oDiv.timer);//执行前先关闭定时器;
oDiv.timer=setTimeout(_moveBat,30);//将timer设置在元素的自定义属性上,避免全局变量;
}
/* oDiv.timer=setTimeout(function () {//设置匿名函数后,会重复新建私有作用域,不能释放,不利于优化
moveBat(target);
},30);*/
}
//1 边界值的判断,预判是否到达边界值;
//2 定时器的timer,设置在元素的自定义属性上,避免全局变量
//3 两个点击事件执行一个定时器时会出问题,所以需要在执行定时器之前,关闭定时器;
//4 定时器中新建匿名函数的优化问题;
</script>
</body>
</html>
- 运动库linear函数封装
- 目的:获取运动元素的实时位置
- 参数:
- b:begin 运动起始位置
- c:change 还要走多远
- d:duration 走完剩下的路程需要的总时间
- t:time 代表走了多少时间
- 变量:time值为可变值,不断地累加,然后计算出实时位置;配合定时器使用;
- 返回值:返回实时位置值;
<script>
function linear(c,d,t,b) {
return c/d*t+b;
}
</script>
<script>
function linear(c,d,t,b) {
return c/d*t+b;
}
var oDiv1=document.getElementById("div1");//运动元素
var oDiv2=document.getElementById("div2");//目标位置元素
//目标值target需要确定
var target=oDiv2.offsetLeft-oDiv1.offsetWidth-oDiv2.offsetWidth;//减去运动元素的宽度和自身的宽度;
var b=oDiv1.offsetLeft;
var c=target-b;
var d=1000;
var t=0;
oDiv1.timer=setInterval(function () {
t+=10;//time为变量,不断累加;
//边界点判断
if(t>d){
oDiv1.style.left=target+"px";
clearInterval(oDiv1.timer);
}
var curLeft=linear(c,d,t,b);
oDiv1.style.left=curLeft+"px";
},10)
</script>
- 实例:一个物体的多运动
- 目的:实现一个物体在x,y两个方向上的同时匀速运动;
- 思路:
- 分别求出物体运动在x,y方向上的起始位置,目标位置,算出各自方向上的总路程;
- 设定总时间duration;
- 起始时间为0,即time初始赋值为0;
- 设置定时器:1)进行time变量的累加,最好跟定时器的执行时间相同;2)边界点判断(设置目标位置、停止定时器、阻断程序执行);3)利用linear方法获取x,y方向上的实时位置;4)设置实时位置;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>一个物体的多运动</title>
<style>
*{
margin: 0;
padding: 0;
}
#div1{
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
font-size: 30px;
color: blue;
border-radius: 50%;
background-color: red;
position: absolute;
left: 300px;
top: 30px;
}
.div2{
width: 10px;
height: 500px;
position: absolute;
top: 30px;
left: 1050px;
background-color: blue;
}
</style>
</head>
<body>
<div id="div1">物体</div>
<div class="div2" id="div2"></div>
<script src="utils.js"></script>
<script>
function linear(c,d,t,b) {
return c/d*t+b;
}
var oDiv1=document.getElementById("div1");
var oDiv2=document.getElementById("div2");
var targetLeft=oDiv2.offsetLeft-oDiv1.offsetWidth,targetTop=oDiv2.offsetHeight+oDiv2.offsetTop-oDiv1.offsetHeight;
var beginLeft=oDiv1.offsetLeft,beginTop=oDiv1.offsetTop;
var changLeft=targetLeft-beginLeft,changTop=targetTop-beginTop;
var duration=1000;
var time=0;
var timer=setInterval(function () {
//1 变量累加
time+=10;
//2 边界点判断
if(time>=duration){
//设置目标值
utils.css(oDiv1,{
left:targetLeft,
top:targetTop
});
//停止定时器
clearInterval(timer);
//阻断程序执行
return ;
}
//3 获取当前位置
var curLeft=linear(changLeft,duration,time,beginLeft);
var curTop=linear(changTop,duration,time,beginTop);
//4 设置当前位置
utils.css(oDiv1,{
left:curLeft,
top:curTop
});
},10);
</script>
</body>
</html>
- 实例:封装方法,实现物体的多运动库
- 参数: ele:元素,target:目标值,对象,duration:运动总时间
- 注意点:
- 工具库的引用,需要按照引用顺序调用;
- 在工具库中利用自执行函数封装的方法,需要设置window,将其设置成全局变量,这样才能在全局引用;
- 工具库代码:
(function () {
var gbEffect={
Linear:function(c,d,t,b){
return c/d*t+b;
}
};
function move(ele,target,duration){
//ele:元素,target:目标值,对象,duration:时间
duration=duration || 2000;
var begin={},change={};
for(var attr in target){
begin[attr]=utils.css(ele,attr);
change[attr]=target[attr]-begin[attr];
}
var time=0;
//定时器
var timer=setInterval(function () {
//变量累加
time+=10;
//边界点判断
if(time>=duration){
//设置边界值
console.log(1)
utils.css(ele,target);
//停止定时器
clearInterval(timer);
//阻断程序执行
return ;
}
//获取实时位置
for(var attr in change){
var linear=gbEffect.Linear(change[attr],duration,time,begin[attr]);
//设置实时位置
utils.css(ele,attr,linear);
}
},10)
}
//自执行函数中与外界无联系,利用window设置为全局
window.animate=move;
})();
<body>
<div id="div1">物体</div>
<div id="div2"></div>
<script src="utils.js"></script>
<script src="move.js"></script>
<script>
var oDiv1=document.getElementById("div1");
var oDiv2=document.getElementById("div2");
animate(oDiv1,{
left:oDiv2.offsetLeft-oDiv1.offsetWidth,
top:oDiv2.offsetTop+oDiv2.offsetHeight-oDiv1.offsetHeight,
opacity:0.8
},2000)
</script>
</body>