js实现封装一个缓动动画,应用于各种动画效果
先封装一个缓动动画的效果,先快后慢的效果,这样的话可以应用到一些用到缓动动画的案例,如手风琴,轮播图等等。下一节讲解利用这个封装好的动画制作手风琴效果。
封装好的代码:
/**
*
* 元素动画效果
* @param {element} ele,一个元素
* @param {number} target ,移动的目标
* @param {string} style,要实现的效果属性(css)
* @param {function} fn,回调函数,动画执行结束时才调用的代码
*/
function animate(ele, target, style, fn) {
// clearInterval(timeId); // 先定义后使用,不能先使用后定义
// 提前清理数据:清理当前元素可能存在的定时器
clearInterval(ele.timeId); // 第一次:ele.timeId == undefined
// if (ele.timeId) return;
// 换一种思路:能否将定时器保存到元素中?元素是一个对象:对象可以增加属性,属性不希望用户看到:非标准属性,只在内存有效
ele.timeId = setInterval(function () {
// console.log(ele, ele.timeId);
// 获取当前的位置
let current = parseInt(getComputedStyle(ele)[style]);
// 计算步长:到底是什么运动
// 正向运动:目标比当前的位置要大:向上取整
// 负向运动:目标比当前的位置要小:向下取整
let step = (target - current) * 0.1;
// 判定是正向还是负向移动
if (target - current >= 0) {
step = Math.ceil(step);
} else {
step = Math.floor(step);
}
// console.log(step);
// 移动
ele.style[style] = current + step + 'px';
// 结束判定
if (step == 0) {
clearInterval(ele.timeId);
// delete ele.timeId;
// 动画结束:调用回调函数
// console.log(fn);
if (typeof fn === 'function') {
fn();
}
}
}, 10);
}
缓动动画效果的使用 animate(ele, target, style, fn)
- @param {element} ele,一个元素
- @param {number} target ,移动的目标
- @param {string} style,要实现的效果属性(css)
- @param {function} fn,回调函数,动画执行结束时才调用的代码
主要思路:运动的距离用剩余距离的百分比算,即如果left从0变成1000,那么每次移动百分之十的话那么第一次移动为100,剩余900,则第二次则移动900的百分之十即90以此类推达到移动的距离逐渐变小
难点:动画执行前和执行完后怎么清除该元素的动画,所以定时器句柄得跟传入的改元素挂钩,即将定时器保存到元素中,元素也是一个对象:对象可以增加属性。
如下例子:效果
例子代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
//该js文件为刚才封装好的缓动动画代码
<script src="js/animate.js"></script>
<style>
.box {
position: absolute;
top: 0;
left: 0;
width: 200px;
height: 200px;
background-color: tomato;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
const box = document.querySelector('.box')
document.querySelector('.box').onclick = function () {
// console.log(1);
animate(box, 400, 'left', function () {
animate(box, 400, 'top', function () {
animate(box, 0, 'left', function () {
animate(box, 0, 'top')
})
})
})
}
</script>
</body>
</html>