复习笔记之API(15) JS动画
2020-04-22 本文已影响0人
晚月川
[TOC]
JS中的动画
动画实现原理
- 核心原理:通过定时器
setInterval()
不断移动盒子的位置- 实现步骤:
- 获得当前盒子位置
- 让当前盒子位置加一个移动距离
- 利用定时器不断重复这个操作
- 加一个结束定时器的条件
- 注意此元素需要添加定位,才能使用
element.style.left
<style>
div {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 200px;
background-color: black;
}
</style>
<div></div>
<!-- IMPORT JS -->
<script>
let div = document.querySelector('div');
let timer = setInterval(function () {
if (div.offsetLeft == 400) {
// 停止动画 本质就是停止定时器
clearInterval(timer);
}
div.style.left = div.offsetLeft + 1 + 'px';
}, 30);
</script>
动画函数的封装
注意函数需要传递两个参数,动画对象和移动到的距离
// 简单动画函数封装 obj目标对象 target目标位置
function animate(obj, target) {
let timer = setInterval(function () {
if (obj.offsetLeft == target) {
// 停止动画 本质就是停止定时器
clearInterval(timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
}, 30);
}
动画函数给不同元素记录不同的定时器:如果多个元素都使用这个动画函数,我们可以给不同的元素使用不同的定时器(自己专用自己的定时器)
- 核心原理:利用JS是一门动态语言,可以很方便的给当前对象添加属性
<style>
div {
position: absolute;
width: 200px;
height: 200px;
background-color: black;
}
span {
position: absolute;
left: 0;
top: 300px;
display: block;
width: 100px;
height: 100px;
background-color: blue;
}
</style>
<div></div>
<span></span>
<script>
// 给不同元素设置了不同的定时器
function animate(obj, target) {
obj.timer = setInterval(function () {
if (obj.offsetLeft >= target) {
// 停止动画 本质就是停止定时器
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
}, 30);
}
animate(div, 300);
animate(span, 500);
</script>
优化一下:添加一个按钮,当点击按钮的时候,动画开始
- 这时会发现一个问题,当我们不断点击按钮的时候,这个元素运动会越来越快,因为开启了太多的定时器
- 解决方案:让元素只有一个定时器执行
<style>
div {
position: absolute;
width: 200px;
height: 200px;
background-color: black;
}
span {
position: absolute;
left: 0;
top: 300px;
display: block;
width: 100px;
height: 100px;
background-color: blue;
}
</style>
<button>点击开始赛跑</button>
<div></div>
<span></span>
<script>
let div = document.querySelector('div'),
span = document.querySelector('span'),
btn = document.querySelector('button');
function animate(obj, target) {
// 先清楚以前的定时器,只保留当前的一个定时器执行
clearInterval(obj.timer);
obj.timer = setInterval(function () {
if (obj.offsetLeft >= target) {
// 停止动画 本质就是停止定时器
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';}
}, 30);
btn.addEventListener('click', function () {
animate(div, 300);
animate(span, 500);
})
</script>
缓动效果
缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来
- 思路:
- 让每次移动距离慢慢变小,速度就会慢慢落下来
- 核心算法:
(目标值 - 现在位置) / 10
作为每次移动的距离步长- 停止的条件是:让当前盒子位置等于目标位置就停止定时器
<style>
div {
position: absolute;
width: 200px;
height: 200px;
background-color: black;
}
span {
position: absolute;
left: 0;
top: 300px;
display: block;
width: 100px;
height: 100px;
background-color: blue;
}
</style>
<button>点击开始赛跑</button>
<div></div>
<span></span>
<script>
let div = document.querySelector('div'),
span = document.querySelector('span'),
btn = document.querySelector('button');
function animate(obj, target) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
// 步长值写到定时器的里面
let step = (target - obj.offsetLeft) / 10;
if (obj.offsetLeft == target) {
// 停止动画 本质就是停止定时器
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 15);
}
btn.addEventListener('click', function () {
animate(div, 1000);
animate(span, 800);
})
</script>
- 匀速动画就是 盒子当前的位置 + 固定的值
- 缓动动画就是 盒子当前位置 + 变化的值 (
(目标值 - 现在位置) / 10
)
这个缓动动画并不完美,因为每次都不能准确的到达终点,因为前面的公式中有除法的存在,所以难以避免最后出现小数,为了解决这个问题,我们就需要吧步长值改为整数,所以可以利用数学函数中的
Math.ceil()
向上取整一下(如果考虑到动画还有后退的过程,就需要向下取整Math.floor()
)
<style>
div {
position: absolute;
width: 200px;
height: 200px;
background-color: black;
}
</style>
<button class="one">跑到500的位置</button>
<button class="two">跑到1000的位置</button>
<div></div>
<script>
let div = document.querySelector('div'),
btn = document.querySelector('.one'),
btn2 = document.querySelector('.two');
function animate(obj, target) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
// 步长值写到定时器的里面
let step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
// 停止动画 本质就是停止定时器
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 15);
}
btn.addEventListener('click', function () {
animate(div, 500);
})
btn2.addEventListener('click', function () {
animate(div, 1000);
})
</script>
动画函数多个目标值之间的移动,我们需要判断步长值正数还是负数
- 如果是正数,则步长往大了取整
- 如果是负的,则步长往小了取整