JS 缓动动画原理

简介: JS 缓动动画原理

所谓的缓动动画就是在动画的基础上,使元素的速度缓慢增加或缓慢减小的过程(减速或加速),那它使得盒子速度缓慢减小的原理是什么呢??很简单,可以理解为定时器每次进行一次,都执行:当前的距离+变化的步长,首先我们需要一个公式:


这个公式就是每次当前距离要加 的 不断变化的步长,我们称其为步长公式:(目标值-当前位置)/ 10  (这个10可以改)


步长公式的理解:

第一次增加的步长:


假设目标值为到 800px 时停止




第二次增加的步长:




第三次增加的步长:



后面的几步同理以此类推,达到了步长递减的效果,从而达到减速的效果,当距离左边的距离等于目标距离时清除定时器停止即可。


一:代码案例:

让盒子不断减速到目标位置800px处,如图所示:






JS实现:

<script>

       document.addEventListener('DOMContentLoaded',function(){

           var box=document.querySelector('div');

           var btn=document.querySelector('button');

           function run(obj,long){

               clearInterval(obj.timer)

               obj.timer=setInterval(function(){

                   if(obj.offsetLeft==long){  //左边距离与目标距离一样时就停止(清除定时器)

                       window.clearInterval(obj.timer);

                   }else{

                       step=(long-box.offsetLeft)/10  //步长公式

                       obj.style.left=obj.offsetLeft+step+'px';

                   }

               },20)

           }

           btn.addEventListener('click',function(){

                run(box,800)

           })

       })

   </script>




但是这样还是存在一个弊端,就是我们目标是停在800px处,但我们可以看到却停在了795.5px,这是因为我们求步长时存在除不尽取小数的问题,这时要解决这个问题我们就要采取:向上转型(Math.ceil)即可


改进代码:

<script>

       document.addEventListener('DOMContentLoaded',function(){

           var box=document.querySelector('div');

           var btn=document.querySelector('button');

           function run(obj,long){

               clearInterval(obj.timer)

               obj.timer=setInterval(function(){

                   if(obj.offsetLeft==long){

                       window.clearInterval(obj.timer);

                   }else{

                       step=Math.ceil((long-box.offsetLeft)/10)

                       obj.style.left=obj.offsetLeft+step+'px';

                   }

               },20)

           }

           btn.addEventListener('click',function(){

                run(box,800)

           })

       })

   </script>




这样就可以得到和目标值一样的移动距离啦 !


案例补充说明:

其次,我们这个案例用了步长公式就可以完成向后退的效果了,原理是得到了负的 step 值,这样当前距离 + 步长其实是一个减法,就可以往回退了,这里同样还是要注意小数转型的问题,刚才正步长相加是向上转型,现在减负步长我们要使用向下转型。这里我们可以增加一个三元运算符判断步长正负来选择使用向上还是向下转型: step=step>0?Math.ceil(step):Math.floor(step)


<body>

   <script>

       document.addEventListener('DOMContentLoaded',function(){

           var box=document.querySelector('div');

           var btn800=document.querySelector('.go800');

           var btn500=document.querySelector('.go500');

           function run(obj,long){

               clearInterval(obj.timer)

               obj.timer=setInterval(function(){

                   if(obj.offsetLeft==long){

                       window.clearInterval(obj.timer);

                   }else{

                       step=(long-box.offsetLeft)/10

                       step=step>0?Math.ceil(step):Math.floor(step)  //判断步长正负来选择使用哪个转型

                       obj.style.left=obj.offsetLeft+step+'px';

                   }

               },20)

           }

           btn500.addEventListener('click',function(){

               run(box,500)

           })

           btn800.addEventListener('click',function(){

                run(box,800)

           })

       })

   </script>

    <div></div>

    <button class="go800">到800</button>

    <button class="go500">到500</button>

</body>


以上问题就可以得到完美解决!!


二:下一个问题是给缓动动画添加回调函数,简单的目标效果是当定时器停止,即盒子到达目标位置后,让盒子变色或其他效果,这时就需要我们添加回调函数啦

我们要在调用 动画函数 的参数里添加一个 变色回调函数 作为实参(以第一个动画函数调用为例)


