目录
一、动画实现原理
核心原理:通过定时器setInterval()不断移动盒子位置。
实现步骤:
1、获得盒子当前的位置。
2、让盒子在当前位置上加1个移动距离。
3、利用定时器不断重复这个操作。
4、加一个结束定时的条件。
注意:需要给元素添加定位
<style>
div {
/* 绝对定位 */
position: absolute;
left: 0;
height: 100px;
width: 100px;
background-color: pink;
}
</style>
<body>
<div></div>
<script>
// 获取元素
var div = document.querySelector('div');
// 3、利用定时器不断重复这个操作
var timer = setInterval(function () {
// 1、获得盒子当前的位置
// 2、让盒子在当前位置上加一个移动距离
div.style.left = div.offsetLeft + 1 + 'px';
// 4、加一个结束定时器的条件
if (div.offsetLeft >= 500) {
clearInterval(timer);
}
}, 10)
</script>
</body>
二、封装动画函数
<style>
.div1 {
/* 绝对定位 */
position: absolute;
top: 40px;
left: 0;
height: 100px;
width: 100px;
background-color: pink;
}
.div2 {
/* 绝对定位 */
position: absolute;
top: 150px;
left: 0;
height: 100px;
width: 100px;
background-color: red;
}
</style>
<body>
<div class="div1"></div>
<div class="div2">唐伯虎</div>
<button>点击唐伯虎移动</button>
<script>
// 封装动画函数
// 获取元素
var div1 = document.querySelector('.div1');
var div2 = document.querySelector('.div2')
// 调用函数
animate(div1, 500);
var btn = document.querySelector('button');
// 不断点击时可以发现,div移动的越来越快,这是因为开了多个定时器的原因。
// 解决方案:在开启定时器时,关闭上一个定时器
btn.onclick = function () {
animate(div2, 600)
}
function animate(obj, target) {
// 关闭上一个定时器
clearInterval(obj.timer);
/**
* obj:需要移动的元素
* target:移动距离
*/
// 3、利用定时器不断重复这个操作
// 如果过个元素都使用这个函数,会导致每次都要var声明。可以给不同的元素使用不同的定时器。
// 核心原理:利用JS是一门动态语言,可以很方便的给当前对象添加属性
// var timer = setInterval(function () {
obj.timer = setInterval(function () {
// 1、获得盒子当前的位置
// 2、让盒子在当前位置上加一个移动距离
obj.style.left = obj.offsetLeft + 1 + 'px';
// 4、加一个结束定时器的条件
if (obj.offsetLeft >= target) {
clearInterval(obj.timer);
}
}, 10)
}
</script>
</body>
三、缓动效果原理
缓动动画就是让元素运动速度有所变化,最常见的是让速度慢下来。
思路:
1、让盒子每次移动距离变小,速度就会慢慢落下来
2、核心算法:(目标值 - 现在的位置)/ 10 = 每次移动的步长
3、停止的条件:当前盒子位置等于目标位置
注意:步长值要取整
<style>
.div2 {
/* 绝对定位 */
position: absolute;
top: 150px;
left: 0;
height: 100px;
width: 100px;
background-color: red;
}
</style>
<body>
<div class="div2">唐伯虎</div>
<button class="btn1">点击唐伯虎移动</button>
<button class="btn2">点击倒退</button>
<script>
// 封装动画函数
// 获取元素
var div2 = document.querySelector('.div2')
var btn = document.querySelector('.btn1');
var btn2 = document.querySelector('.btn2')
btn.onclick = function () {
animate(div2, 600)
}
btn2.onclick = function () {
animate(div2, 0)
}
function animate(obj, target) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
// 可以发现:元素只会达到594.6,这是因为有小数的问题,解决办法,给step取整
var step = (target - obj.offsetLeft) / 10;
// floor 向下取整 ceil向上取整
// 如果是正值,往大了取整。如果是负值,往小了取整
step = step < 0 ? Math.floor(step) : Math.ceil(step);
obj.style.left = obj.offsetLeft + step + 'px';
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
}
}, 10)
}
</script>
</body>
四、添加回调函数
回调函数原理:函数可以作为一个参数。将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫回调。
回调函数写的位置:定时器结束时
<script>
// 封装动画函数
// 获取元素
var div2 = document.querySelector('.div2')
var btn = document.querySelector('.btn1');
var btn2 = document.querySelector('.btn2')
btn.onclick = function () {
// 传入回调函数
animate(div2, 600, function () {
div2.style.backgroundColor = 'green';
})
}
btn2.onclick = function () {
animate(div2, 0, function () {
div2.style.backgroundColor = 'red';
})
}
function animate(obj, target, callback) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
var step = (target - obj.offsetLeft) / 10;
step = step < 0 ? Math.floor(step) : Math.ceil(step);
obj.style.left = obj.offsetLeft + step + 'px';
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
// 判断是否传入了回调函数
// if (callback) {
// callback();
// }
callback && callback();
}
}, 10)
}
</script>