《js动画效果》之缓冲动画

来源:互联网 发布:bt下载软件苹果 编辑:程序博客网 时间:2024/05/21 08:47


js

学习资源来自慕课网《js动画效果》:http://www.imooc.com/learn/167

这里的缓冲动画指的是非匀速运动的动画,这里以速度动画原型为基础修改代码:

[html] view plaincopyprint?
  1. <!DOCTYPE HTML>  
  2. <html>  
  3.     <head>  
  4.         <meta charset="utf-8">  
  5.         <style type="text/css">  
  6.         *{  
  7.             padding:0;  
  8.             margin:0;  
  9.         }  
  10.         #box{  
  11.             width:200px;  
  12.             height:200px;  
  13.             background:red;  
  14.             position:relative;  /*物体初始必须要有此参数,否则不能实现物体的移动*/  
  15.             left:-200px;  
  16.             top:0;  
  17.         }  
  18.         #box span{  
  19.             width:20px;  
  20.             height:45px;  
  21.             background:green;  
  22.             position:absolute;  
  23.             left:200px;  
  24.             top:75px;  
  25.             color:#fff;  
  26.             text-align:center;  
  27.             padding-top:10px;  
  28.             cursor:pointer;  
  29.         }  
  30.         </style>  
  31.         <script type="text/javascript">  
  32.         window.onload = function(){  
  33.             var divEle = document.getElementById("box");  
  34.             divEle.onmouseover = function(){  
  35.                 playBox3(0);  //更精简的函数  
  36.             };  
  37.             divEle.onmouseout = function(){  
  38.                 playBox3(-200); //更精简的函数  
  39.             }  
  40.   
  41.         }  
  42.   
  43.         //定义定时器初始化为null  
  44.         var timer = null;  
  45.   
  46.   
  47.         //简化参数个数的函数  
  48.         function playBox3(target){  
  49.             //先清除之前的定时器,避免开多个定时器造成bug  
  50.             clearInterval(timer);  
  51.             var divEle = document.getElementById("box");  
  52.             var speed = 0;  
  53.   
  54.             //简化传参个数,为移动速度赋值  
  55.             /*if(divEle.offsetLeft > target){  
  56.                 speed = -10;  
  57.             }else{  
  58.                 speed = 10;  
  59.             }*/  
  60.   
  61.             timer = setInterval(function(){  
  62.   
  63.                 //非匀速运动的速度计算  
  64.                 var speed = (target - divEle.offsetLeft)/10;  
  65.   
  66.                 //速度为正时Math.ceil向上取整,速度为负值Math.floor向下取整  
  67.                 //这里必须分情况取整,不然物体运动停止时达不到目标值target  
  68.                 speed = speed > 0?Math.ceil(speed):Math.floor(speed);  
  69.                   
  70.                 if(divEle.offsetLeft == target){ //面板全部移出/移入时,清空定时器,停止运动  
  71.                     clearInterval(timer);  
  72.                 }else{  
  73.                     divEle.style.left = divEle.offsetLeft + speed +"px";  
  74.                 }  
  75.                 console.log(divEle.offsetLeft);  
  76.             },50); //每个50ms物体匀速运动 speed + "px"  
  77.         }  
  78.   
  79.         </script>  
  80.     </head>  
  81.     <body>  
  82.         <div id="box"><span id="share">分享</span></div>  
  83.     </body>  
  84. </html>  

分析:

缓冲动画实现的关键点是speed的计算,且注意对于正负值得处理,速度为正时Math.ceil向上取整,速度为负值Math.floor向下取整。

为什么正时Math.ceil向上取整,速度为负值Math.floor向下取整,当时学习的时候我也想不通,于是把Math.ceil(speed)和Math.floor(speed)拿来进行单独的测试,发现其中的原因。

Math.ceil(speed)来测试,改动代码(部分)如下:

[html] view plaincopyprint?
  1. timer = setInterval(function(){  
  2.   
  3.                 //非匀速运动的速度计算  
  4.                 var speed = (target - divEle.offsetLeft)/10;  
  5.   
  6.                 //速度为正时Math.ceil向上取整,速度为负值Math.floor向下取整  
  7.                 //这里必须分情况取整,不然物体运动停止时达不到目标值target  
  8.                 speed = Math.ceil(speed);  
  9.                   
  10.                 if(divEle.offsetLeft == target){ //面板全部移出/移入时,清空定时器,停止运动  
  11.                     clearInterval(timer);  
  12.                 }else{  
  13.                     divEle.style.left = divEle.offsetLeft + speed +"px";  
  14.                 }  
  15.                 console.log(divEle.offsetLeft);  
  16.             },50); //每个50ms物体匀速运动 speed + "px"  

测试结果如下图-1,图-2


图-1



图-2


由图-1可以看出鼠标划入划出,动画停止时,滑动面板并没有完整显示或隐藏,特别是鼠标滑出时,面板停止运动,但是却漏了一点出来,这是bug呀。为什么会出现这样的bug?原因是,面板停止运动时的left值只达到 -4.5px 、-196.4px,而不是0、-200px。我们来分析一下console.log(divEle.offsetLeft)输出的最后的值,即动画停止运动时divEle.offsetLeft的值,以鼠标划入做分析——鼠标划入时,要求面板以动画完整显示整个面板,即面板的 left 的最终值为 0 ,现在面板停止,divEle.offsetLeft为 -5 ,由代码中speed 的计算公式  var speed = (target - divEle.offsetLeft)/10; 可知 ,此时speed 的值为 0.5 ,然后用speed =Math.ceil(speed) 取整 得speed 的值为 0,计算出divEle.style.left = divEle.offsetLeft + speed +"px"; 所以left 的值一直是 -4.5,而定时器一直在运行,所以面板停止运动,实际是left的值每次计算出来都是同一个值,而不是定时器停止运行了:

timer = setInterval(function(){


//非匀速运动的速度计算
var speed = (target - divEle.offsetLeft)/10;

speed = Math.ceil(speed);

if(divEle.offsetLeft == target){ //面板全部移出/移入时,清空定时器,停止运动
clearInterval(timer);
}else{
divEle.style.left = divEle.offsetLeft + speed +"px";
}
console.log(divEle.offsetLeft);
},50); //每个


要解决上面的bug,必须在speed值为负时,采用Math.floor(speed)向上取整,而不是用Math.floor(speed)向下取整造成未达到终点前速度为0了;同理,只使用Math.foor(speed)也会出现此bug,所以需使用 speed = speed > 0?Math.ceil(speed):Math.floor(speed); 做判断取整。

0 0
原创粉丝点击