如何实现一个盒子匀速运动?
css的linear可以实现。
在js中,给定位的盒子left = 盒子当前.offsetleft + 1 + 'px'。
怎么实现的呢?靠的就是这个1像素的定值。
那么如何实现减速呢?
把1变成变量即可。
步长step = ( target - 当前offsetleft ) / x
这个x可以自己定,x越大的话跑的越慢,很容易理解。
那如何实现在多个目标值之间来回移动呢?
在做这个效果之前我们必须知道,步长一定要取整,不然的话盒子无法精确的跑到我们的target值上面。
而取整又涉及到了向上和向下取整 math.ceil 和 math.floor
如果向右跑,很显然步长是正数,这个时候要向上取整才能往右跑,因此是ceil
如果向左跑,很显然步长是负数,这个时候要向下取整才能向左跑,因此是floor
所以用到了三元表达式
step = step > 0 ? Math.ceil(step) : Math.floor(step);
最后一个需要注意的就是
终止条件
if (obj.offsetLeft >= target) {
clearInterval(obj.timer);
} 对吗?
我最开始也没看出来,因为我最开始没有取整,没有取整的话如果是==,很显然盒子不会停下来,因为涉及到小数不可能完全相等,事实也是如此,所以我用的是>=
但是由于我们取整了,最后肯定是可以等于target值的(?应该吧,我心里也不是很有底,但确实是这样)
因此再用>=就不合适了,比如你先跑到800px,还能跑到500px吗?
肯定不行,因为判断条件根本就过不去,直接清除定时器了。所以要把判断条件改成==
代码部分:
<body>
<button class="btn500">按钮500</button>
<button class="btn800">按钮800</button>
<div></div>
<script>
var btn500 = document.querySelector('.btn500');
var btn800 = document.querySelector('.btn800');
var div = document.querySelector('div');
//实现缓动动画的原理,让每一次盒子移动的步长慢慢变短,这样就是越走越慢
// 注意 步长一定要写到定时器里面,每一次都要变,否则不起作用!!!
function animate(obj, target) { // 传递两个参数,obj是动画对象,target是目标距离
//先清除之前的定时器,只保留当前的定时器,目的是在连续点击时 不让他加速运动
clearInterval(obj.timer);
obj.timer = setInterval(function() {
var step = (target - obj.offsetLeft) / 20;
// 这一步 是为了实现往后倒退时,ceil达到的不是前进的效果,而是后退,所以要通过判断,小于0时用floor
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
} else {
obj.style.left = obj.offsetLeft + step + 'px';
}
}, 15)
}
btn500.addEventListener('click', function() {
animate(div, 500);
});
btn800.addEventListener('click', function() {
animate(div, 800);
});
</script>
</body>