一、动画函数封装
1.1 动画实现原理
核心原理:通过定时器setInterval()不断移动盒子位置
实现步骤:
- 获取盒子当前位置
- 让盒子在当前位置上加1个移动距离
- 利用定时器不断重复这个操作
- 最后加个结束定时器的条件
- 注意:此元素需要添加定位,才能使用element.style.left
案例练习
div{
width: 100px;
height: 100px;
position: absolute;
left: 0;
background: skyblue;
border: 1px solid #ccc;
}
<div></div>
<script>
var div = document.querySelector('div');
var timer = setInterval(function(){
if(div.offsetLeft >= 200){
clearInterval(timer);
} else {
div.style.left = div.offsetLeft + 1 +'px';
}
},30);
</script>
1.2 动画函数简单封装
注意:函数需要传递2个参数,动画对象 和 移动到的距离
以1.1案例练习为例,封装动画函数
function animate(obj,target){
var timer = setInterval(function(){
if(obj.offsetLeft >= target){
clearInterval(timer);
} else {
obj.style.left = obj.offsetLeft + 1 +'px';
}
},30);
}
var div = document.querySelector('div');
animate(div,200);
1.3 动画函数给不同元素记录不同定时器
如果多个函数使用这个动画函数,每次都需要var声明定时器,因此可以给不同的元素使用不同的定时器
核心原理:利用JS是一门动态语言,可以很方便的给当前对象添加属性
function animate(obj,target){
clearInterval(obj.timer)
// 给不同元素指定了不同定时器
obj.timer = setInterval(function(){
if(obj.offsetLeft >= target){
clearInterval(obj.timer);
} else {
obj.style.left = obj.offsetLeft + 1 +'px';
}
},30);
}
1.4 缓动画原理
缓动画就是让元素运动速度有所变化,最常见的就是让速度慢慢停下来
思路:
- 让盒子每次移动距离逐渐变小,达到速度变慢的效果
- 核心算法:(目标值-现在的位置)/ n 作为每次移动的距离
- 停止条件:让盒子位置等于目标位置就停止定时器
1.5 案例练习 - 让动画函数可以在两个位置之间来回移动
注意:
- 步长值需为整数
- 步长值如果为正整数,则遇到小数点时往大取整
- 步长值如果为负整数,则遇到小数点时往小取整
div{
width: 100px;
height: 100px;
position: absolute;
left: 0;
background: skyblue;
border: 1px solid #ccc;
}
<button class="btn1">点击按钮到达500px</button> <button class="btn2">点击按钮到达800px</button> <div></div> <script> function animate(obj,target){ clearInterval(obj.timer) // 给不同元素指定了不同定时器 obj.timer = setInterval(function(){ // 步长值写道定时器里 // var step = Math.ceil((target - obj.offsetLeft) / 10); var step = (target - obj.offsetLeft) / 10; // 判断步长值的正负 step = step > 0 ? Math.ceil(step) :Math.floor(step); if(obj.offsetLeft == target){ clearInterval(obj.timer); } else { obj.style.left = obj.offsetLeft + step +'px'; } },30); } var div = document.querySelector('div'); var btn1 = document.querySelector('.btn1'); var btn2 = document.querySelector('.btn2');
btn1.addEventListener('click',function(){ animate(div,500) }); btn2.addEventListener('click',function(){ animate(div,800) });</code></pre>
1.6 动画函数添加回调函数
回调函数原理:函数可以作为一个参数。将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫做回调
回调函数写的位置:定时器结束的位置
以1.5案例为基础的案例练习
<button class="btn1">点击按钮到达500px</button> <button class="btn2">点击按钮到达800px</button> <div></div> <script> function animate(obj, target, callback){ clearInterval(obj.timer) // 给不同元素指定了不同定时器 obj.timer = setInterval(function(){ // 步长值写道定时器里 // var step = Math.ceil((target - obj.offsetLeft) / 10); var step = (target - obj.offsetLeft) / 10; // 判断步长值的正负 step = step > 0 ? Math.ceil(step) :Math.floor(step); if(obj.offsetLeft == target){ clearInterval(obj.timer); // 回调函数写道定时器结束里面 if(callback){ callback(); } } else { obj.style.left = obj.offsetLeft + step +'px'; } },30); } var div = document.querySelector('div'); var btn1 = document.querySelector('.btn1'); var btn2 = document.querySelector('.btn2');
btn1.addEventListener('click',function(){ animate(div,500,function(){ div.style.background = 'red'; }) }); btn2.addEventListener('click',function(){ animate(div,800) });</code></pre>
1.7 案例练习 - 侧边栏划出动画效果
<style> .sliderbar { position: fixed; right: 0; bottom: 100px; width: 40px; height: 40px; text-align: center; line-height: 40px; cursor: pointer; color: #fff; }
.con { position: absolute; left: 0; top: 0; width: 200px; height: 40px; background-color: skyblue; z-index: -1; } </style> <script src="animate.js"></script></code></pre>
<div class="sliderbar">
<span>←</span>
<div class="con">问题反馈</div>
</div>
<script>
var sliderbar = document.querySelector('.sliderbar');
var con = document.querySelector('.con');
sliderbar.addEventListener('mouseenter',function(){
animate(con, -160,function(){
sliderbar.children[0].innerHTML = '→';
});
});
sliderbar.addEventListener('mouseleave',function(){
animate(con, 0);
sliderbar.children[0].innerHTML = '←';
});
</script>
animate.js
function animate(obj, target, callback) {
clearInterval(obj.timer)
// 给不同元素指定了不同定时器
obj.timer = setInterval(function(){
// 步长值写道定时器里
// var step = Math.ceil((target - obj.offsetLeft) / 10);
var step = (target - obj.offsetLeft) / 10;
// 判断步长值的正负
step = step > 0 ? Math.ceil(step) :Math.floor(step);
if(obj.offsetLeft == target){
clearInterval(obj.timer);
// 回调函数写道定时器结束里面
if(callback){
callback();
}
} else {
obj.style.left = obj.offsetLeft + step +'px';
}
},15);
}