zoukankan      html  css  js  c++  java
  • JavaScript 运动框架(介绍及原理)

    1,运动原理

    Js运动,本质来说,就是让 web 上 DOM 元素动起来。而想要 DOM 动起来,改变其自身的位置属性,比如高宽,左边距,上边距,透明度等。动画的原理就是把不同状态的物体,串成连续的样子,就像一本书,画了几个小人,然后一翻书,就看见小人在动。js动画也一样。不同状态的DOM,用定时器控制,就能得到动画效果。

    1.  1 window.onload = function(){  
       2     var oBtn = document.getElementById('btn');  
       3     oBtn.onclick = function(){  
       4         var oDiv = document.getElementById('div1');  
       5         //设置定时器  
       6         setInterval(function(){  
       7             //改变物体位置  
       8             oDiv.style.left = oDiv.offsetLeft + 10 + 'px';  
       9         },30)  
      10                                                                                                                                                                                                                                                                       
      11     }  
      12 }  


    上述代码,点击btn之后,就能是物体向左运动。可是会一直向右动,不会停止。因此需要创立一个停止的条件。在条件符合的情况下,清楚定时器。其中对于目标点的判断,尤为重要。

    1.  1 window.onload = function(){  
       2     var oBtn = document.getElementById('btn');  
       3     oBtn.onclick = function(){  
       4         var oDiv = document.getElementById('div1');  
       5         //设置定时器  
       6         var timer = setInterval(function(){  
       7             //判断停止条件  
       8             if(oDiv.offsetLeft > 300){  
       9                 clearInterval(timer);  
      10             }else{  
      11                 //改变物体位置  
      12                 oDiv.style.left = oDiv.offsetLeft + 10 + 'px';  
      13                 document.title = oDiv.offsetLeft;  
      14             }  
      15         },30);  
      16                                                                                                                                                                                                                                                            
      17     }  
      18 }  


    上述代码中,但物体的位置大于300的时候,将停止运动。但是上述代码还有个问题,就是连续点击按钮,物体会运动越来越快。因为每点击一次,就开了一个定时器,累加的定时器。造成运动混乱。

    2,运动框架 (滑入滑出,淡入淡出)

    为了解决上述问题,则必须在开启定时器之前,先清除定时器,因此需要一个全局变量 timer保存定时器。如下面代码。

    1.  1 window.onload = function(){  
       2     var oBtn = document.getElementById('btn');  
       3     oBtn.onclick = function(){  
       4         startMove();  
       5     }  
       6 }  
       7 var timer = null;  
       8 function startMove(){  
       9     var oDiv = document.getElementById('div1');  
      10     clearInterval(timer);  
      11     //设置定时器  
      12     timer = setInterval(function(){  
      13         //判断停止条件  
      14         if(oDiv.offsetLeft > 300){  
      15             clearInterval(timer);  
      16         }else{  
      17             //改变物体位置  
      18             oDiv.style.left = oDiv.offsetLeft + 10 + 'px';  
      19             document.title = oDiv.offsetLeft;  
      20         }  
      21     },30);  
      22 }  
    
    

    此外,在改变物体位置的时候,那个 “10”则是更改的数量,其实也就是速度。如果更改速度,运动的快慢就能确定。因此,运动框架的原理,基本步骤为。

    • 先清除定时器

    • 开启定时器,计算速度

    • 判断停止条件,执行运动

    1.  1 var timer = null;  
       2 function startMove(){  
       3     var oDiv = document.getElementById('div1');  
       4     clearInterval(timer);  
       5         //计算速度  
       6     var iSpeed = 10;  
       7     //设置定时器  
       8     timer = setInterval(function(){  
       9         //判断停止条件  
      10         if(oDiv.offsetLeft > 300){  
      11             clearInterval(timer);  
      12         }else{  
      13             //改变物体位置  
      14             oDiv.style.left = oDiv.offsetLeft + iSpeed + 'px';  
      15             document.title = oDiv.offsetLeft;  
      16         }  
      17     },30);  
      18 }  
    
    

    对于停止条件,写死在里面了,所以需分离出参数。下面是一个分享到的例子。主要是根据目标判断速度的正负。从而在鼠标滑入画出时候进行运动/恢复的效果。

    1.  1 window.onload = function(){  
       2     var oDiv = document.getElementById('div1');  
       3     oDiv.onmouseover = function(){  
       4         startMove(0);  
       5     }  
       6     oDiv.onmouseout = function(){  
       7         startMove(-100);  
       8     }  
       9 }  
      10 var timer = null;  
      11 var iSpeed;  
      12 function startMove(iTatget){  
      13     var oDiv = document.getElementById('div1');  
      14     clearInterval(timer);  
      15     timer = setInterval(function(){  
      16         //计算速度  
      17         if(iTatget -oDiv.offsetLeft > 0){  
      18             iSpeed = 10;  
      19         }else{  
      20             iSpeed = -10;  
      21         }  
      22                                                                                                                                                                                                                                
      23         if(oDiv.offsetLeft == iTatget){  
      24             clearInterval(timer);  
      25         }else{  
      26             oDiv.style.left = oDiv.offsetLeft + iSpeed + 'px';  
      27         }  
      28         document.title = oDiv.offsetLeft;  
      29     },30)  
      30 }  


    另外一个小例子,淡入淡出,即改变物体的透明度,由于没有像原生的位置属性那样的offsetLset. 需要一个变量来保存透明度的值,用来和速度加减,最后付给元素的透明度样式。从而实现淡入淡出效果。

    1.  1 window.onload = function(){  
       2     var oImg = document.getElementById('img1');  
       3     oImg.onmouseover = function(){  
       4         startMove(100);  
       5     }  
       6     oImg.onmouseout = function(){  
       7         startMove(30);  
       8     }  
       9 }  
      10 var timer = null;  
      11 //保存透明度的数字值  
      12 var alpha = 30;  
      13 function startMove(iTarget){  
      14     var oDiv = document.getElementById('img1');  
      15     clearInterval(timer);  
      16     timer = setInterval(function(){  
      17         var iSpeed = 0;  
      18         if(alpha > iTarget){  
      19             iSpeed = -1;  
      20         }else{  
      21             iSpeed = 1;  
      22         }  
      23         if(alpha == iTarget){  
      24             clearInterval(timer);  
      25         }else{  
      26                         //改变透明度速度值  
      27             alpha += iSpeed;  
      28             oDiv.style.filter = 'alpha(opacity:'+ alpha+')';  
      29             oDiv.style.opacity = alpha/100;  
      30             document.title = alpha;  
      31         }  
      32                                                                                                                                                                                                          
      33     },30)  
      34 }  


    3,缓冲运动

    缓冲运动原理就是,改变速度的值。每次累加的速度值变小,就是会是整个物体看起来越来越慢,以至于最后停掉。相当于改变使物体具有一个加速度。这个加速度,可以由物体当前位置和目标位置之间的距离得到,因为两者之间的距离一直在变小,所以速度也一直在变小。如下:

    1.  1 window.onload = function(){  
       2     var btn = document.getElementsByTagName('input')[0];  
       3     btn.onclick = function(){  
       4         startMove(300);  
       5     }  
       6 }  
       7 var timer = null;  
       8 function startMove(iTarget){  
       9     var oDiv = document.getElementById('div1');  
      10     clearInterval(timer);  
      11     timer = setInterval(function(){  
      12         //求出带有变化的速度   
      13         var iSpeed = (iTarget - oDiv.offsetLeft) / 8;  
      14         if(oDiv.offsetLeft == iTarget){  
      15             clearInterval(timer);  
      16         }else{  
      17             oDiv.style.left = oDiv.offsetLeft + iSpeed + 'px';  
      18         }  
      19         document.title = oDiv.offsetLeft + '...' + iSpeed;  
      20     },30);  
      21 }  

    上述方法可以得到缓冲运动,但是实际运行效果,物体并没有在 300的位置停掉,而是在 293的位置就停掉了。究其原因。因为当物体的速度小于1 的时候。物体位置为293。此时计算的速度是 0.875.通过 oDiv.style.left = oDiv.offsetLeft + iSpeed + 'px'; 物体的位置为 293.875.可是计算机不能识别小数,将小数省略了。此时的 位置offsetLeft仍然是 293.再计算一次,还是同样的结果。定时器没有关掉,但是物体的位置却再也无法改变,故停留在了 293的位置。解决方案,就是将速度进行向上取整。但是,像上述运动,速度是正的,可是,当速度是负的时候,就同样会有相同的结果,因此需要在速度为负的时候,向下取整。

    1.  1 function startMove(iTarget){  
       2     var oDiv = document.getElementById('div1');  
       3     clearInterval(timer);  
       4     timer = setInterval(function(){  
       5         var iSpeed = (iTarget - oDiv.offsetLeft) / 8;  
       6         //对正的速度向上取整,负的速度向下取整  
       7         iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);  
       8         if(oDiv.offsetLeft == iTarget){  
       9             clearInterval(timer);  
      10         }else{  
      11             oDiv.style.left = oDiv.offsetLeft + iSpeed + 'px';  
      12         }  
      13         document.title = oDiv.offsetLeft + '...' + iSpeed;  
      14     },30);  
      15 }  


    4.多物体运动

    下一步,就是处理多物体运动,运动函数里面每次都要选取一个元素加事件。如果需要对多个物体进行同样的运动, 需要将运动对象作为参数传进来。

    1.  1 window.onload = function(){  
       2     var aDiv = document.getElementsByTagName('div');  
       3     for(var i=0;i<aDiv.length;i++){  
       4         aDiv[i].onmouseover = function(){  
       5             startMove(this,300);  
       6         }  
       7         aDiv[i].onmouseout = function(){  
       8             startMove(this,100);  
       9         }  
      10     }  
      11 }  
      12 var timer = null;  
      13 function startMove(obj,iTarget){  
      14     clearInterval(timer);  
      15     timer = setInterval(function(){  
      16         var iSpeed = (iTarget - obj.offsetWidth) / 8;  
      17         iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);  
      18         if(obj.offsetWidth == iTarget){  
      19             clearInterval(timer);  
      20         }else{  
      21             obj.style.width = obj.offsetWidth + iSpeed + 'px';  
      22         }  
      23                                                                                                                                                          
      24     },30)  
      25 }  


    通过循环物体,将物体的 this传给运动函数,使得多物体可以运动。但是这样有一个弊端,即当滑入第一个运动的时候,开启了定时器。如果此时,滑入另外一个物体,将会清理上一个定时器。这就造成了,上一次运动,很有可能还没完成结束,定时器就没关闭了。解决的方法,每个运动的物体,都能开了一个属于自己的定时器。因此,把定时器当成物体的属性。清理的时候也就是清理自己的定时器。

    1. window.onload = function(){  
          var aDiv = document.getElementsByTagName('div');  
          for(var i=0;i<aDiv.length;i++){  
              aDiv[i].onmouseover = function(){  
                  startMove(this,300);  
              }  
              aDiv[i].onmouseout = function(){  
                  startMove(this,100);  
              }  
          }  
      }  
      function startMove(obj,iTarget){  
          //将定时器,变成物体的属性,类似给物体添加索引  
          clearInterval(obj.timer);  
          obj.timer = setInterval(function(){  
              var iSpeed = (iTarget - obj.offsetWidth) / 8;  
              iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);  
              if(obj.offsetWidth == iTarget){  
                  clearInterval(obj.timer);  
              }else{  
                  obj.style.width = obj.offsetWidth + iSpeed + 'px';  
              }  
                                                                                                                                                   
          },30)  
      }  
    
    

    多物体的淡入淡出的时候,也有类似的问题。因为修改透明度的时候,是先用一个变量保存透明度,必须针对每个物体设立透明度值属性。

    1.  1 window.onload = function(){  
       2     var aDiv = document.getElementsByTagName('div');  
       3     for(var i=0;i<aDiv.length;i++){  
       4         //将透明度值当初属性  
       5         aDiv[i].alpha = 30;  
       6         aDiv[i].onmouseover = function(){  
       7             startMove(this,100);  
       8         }  
       9         aDiv[i].onmouseout = function(){  
      10             startMove(this,30);  
      11         }  
      12     }  
      13 }  
      14 function startMove(obj,iTarget){      
      15     clearInterval(obj.timer);  
      16     obj.timer = setInterval(function(){  
      17         var iSpeed = (iTarget - obj.alpha) / 8;  
      18         iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);  
      19         if(obj.alpha == iTarget){  
      20             clearInterval(obj.timer);  
      21         }else{  
      22             obj.alpha += iSpeed;  
      23             obj.style.filter = 'alpha(opacity:'+obj.alpha+')';  
      24             obj.style.opacity = obj.alpha / 100;  
      25         }  
      26         document.title = obj.alpha;  
      27     },30);  
      28 }  


    4.1  位置属性的bug

    offsetWidth 或者 offsetHeight 等位置属性,一旦给他们加上 border。则会有诡异的现象出现。

    1. window.onload = function(){  
              var oDiv = document.getElementById('div1');  
              setInterval(function(){  
                  oDiv.style.width = oDiv.offsetWidth - 1 + "px";  
              },30)  
          }  
    
    

    例如 oDiv.style.width = oDiv.offsetWidth - 1 + 'px'; 如果给 oDiv 的width 为一百,border 为 1.则这个物体的 width是100px;offsetWidth 为102px;带入公式之后,即减一之后。100 = 102 - 1 ,反而等于101;即 物体本来要减小,事实却增大了。解决的方案就是,加减的时候,必须使用物体的内联样式。但是 火狐 和 IE 又有兼容模式。解决方案如下:

    1.  1 window.onload = function(){  
       2         var oDiv = document.getElementById('div1');  
       3         setInterval(function(){  
       4                                                                                                                    
       5             oDiv.style.width = parseInt(getStyle(oDiv,'width')) - 1 + 'px';  
       6                                                                                                         
       7         },30)  
       8     }  
       9     function getStyle(obj,attr){  
      10         if(obj.currentStyle){  
      11             return obj.currentStyle[attr];  
      12         }else{  
      13             return getComputedStyle(obj,false)[attr];  
      14         }  
      15     }  


    其中,getStyle函数,传入一个元素对象,和其 css 属性,获取的是元素的样式,即 witdh 100px;因此需要parseInt转换

    5.任意值运动

    通过 getStyle 函数,可以获取元素的样式,还可也通过 attr 制定需要修改的 css属性。这样就能是物体有不同的运动形式。

    1.  1 window.onload = function(){  
       2     var aDiv = document.getElementsByTagName('div');  
       3     aDiv[0].onmouseover = function(){  
       4         startMove(this,'width',300);  
       5     }  
       6     aDiv[0].onmouseout = function(){  
       7         startMove(this,'width',100);  
       8     }  
       9     aDiv[1].onmouseover = function(){  
      10         startMove(this,'height',100);  
      11     }  
      12     aDiv[1].onmouseout = function(){  
      13         startMove(this,'height',50);  
      14     }  
      15 }  
      16 function getStyle(obj,attr){  
      17     if(obj.currentStyle){  
      18         return obj.currentStyle(attr);  
      19     }else{  
      20         return getComputedStyle(obj,false)[attr];  
      21     }  
      22 }  
      23 function startMove(obj,attr,iTarget){  
      24     clearInterval(obj.timer);  
      25     obj.timer = setInterval(function(){  
      26         var iCur = parseInt(getStyle(obj,attr));  
      27         var iSpeed = (iTarget - iCur) / 8;  
      28         iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);  
      29         if(iCur == iTarget){  
      30             clearInterval(obj.timer);  
      31         }else{  
      32             obj.style[attr] = iCur + iSpeed + 'px';  
      33         }  
      34                                                                                                     
      35     },30)  
      36 }  
    
    

    5.1 任意值完美版

    上述版本,还不能处理透明度的任意值,因此需要增加额外的兼容hack。

    1.  1 window.onload = function(){  
       2         var aDiv = document.getElementsByTagName('div');  
       3         aDiv[0].onmouseover = function(){  
       4             startMove(this,'opacity',100);  
       5         }  
       6         aDiv[0].onmouseout = function(){  
       7             startMove(this,'opacity',30);  
       8         }  
       9     }  
      10     function getStyle(obj,attr){  
      11         if(obj.currentStyle){  
      12             return obj.currentStyleattr[attr];  
      13         }else{  
      14             return getComputedStyle(obj, false)[attr];  
      15         }  
      16     }  
      17     function getStyle(obj, attr){  
      18         if(obj.currentStyle)    {  
      19             return obj.currentStyle[attr];  
      20         }else{  
      21             return getComputedStyle(obj, false)[attr];  
      22         }  
      23     }  
      24     function startMove(obj,attr,iTarget){  
      25         clearInterval(obj.timer);  
      26         obj.timer = setInterval(function(){  
      27             var iCur = 0;  
      28             if(attr == 'opacity'){  
      29                 iCur = parseInt(parseFloat(getStyle(obj, attr))*100);  
      30             }else{  
      31                 iCur = parseInt(getStyle(obj,attr));  
      32             }  
      33             var iSpeed = (iTarget - iCur) / 8;  
      34             iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);  
      35             if(iCur == iTarget){  
      36                 clearInterval(obj.timer);  
      37             }else{  
      38                 if(attr=='opacity'){  
      39                     iCur += iSpeed  
      40                     obj.style.filter='alpha(opacity:' + iCur + ')';  
      41                     obj.style.opacity=iCur / 100;  
      42                 }  
      43                 else{  
      44                     obj.style[attr]=iCur+iSpeed+'px';  
      45                 }  
      46                 document.title = obj.style[attr];  
      47             }  
      48                                                                                       
      49         },30)  
      50     }  


    6.链式运动

    我们的运动框架到目前为止,基本功能都能实现了。现在拓展。所谓链式运动,即运动接着运动。当运动停止的时候,如果回调一个函数。回调一个运动函数,就能出现这样的效果。因此传入一个函数作为回调函数。

    1.  1 window.onload = function(){  
       2     var oDiv = document.getElementById('div1');  
       3     oDiv.onclick = function(){  
       4         startMove(this,'width',300,function(){  
       5             startMove(oDiv,'height',300,function(){  
       6                 startMove(oDiv,'opacity',100)  
       7             })  
       8         })  
       9     }  
      10 }  
      11 function getStyle(obj,attr){  
      12     if(obj.currentStyle){  
      13         return obj.currentStyleattr[attr];  
      14     }else{  
      15         return getComputedStyle(obj, false)[attr];  
      16     }  
      17 }  
      18                                                                       
      19 function startMove(obj,attr,iTarget,fn){  
      20     clearInterval(obj.timer);  
      21     obj.timer = setInterval(function(){  
      22         var iCur = 0;  
      23         if(attr == 'opacity'){  
      24             iCur = parseInt(parseFloat(getStyle(obj, attr))*100);  
      25         }else{  
      26             iCur = parseInt(getStyle(obj,attr));  
      27         }  
      28         var iSpeed = (iTarget - iCur) / 8;  
      29         iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);  
      30         if(iCur == iTarget){  
      31             clearInterval(obj.timer);  
      32             //回调函数  
      33             if(fn) fn();  
      34         }else{  
      35             if(attr=='opacity'){  
      36                 iCur += iSpeed  
      37                 obj.style.filter='alpha(opacity:' + iCur + ')';  
      38                 obj.style.opacity=iCur / 100;  
      39             }  
      40             else{  
      41                 obj.style[attr]=iCur+iSpeed+'px';  
      42             }  
      43             document.title = obj.style[attr];  
      44         }  
      45                                                                         
      46     },30)  
      47 }  


    7.同时运动

    目前为止,我们的运动框架还有个小缺点,就是不能同时该两个属性进行运动,比如同时更改宽和高。这个要求传入的属性是不同的几个值。则考虑传入一个 json用来保存需要更改的属性。

    1.  1 window.onload = function(){  
       2     var oDiv = document.getElementById('div1');  
       3     oDiv.onclick = function(){  
       4         startMove(this,{'width':300,'height':400});  
       5     }  
       6 }  
       7 function getStyle(obj, attr){  
       8     if(obj.currentStyle)    {  
       9         return obj.currentStyle[attr];  
      10     }else{  
      11         return getComputedStyle(obj, false)[attr];  
      12     }  
      13 }  
      14 function startMove(obj,json,fn){  
      15     clearInterval(obj.timer);  
      16     obj.timer = setInterval(function(){  
      17      // 循环json   
      18      for(var attr in json){        
      19             var iCur = 0;  
      20             if(attr == 'opacity'){  
      21                 iCur = parseInt(parseFloat(getStyle(obj, attr))*100);  
      22             }else{  
      23                 iCur = parseInt(getStyle(obj,attr));  
      24             }  
      25             var iSpeed = (json[attr] - iCur) / 8;  
      26             iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);  
      27             if(iCur == json[attr]){  
      28                 clearInterval(obj.timer);  
      29                 if(fn) fn();  
      30             }else{  
      31                 if(attr=='opacity'){  
      32                     iCur += iSpeed  
      33                     obj.style.filter='alpha(opacity:' + iCur + ')';  
      34                     obj.style.opacity=iCur / 100;  
      35                 }  
      36                 else{  
      37                     obj.style[attr]=iCur+iSpeed+'px';  
      38                 }  
      39                 document.title = obj.style[attr];  
      40             }  
      41         }  
      42     },30)  
    
    

    上述代码,可以解决了同时运动的问题。但是还是有一个bug。比如,同时运动的某个属性,如果变化很小,马上就停止了,即关掉了定时器。那么会造成其他属性的变化也停止。因为这些属性都共用了一个定时器。因此需要判断,假设有三个人要来,然后一起去爬山。三个人有的先来,有的后来,只要三个人都到齐了,才出发。也就是只有三个属性都到了目标值,才关定时器。一开始,设立一个检查量,为真。假设所有人都到了,然后循环,只有有一个人没有到,检查就为假。直到所有的都到了,检测为真。则停止定时器。

    1.  1 window.onload = function(){  
       2     var oDiv = document.getElementById('div1');  
       3     oDiv.onclick = function(){  
       4         startMove(this,{'width':102,'height':400,'opacity':100});  
       5     }  
       6 }  
       7 function getStyle(obj, attr){  
       8     if(obj.currentStyle)    {  
       9         return obj.currentStyle[attr];  
      10     }else{  
      11         return getComputedStyle(obj, false)[attr];  
      12     }  
      13 }  
      14 function startMove(obj,json,fn){  
      15     clearInterval(obj.timer);  
      16     obj.timer = setInterval(function(){  
      17         var bStop = true;  
      18         for(var attr in json){    
      19             //取当前值    
      20             var iCur = 0;  
      21             if(attr == 'opacity'){  
      22                 iCur = parseInt(parseFloat(getStyle(obj, attr))*100);  
      23             }else{  
      24                 iCur = parseInt(getStyle(obj,attr));  
      25             }  
      26             //计算速度  
      27             var iSpeed = (json[attr] - iCur) / 8;  
      28             iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);  
      29             //检测停止  
      30             if(iCur != json[attr]){  
      31                 bStop = false;  
      32             }     
      33             if(attr=='opacity'){  
      34                 iCur += iSpeed  
      35                 obj.style.filter='alpha(opacity:' + iCur + ')';  
      36                 obj.style.opacity=iCur / 100;  
      37             }  
      38             else{  
      39                 obj.style[attr]=iCur+iSpeed+'px';  
      40             }  
      41         }  
      42         if(bStop){  
      43             clearInterval(obj.timer);  
      44             if(fn) fn();  
      45         }  
      46     },30)  
      47 }  
    
    

    再循环外定义一个 标志变量 bStop = true。用来表示所有属性到达目标值。等循环结束了,如果这个值是真的,则停止定时器。因为,每次运行定时器,都会初始化这个值。循环的过程中,只要有一个没有到,bStop就被设定为 false。如果某个到了,此时 iCur != json[attr],表示速度为0 后面执行的结果,也不会有变化。只有所有的都达到目标值。循环则不再改变 bStop的值。此时,只要下一次运行定时器。就是初始化 bStop为真。而循环因为都到了,所以速度为0 也就再也没有变化。循环结束,sBstop还是真,表示所有都到了。因此此时结束定时器。

    最后附上完美运动框架,封装成 move.js 就可以调用了。

     1   /** 
     2   * @author rsj217 
     3    * getStyle 获取样式 
     4    * startMove 运动主程序 
     5 */  
     6                    
     7   function getStyle(obj, attr){  
     8       if(obj.currentStyle)    {  
     9           return obj.currentStyle[attr]; //for ie 
    10      }else{  
    11          return getComputedStyle(obj, false)[attr];  // for ff
    12      }  
    13  }  
    14  function Move(obj,json,fn){  
    15      //停止上一次定时器  
    16      clearInterval(obj.timer); //关闭前一个定时器,解决对同个对象同时调用多个Move()时,定时器叠加问题。使用obj.timer给每个调用Move()的对象赋予各自的定时器,防止多个对象同时调用Move()时,同用一个定时器,而导致相关干扰问题。 
    17      //保存每一个物体运动的定时器  
    18      obj.timer = setInterval(function(){  
    19          //判断同时运动标志  
    20          var bStop = true;  
    21          for(var attr in json){    
    22              //取当前值    
    23              var iCur = 0;  //创建一个变量,用于存储 attr属性每时每刻的值
    24              if(attr == 'opacity'){  
    25               //针对在FF中opacity属性值为浮点数值问题,将属性值 四舍五入、转换成浮点型。乘以100,使opacity属性值与IE统一为百分数
    26                  iCur = Math.round(parseFloat(getStyle(obj, attr))*100);  
    27              }else{  
    28                  iCur = parseInt(getStyle(obj,attr)); //将除opacity外的属性(width/fontSize/MarginLeft等)的初始值 转换为整型 
    29              }  
    30              //计算速度  
    31              var iSpeed = (json[attr] - iCur) / 8;  //创建 递减的速度speed变量。实现属性值的变速改变
    32              iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);  //取整,解决浏览器忽略小于1px的数值 导致运动结束时,离目标值Itarget少几个像素的问题
    33              //检测同时到达标志  
    34              if(iCur != json[attr]){  
    35                  bStop = false;  
    36              }     
    37              //更改属性,获取动画效果  
    38              if(attr=='opacity'){  
    39                  iCur += iSpeed  
    40                  obj.style.filter='alpha(opacity:' + iCur + ')';  
    41                  obj.style.opacity=iCur / 100;  
    42              }  
    43              else{  
    44                  obj.style[attr]=iCur+iSpeed+'px';  
    45              }  
    46          }  
    47          //检测停止  
    48          if(bStop){  
    49              clearInterval(obj.timer);  
    50              if(fn) fn();  
    51          }  
    52      },30)  
    53   }  
    1.  

  • 相关阅读:
    关于将so 打包入APK的问题
    求 在独立service 中 调用contentprovider的方法
    ndk 环境下 c版 md5
    请教大牛们一个问题
    编写 service 与导出 jar 时注意的问题
    引入已编译好的动态库
    PHP 日期格式说明
    Ocaml 插件
    【转】简单至极的 PHP 缓存类
    PHP mysqlnd cannot connect to MySQL 4.1+ using old authentication
  • 原文地址:https://www.cnblogs.com/hl-520/p/4241515.html
Copyright © 2011-2022 走看看