首頁 >web前端 >js教程 >Javascript 完美運動框架(逐行分析程式碼,讓你輕鬆了運動的原理)_javascript技巧

Javascript 完美運動框架(逐行分析程式碼,讓你輕鬆了運動的原理)_javascript技巧

WBOY
WBOY原創
2016-05-16 16:18:241200瀏覽

大家一聽這名字就知道,有了這套框架 網路上的效果基本上都是可以實現的。實際上之前的運動框架還是有限制的,就是不能讓好幾個值一塊運動。

那這個問題要怎麼解決呢? 我們先來看看之前的運動框架

function getStyle(obj, name) {
  if (obj.currentStyle) {
    return obj.currentStyle[name];
  } else {
    return getComputedStyle(obj, null)[name];
  }
}


function startMove(obj, attr, iTarget) {
  clearInterval(obj.time);
  obj.time = setInterval(function() {
    var cur = 0;

    if (attr == 'opacity') {
      cur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
    } else {
      cur = parseInt(getStyle(obj, attr));
    }

    var speed = (iTarget - cur) / 6;

    speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

    if (cur == iTarget) {
      clearInterval(obj.time);
    } else {
      if (attr == 'opacity') {
        obj.style.filter = 'alpha(opacity=' + cur + speed + ')';
        obj.style.opacity = (cur + speed) / 100;
      } else {
        obj.style[attr] = cur + speed + 'px';
      }
    }
  }, 30);
}

怎麼修改呢? 實際上很簡單, 在過去的框架中,你每次只能傳一個樣式,和一個值。那麼現在把這些改成一個json物件。相信大家就明白了。

我們呼叫的時候就是startMove(oDiv,{width:200,height:200}); 如果需要的話就在加上回呼函數。那我們就具體看看程式碼是怎麼修改的。

function startMove(obj, json, fnEnd)
{
  var MAX=18;
  //每次调用就只有一个定时器在工作(开始运动时关闭已有定时器)
  //并且关闭或者开启都是当前物体的定时器,已防止与页面上其他定时器的冲突,使每个定时器都互不干扰 
  clearInterval(obj.timer); 
  obj.timer=setInterval(function (){
    
    var bStop=true; // 假设:所有的值都已经到了
    
    for(var name in json)
    {
      var iTarget=json[name]; // 目标点
      
      //处理透明度,不能使用parseInt否则就为0了 
      
      if(name=='opacity')
      {
        
        // *100 会有误差 0000007 之类的 所以要用 Math.round() 会四舍五入
        var cur=Math.round(parseFloat(getStyle(obj, name))*100); 
      }
      else
      {
        var cur=parseInt(getStyle(obj, name)); // cur 当前移动的数值
      }
      
      var speed=(iTarget-cur)/5; // 物体运动的速度 数字越小动的越慢 /5 : 自定义的数字
      
      speed=speed>0?Math.ceil(speed):Math.floor(speed);
      
      if(Math.abs(speed)>MAX)speed=speed>0?MAX:-MAX;
      
      if(name=='opacity')
      {
        obj.style.filter='alpha(opacity:'+(cur+speed)+')'; //IE
        obj.style.opacity=(cur+speed)/100; //ff chrome
      }
      else
      {
        obj.style[name]=cur+speed+'px';
      }
      
      // 某个值不等于目标点 
      if(cur!=iTarget)
      {
        bStop=false;
      }
    }
    
    // 都达到了目标点
    if(bStop)
    {
      clearInterval(obj.timer);
      
      if(fnEnd) //只有传了这个函数才去调用
      {
        fnEnd();
      }
    }
  }, 20);
}

為什麼會有bstop的假設呢?

其實如果我這樣呼叫startMove(oDiv,{width:101,height:200}); 寬度變成101 已經完成運動了,高度沒有到, 但是我們可能已經關閉了當前的定時器。運動已經結束了,就會出現一個特殊情況下的bug。解釋一下:

實際上來說,需要所有的運動都到了才關閉定時器,反過來說,如果沒有不到的,那就關閉。在程式上就是定義一個布林值,一開始為true,假設

所有的值都已經到了,如果說有一個值不等於目標點,bstop為false 。 在整個循環結束後,bstop 為ture 就表示所有動作都完成了,這個時候就關閉定時器。

那麼這個運動框架基本上已經完成了,適用css2 不適用css3。

總結:

運動框架的演變過程

startMove(iTarget) 運動框架
startMove(obj,iTarget) 多物體
startMove(obj,attr,iTarget) 任意值
startMove(obj,attr,iTarget,fn) 鍊式運動
startMove(obj,json,fn) 完美運動

O(∩_∩)O謝謝 ~

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn