动画原理
什么是动画?让一个东西动起来呗,先从最简单的水平移动开始
水平匀速移动
如下所示:
让图中DIV水平移动到一个地方,就是给它一双脚,这双脚每次走1.5px
。目的地是走800px
于是有了如下JS代码:
<input type="button" value="运动到800米">
<div></div>
<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
为目标位置
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)
}
让步伐不再匀速
上面是每一步走的都是同样的距离,如果每次的步长慢慢减小,就是缓动的动画了。
如下结构:
<body>
<input type="button" value="400" />
<div></div>
</body>
根据思路,JS函数核心:盒子位置= 盒子本身的位置+(目标位置-盒子本身的位置)/10
<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是正数还是负数,如果是正数就向上取整,如果是负数就向下取整;
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)
}
最终:
封装水平缓动框架如下
//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)
}