> 文档中心 > 缓动动画原理

缓动动画原理

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

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


步长公式的理解:

第一次增加的步长:

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


 第二次增加的步长: 


 第三次增加的步长:

 


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


代码案例:

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




 JS实现:

  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)     }) })    

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


改进代码:

 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)     }) })    

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


案例补充说明:

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

     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)     }) })         

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