动画效果之运动

     今天开始学习《JS动画效果》,上午把整个课程了解了一遍,决定动手做做实践。一上手就发现看似简单的问题却总是报错,几经推敲才发现问题所在。

关于匀速运动:

      首先,做一个简单的“分享到”匀速运动,即当鼠标移到“块”上时,隐藏的块匀速被拉出,移走鼠标,块匀速隐藏。

     1.这里涉及到定时器的问题。在开启一个定时器之前一定要关掉定时器,以免出现鼠标不停划上去的时候不停的开启定时器;

     2.鼠标进入与离开事件可用一个函数表示,传入不同参数即可通用一个函数(注意尽量少的参数,所以可以精简);

     3.offset对于元素的宽高等属性而言是包含border宽度的,因此不能把运动函数简单写成:         

function(){
  obj.style.width=obj.offsetWidth+speed+"px";
  ...
}

     而应该利用函数(考虑浏览器兼容性)获得此类样式(行间样式可以直接用parseInt(obj.style.width)取得,但是不利于HTML/CSS/JavaScript分离,因此可忽略):

 function getStyle(obj,attr){
   if(obj.currentStyle){
     // 针对ie浏览器
     return obj.currentStyle[attr];            
 }else{
    //针对firefox浏览器
     return getComputedStyle(obj,false)[attr];
   }
}

     该函数可以取得各种样式,包括字体等。

      其次,做了一个透明度的匀速变化运动。 它与其他属性不同有以下几点要注意:

     1.浏览器兼容问题:ie下表示方式为“filter:alpha(opacity:30)”,firefox与chrome等高级浏览器表示方式为“opacity:0.3”。因此在做该属性相关事件时应该解决浏览器兼容问题。并且,表示范围也不一样,前者为1~100,后者为0~1。

     2.透明度不存在offset属性,因此可以给它一个初始值,作为运动参考点。

关于缓冲运动:

    无论是宽高变化,还是透明度变化,在物体做缓冲运动的时候一定要记得给速度取整。因为当speed=(iTarget-alpha)/20右边取值为浮点值时,永远到不了iTarget值,因此speed为负值时用Math.ceil向上取整,正值用Math.floor向下取整。

关于多物体运动:

    由于此时不再是单一物体的运动,因此在定时器开启前的关闭定时器要针对每个物体而关闭,透明度的多物体运动要注意给每个物体定义初始值。

关于任意属性值运动:

    由于有了getStyle()这个函数,因此可以直接使很多样式得到改变,但是透明度仍然有问题。

    1.初始值"iCur=parseInt(getStyle(obj.attr))"————在firefox与chrome中opacity为小数,取整后直接为0。因此可以针对透明度将初始值取值为“iCur=parseFloat(getStyle())*100”,注意前面提到的浏览器兼容性。

    2.对于计算机而言,parseFloat不能很严格精确的去到整数,因此需要用Math.round对其取整。

关于链式动画

     即一个运动接着一个运动,例如变宽后变高再变透明度。可以给运动框架上加一个函数fn(调用之前要清楚定时器):

function startMove(obj,attr,iTarget,fn){
   ...
}

    鼠标移出时,按倒序还原。

关于同时运动

    即物体同时做几种运动。此时,可能我们想当然的以为两个运动写一起就好了,可是不然,由于运动之前有抢出定时器的存在,因此永远只有最后一个运动可行。因此,我们需要想办法可以同时取多个属性,此时可以用到JSON。此时遍历JSON要用到for(var i in JSON),i代表里面的name,json.[i]表示key即属性值。此时我们可以把之前的运动框架改为:

function startMove(obj,json,fn){
    clearInterval(obj.timer);
   obj.timer=setInterval(function(){
   for(var attr in json){
  //运动框架
  ...
   }
   },30)
}

但此时要注意此框架下的运动不完全,因为它只要有一个属性值到达终点,它就会停止运动,因此还需要判定是否所有的目标值都达到了。在执行下一个运动之前先判定flag值是否为真(之前假设flag为真代表所有目标值都达到了),若不为真,则继续执行下一个属性值,如果为真,则执行下一个运动。

    到目前为止,我们应该算做好了一个完美的运动框架,动手试试吧!

原文地址:https://www.cnblogs.com/july-Vivian/p/4584090.html