//第一个动画函数的调用

btn500.addEventListener('click',function(){

               run(box,500,function(){

                   box.style.backgroundColor='red';

               })

           })

然后动画函数的形参需要有一个值来接收,我们命名该形参为 callback,接收后当函数调用时相当于执行了一步:callback=function(){},然后因为我们目标是在停下之后变色,所以这个函数的调用应该放在定时器结束判断条件之后


if(callback){     //如果有回调函数实参传入,就执行回调函数,没有就不执行

      callback();

}

完整代码为:

<body>

   <script>

       document.addEventListener('DOMContentLoaded',function(){

           var box=document.querySelector('div');

           var btn800=document.querySelector('.go800');

           var btn500=document.querySelector('.go500');

           var btn0=document.querySelector('.go0')

           function run(obj,long,callback){

               clearInterval(obj.timer)

               obj.timer=setInterval(function(){

                   if(obj.offsetLeft==long){

                       window.clearInterval(obj.timer);

                       if(callback){

                       callback();

                   }

                   }else{

                       step=(long-box.offsetLeft)/10

                       step=step>0?Math.ceil(step):Math.floor(step)

                       obj.style.left=obj.offsetLeft+step+'px';

                   }

               },20)

           }

           btn500.addEventListener('click',function(){

               run(box,500,function(){

                   box.style.backgroundColor='red';

               })

           })

           btn800.addEventListener('click',function(){

                run(box,800)

           })

           btn0.addEventListener('click',function(){

               run(box,0)

           })

       })

   </script>

    <div></div>

    <button class="go800">到800</button>

    <button class="go500">到500</button>

    <button class="go0">到原位</button>

</body>


相关文章
|
3月前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包:原理与实战
【10月更文挑战第12天】深入理解JavaScript中的闭包:原理与实战
|
9天前
|
前端开发 API 开发者
Next.js 实战 (五):添加路由 Transition 过渡效果和 Loading 动画
这篇文章介绍了Framer Motion,一个为React设计的动画库,提供了声明式API处理动画和页面转换,适合创建响应式用户界面。文章包括首屏加载动画、路由加载Loading、路由进场和退场动画等主题,并提供了使用Framer Motion和next.js实现这些动画的示例代码。最后,文章总结了这些效果,并邀请读者探讨更好的实现方案。
|
2月前
|
JavaScript 前端开发
如何使用时间切片来优化JavaScript动画的性能?
如何使用时间切片来优化JavaScript动画的性能?
|
2月前
|
缓存 前端开发 JavaScript
JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式
本文深入解析了JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式(Hash路由和History路由)、优点及挑战,并通过实际案例分析,帮助开发者更好地理解和应用这一关键技术,提升用户体验。
89 1
|
2月前
|
JavaScript 前端开发
如何在不影响性能的前提下使用JavaScript库来实现复杂的动画效果?
如何在不影响性能的前提下使用JavaScript库来实现复杂的动画效果?
|
2月前
|
监控 JavaScript 算法
深度剖析 Vue.js 响应式原理:从数据劫持到视图更新的全流程详解
本文深入解析Vue.js的响应式机制,从数据劫持到视图更新的全过程,详细讲解了其实现原理和运作流程。
|
2月前
|
JavaScript 前端开发
CSS3 动画和 JavaScript 动画的性能比较
具体的性能表现还会受到许多因素的影响,如动画的复杂程度、浏览器的性能、设备的硬件条件等。在实际应用中,需要根据具体情况选择合适的动画技术。
|
2月前
ractive.js联系表单动画效果源码
一款ractive.js联系表单动画效果,很有创意的发送邮件、联系内容等表单,基于ractive.js实现的动画效果,以发送信件的方式。
27 1
|
2月前
|
JavaScript
js动画循环播放特效源码(上班族的一天)
js动画循环播放特效是一段实现了包含形象的卡通小人吃、睡、电脑工作的网页动画,js循环动画,简单的画面设计。非常丝滑有意思,欢迎对此代码感兴趣的朋友前来下载参考。
34 2
|
2月前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
71 0
下一篇
开通oss服务