基于時(shí)間的動(dòng)畫函數(shù)

基于時(shí)間的動(dòng)畫函數(shù)是適用于大多數(shù)情況,避免了由于頁(yè)面切換造成的動(dòng)畫不連貫現(xiàn)象,同時(shí)jquery內(nèi)部也使用的這種方法。下面是源碼,結(jié)合源碼看一下就明白了。

<script>
   var btn=document.getElementsByClassName("button-success")[0];
   var dv=document.getElementsByClassName("div")[0];
   btn.onclick= function () {
      getStyle(dv,"left");
      move(dv,2000,{
         left:"200",
         top:"300",
      },"elasticBoth", function () {
         console.log(1);
      })
   }
   var move= function (obj,t, JSON, type, fn) {
      var startValue={};//獲取其實(shí)值
      var startTime=(new Date()).getTime();//獲取起始時(shí)間
      for(var attr in JSON){
         startValue[attr]=0;//初始化一個(gè)style對(duì)象
         if(attr ==="opacity"){
            startValue[attr]=Math.round(getStyle(obj,attr)*100);//兼容IE style是opacity的情況
         }else{
            startValue[attr]=parseInt(getStyle(obj,attr))
         }
      }
      clearInterval(obj.time);//避免多次觸發(fā)造成動(dòng)畫疊加
      obj.time=setInterval(function () {
         var nowTime=(new Date()).getTime();//獲取現(xiàn)在時(shí)間
         var scale=1-Math.max(0,startTime+t-nowTime)/t;//通過(guò)tartTime+t-nowTime獲取隨著時(shí)間變化的變化率
         for(var attr in JSON){//對(duì)json形式的style進(jìn)行挨個(gè)賦值
            var value=Tween[type](scale*t,startValue[attr],JSON[attr]-startValue[attr],t);//Tween用法,這里把時(shí)間t設(shè)置為變化量,這樣就可以得到Tween處理后的變化值。
            if(attr==="opacity"){
               obj.style.filter='alpha(opacity'+value+')';
               obj.style.opacity=value/100;
            }else{
               obj.style[attr]=value+'px';
            }
         }
         if(scale===1){
            clearInterval(obj.time);
            if(fn){
               fn.call(obj);//觸發(fā)回調(diào)
            }
         }
      },30);

   }
   var getStyle= function (obj, attr) {
      if(obj.currentStyle){
         return obj.currentStyle[attr];
      }else{
         return getComputedStyle(obj,false)[attr];
      }
   }
   var Tween = {
      linear: function (t, b, c, d){  //勻速
         return c*t/d + b;
      },
      easeIn: function(t, b, c, d){  //加速曲線
         return c*(t/=d)*t + b;
      },
      easeOut: function(t, b, c, d){  //減速曲線
         return -c *(t/=d)*(t-2) + b;
      },
      easeBoth: function(t, b, c, d){  //加速減速曲線
         if ((t/=d/2) < 1) {
            return c/2*t*t + b;
         }
         return -c/2 * ((--t)*(t-2) - 1) + b;
      },
      easeInStrong: function(t, b, c, d){  //加加速曲線
         return c*(t/=d)*t*t*t + b;
      },
      easeOutStrong: function(t, b, c, d){  //減減速曲線
         return -c * ((t=t/d-1)*t*t*t - 1) + b;
      },
      easeBothStrong: function(t, b, c, d){  //加加速減減速曲線
         if ((t/=d/2) < 1) {
            return c/2*t*t*t*t + b;
         }
         return -c/2 * ((t-=2)*t*t*t - 2) + b;
      },
      elasticIn: function(t, b, c, d, a, p){  //正弦衰減曲線(彈動(dòng)漸入)
         if (t === 0) {
            return b;
         }
         if ( (t /= d) == 1 ) {
            return b+c;
         }
         if (!p) {
            p=d*0.3;
         }
         if (!a || a < Math.abs(c)) {
            a = c;
            var s = p/4;
         } else {
            var s = p/(2*Math.PI) * Math.asin (c/a);
         }
         return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
      },
      elasticOut: function(t, b, c, d, a, p){    //正弦增強(qiáng)曲線(彈動(dòng)漸出)
         if (t === 0) {
            return b;
         }
         if ( (t /= d) == 1 ) {
            return b+c;
         }
         if (!p) {
            p=d*0.3;
         }
         if (!a || a < Math.abs(c)) {
            a = c;
            var s = p / 4;
         } else {
            var s = p/(2*Math.PI) * Math.asin (c/a);
         }
         return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
      },
      elasticBoth: function(t, b, c, d, a, p){
         if (t === 0) {
            return b;
         }
         if ( (t /= d/2) == 2 ) {
            return b+c;
         }
         if (!p) {
            p = d*(0.3*1.5);
         }
         if ( !a || a < Math.abs(c) ) {
            a = c;
            var s = p/4;
         }
         else {
            var s = p/(2*Math.PI) * Math.asin (c/a);
         }
         if (t < 1) {
            return - 0.5*(a*Math.pow(2,10*(t-=1)) *
                  Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
         }
         return a*Math.pow(2,-10*(t-=1)) *
               Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b;
      },
      backIn: function(t, b, c, d, s){     //回退加速(回退漸入)
         if (typeof s == 'undefined') {
            s = 1.70158;
         }
         return c*(t/=d)*t*((s+1)*t - s) + b;
      },
      backOut: function(t, b, c, d, s){
         if (typeof s == 'undefined') {
            s = 3.70158;  //回縮的距離
         }
         return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
      },
      backBoth: function(t, b, c, d, s){
         if (typeof s == 'undefined') {
            s = 1.70158;
         }
         if ((t /= d/2 ) < 1) {
            return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
         }
         return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
      },
      bounceIn: function(t, b, c, d){    //彈球減振(彈球漸出)
         return c - Tween['bounceOut'](d-t, 0, c, d) + b;
      },
      bounceOut: function(t, b, c, d){
         if ((t/=d) < (1/2.75)) {
            return c*(7.5625*t*t) + b;
         } else if (t < (2/2.75)) {
            return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
         } else if (t < (2.5/2.75)) {
            return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
         }
         return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
      },
      bounceBoth: function(t, b, c, d){
         if (t < d/2) {
            return Tween['bounceIn'](t*2, 0, c, d) * 0.5 + b;
         }
         return Tween['bounceOut'](t*2-d, 0, c, d) * 0.5 + c*0.5 + b;
      }
   }
</script>

Linear:無(wú)緩動(dòng)效果(勻速運(yùn)動(dòng));
Quadratic:二次方的緩動(dòng);
Cubic:三次方的緩動(dòng)
Quartic:四次方的緩動(dòng);
Quintic :五次方的緩動(dòng);
Sinusoidal:正弦曲線的緩動(dòng);
Exponential:指數(shù)曲線的緩動(dòng);
Circular:圓形曲線的緩動(dòng);
Elastic:指數(shù)衰減的正弦曲線緩動(dòng);
Back:超過(guò)范圍的三次方緩動(dòng));
Bounce:指數(shù)衰減的反彈緩動(dòng)。
每個(gè)效果都分三個(gè)緩動(dòng)方式(方法),分別是:
easeIn:從0開始加速的運(yùn)動(dòng);
easeOut:減速到0的運(yùn)動(dòng);
easeInOut:前半段從0開始加速,后半段減速到0的運(yùn)動(dòng)。
函數(shù)的四個(gè)參數(shù)分別代表:
t--- current time(當(dāng)前時(shí)間);
b--- beginning value(初始值);
c--- change in value(變化量);
d---duration(持續(xù)時(shí)間)
運(yùn)算的結(jié)果就是當(dāng)前的運(yùn)動(dòng)路程??梢钥吹?,只有t-current-time是能變化的,這樣就支持了根據(jù)時(shí)間來(lái)實(shí)現(xiàn)動(dòng)畫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 鏈接 歡迎大家訪問(wèn)我的個(gè)人網(wǎng)站四度空間 Fuse? 很多時(shí)候,設(shè)計(jì)師設(shè)計(jì)一個(gè)特效動(dòng)畫出來(lái),用靜態(tài)的UE是很難向開發(fā)...
    Carden閱讀 6,161評(píng)論 0 1
  • 1 背景 不能只分析源碼呀,分析的同時(shí)也要整理歸納基礎(chǔ)知識(shí),剛好有人微博私信讓全面說(shuō)說(shuō)Android的動(dòng)畫,所以今...
    未聞椛洺閱讀 2,844評(píng)論 0 10
  • 主要參考的文章 Zookeeper作用和典型應(yīng)用場(chǎng)景 Zookeeper作為一個(gè)分布式系統(tǒng),主要用來(lái)解決分布式集群...
    walker_liu_fei閱讀 436評(píng)論 0 0
  • 登山尋隱訪古風(fēng), 高岳峰回漫天紅。 望夫石下三重淚, 遠(yuǎn)去黃淮無(wú)禹同。 倚門三辭只為公, 林海春風(fēng)凱歌鳴。 聽聞涂...
    荷軒畫雪閱讀 439評(píng)論 1 2
  • 第十一章(一)umbrella什么都不知道。他只記得FOX和FLLFFL爭(zhēng)吵了起來(lái),然后就沒(méi)了下文——當(dāng)時(shí)他就是覺(jué)...
    汀雨S26閱讀 560評(píng)論 0 2

友情鏈接更多精彩內(nèi)容