动画函数封装
核心原理:通过定时器 setInterval()不断移动盒子
实现步骤:
- 获得盒子的当前位置
- 让盒子在当前位置加上一个移动距离
- 利用定时器不断重复这个操作
- 加一个结束定时的条件
- 注意此元素需要添加定位,才可以使用element.style.left
<style> div { position: absolute; width: 100px; height: 100px; background-color: aquamarine; } </style> </head> <body> <div></div> <script> var div = document.querySelector("div"); var timer = setInterval(function () { if (div.offsetLeft >= 400) { //停止动画 即停止定时器 clearInterval(timer); } div.style.left = div.offsetLeft + 1 + "px"; }, 30); </script> </body>
动画函数的封装
//动画函数的封装 obj 目标对象 target 目标位置 function animate(obj, target) { var timer = setInterval(function () { if (obj.offsetLeft >= target) { //停止动画 即停止定时器 clearInterval(timer); } obj.style.left = obj.offsetLeft + 1 + "px"; }, 30); }
调用:
//调用函数 var div = document.querySelector("div"); animate(div, 300);
动画函数给不同元素记录不同定时器
核心原理:JS是一门动态语言,可以很方便地给当前对象添加属性
//给不同元素记录不同定时器 function animate(obj, target) { obj.timer = setInterval(function () { if (obj.offsetLeft >= target) { //停止动画 即停止定时器 clearInterval(obj.timer); } obj.style.left = obj.offsetLeft + 1 + "px"; }, 30); } var div = document.querySelector("div"); animate(div, 300);
但如果设置了点击事件动画才开始时,如果不断点击按钮,对应元素的速度会越来越快,因为开启了太多的定时器。
解决方法:
让元素只有一个定时器即可,先清除以前的定时器,只保留当前的一个定时器执行//给不同元素记录不同定时器 function animate(obj, target) { //先清除以前的定时器,只保留当前的一个定时器执行 clearInterval(obj.timer); obj.timer = setInterval(function () { ........ }
缓动效果原理
缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来
思路:让盒子每次移动的距离慢慢变小,速度就会慢慢落下来
核心算法:(目标值-现在的位置)/ 10 作为每次移动的距离步长
停止的条件是:让当前位置等于目标位置就停止定时器
匀速动画:盒子当前的位置 + 固定的值
缓动动画:盒子当前的位置 +(目标值-现在的位置)/ 10
<style> div { width: 200px; height: 200px; background: blueviolet; position: absolute; } </style> </head> <body> <button class="go">点击到500</button> <button class="back">点击到800</button> <div></div> <script> var btnGo = document.querySelector(".go"); var btnBack = document.querySelector(".back"); var div = document.querySelector("div"); btnGo.addEventListener("click", function () { animate(div, 500); }); btnBack.addEventListener("click", function () { animate(div, 800); }); function animate(obj, target) { clearInterval(obj.timer); obj.timer = setInterval(function () { //步长值写到定时器里面 //把步长值取成整数,往上取整Math.ceil() var step = (target - obj.offsetLeft) / 10; //考虑到可能会后退,会是负值, step > 0 ? Math.ceil(step) : Math.floor(step); if (obj.offsetLeft == target) { clearInterval(obj.timer); } //把每次加1 这个步长值改为一个慢慢变小的值 步长公式:(目标值-现在的位置)/ 10 obj.style.left = obj.offsetLeft + step + "px"; }, 15); } </script> </body>
动画函数添加回调函数
回调函数原理:函数可以作为一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就是回调。
回调函数的位置:定时器结束的位置。function animate(obj, target,callback) { //callback = function(){} 调用的时候 callback() .............. if (obj.offsetLeft == target) { clearInterval(obj.timer); //回调函数写到定时器结束里面 if (callback) { //调用函数 callback(); } } } btnGo.addEventListener("click", function () { animate(div, 500, function () { alert('你好吗'); //前面的动画都结束后才会调用这个函数 弹出 你好吗 }); }); //三个参数,最后一个参数是函数
动画函数封装到单独JS文件里面
因为以后会经常用到这个动画函数,可以单独封装到一个JS文件里面,使用的时候引用JS文件即可
JS文件如下:function animate(obj, target, callback) { //callback = function(){} 调用的时候 callback() clearInterval(obj.timer); obj.timer = setInterval(function () { //步长值写到定时器里面 //把步长值取成整数,往上取整Math.ceil() var step = (target - obj.offsetLeft) / 10; //考虑到可能会后退,会是负值, step > 0 ? Math.ceil(step) : Math.floor(step); if (obj.offsetLeft == target) { clearInterval(obj.timer); //回调函数写到定时器结束里面 if (callback) { //调用函数 callback(); } } //把每次加1 这个步长值改为一个慢慢变小的值 步长公式:(目标值-现在的位置)/ 10 obj.style.left = obj.offsetLeft + step + "px"; }, 15); }