JS动画框架一

动画原理

什么是动画?让一个东西动起来呗,先从最简单的水平移动开始


水平匀速移动

如下所示:

让图中DIV水平移动到一个地方,就是给它一双脚,这双脚每次走1.5px。目的地是走800px
于是有了如下JS代码:

1
2
<input type="button" value="运动到800米">
<div></div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
var inp = document.getElementsByTagName('input')[0];
var div = document.getElementsByTagName('div')[0];
inp.onclick=function () {
//瞬间到800
var leader = 0;
var timer = setInterval(function () {
leader+=1.5;
div.style.left = leader+"px";
if(leader>=800){
//一定要到800
// div.style.left = 800+"px";
clearInterval(timer);


}
},10)
}
</script>

这就是动画最开始的起源啦~~

封装简单的动画框架

根据上面的原理,封装一个简单的水平移动的“小框架”:

参数obj为运动对象,target为目标位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
      function animate(obj,target) {
clearInterval(obj.timer);
//匀速动画原理:物体当前位置 = 物体原来的位置+步长(leader = obj.offsetLeft+speed)
obj.timer = setInterval(function () {
//一次走10px
//到target就停下来
//我是希望不管obj原来在哪里都能到达target
// if(obj.offsetLeft>target){
// var speed = -10;
// }else{
// var speed = 10;
// }
var speed = (obj.offsetLeft>target?-10:10);
if(Math.abs(obj.offsetLeft-target)<10){
//就是物体原来位置距离目标不到一步,直接一步到target
obj.style.left = target+"px";
clearInterval(obj.timer);
}else{
obj.style.left = obj.offsetLeft+speed+"px";
}
},30)
}

让步伐不再匀速

上面是每一步走的都是同样的距离,如果每次的步长慢慢减小,就是缓动的动画了。

如下结构:

1
2
3
4
<body>
<input type="button" value="400" />
<div></div>
</body>

根据思路,JS函数核心:盒子位置= 盒子本身的位置+(目标位置-盒子本身的位置)/10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script>
var btn = document.getElementsByTagName('input')[0];
var div = document.getElementsByTagName('div')[0];
btn.onclick = function(){
//盒子位置= 盒子本身的位置+(目标位置-盒子本身的位置)/10
//div.style.left = div.offsetLeft+(400-div.offsetLeft)/10+"px"
setInterval(function(){
console.log(div.offsetLeft);//396
div.style.left = div.offsetLeft+(400-div.offsetLeft)/10+"px";
console.log(div.style.left);//396.4
//分析原因:
//盒子本身的位置 目标位置 步长 已经到达了的位置
//0 400 0 0
//0 400 40 40
//40 400 36 76
//76 400 32.4 108.4
//396 400 0.4 396.4
//396(会四舍五入) 400 0.4 396.4(取具体值)
//396 400 1 397
//397 400 1
//js实际运算的时候会四舍五入取整,然后计算。
},100)
}
</script>

不过此处会一直达不到目标,JS会四舍五入。所以最后实现代码如下:

每一次都要判断speed是正数还是负数,如果是正数就向上取整,如果是负数就向下取整;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
btn.onclick = function(){
//盒子位置= 盒子本身的位置+(目标位置-盒子本身的位置)/10
//div.style.left = div.offsetLeft+(400-div.offsetLeft)/10+"px"
btn.timer = setInterval(function(){
//每一次都要判断speed是正数还是负数,如果是正数就向上取整,如果是负数就向下取整;
var speed = (400-div.offsetLeft)/10;
speed = speed>0?Math.ceil(speed):Math.floor(speed);
div.style.left = div.offsetLeft+speed+"px";
if(div.offsetLeft==400){
clearInterval(btn.timer);
}
console.log(div.style.left);
},30)
}

最终:

封装水平缓动框架如下

1
2
3
4
5
6
7
8
9
10
11
12
13
//animation:让指定的dom元素缓动到指定位置
function animation(obj,target){
clearInterval(obj.timer);
obj.timer = setInterval(function(){
var speed = (target - obj.offsetLeft)/10;
speed = speed>0?Math.ceil(speed):Math.floor(speed);
obj.style.left = obj.offsetLeft + speed +"px";
if(obj.offsetLeft==target){
clearInterval(obj.timer);
}

},30)
}
文章目录
  1. 1. 动画原理
    1. 1.1. 水平匀速移动
    2. 1.2. 封装简单的动画框架
    3. 1.3. 让步伐不再匀速
    4. 1.4. 最终:
|