tween.js運動曲線


原文

https://www.cnblogs.com/mrsunny/archive/2011/06/21/2086080.html

四、線性美學

在 javascript動畫、運動算法詳細解釋與分析 (一、Tween 運動算法) 中我們簡單介紹了一下線性動畫在javascript中的實現,你可能會像剛開始的我一樣感覺這個動畫直白,生硬,不自然,沒有任何趣味性。而我們現實生活中也不會存在這樣的勻速,直線,從0px移動到300px的灰色箱子。。但想象一下,如果我們的箱子會緩動,會彈跳,會變形,那就會有意思的多。

現實生活中,物體的運動都存在加速度或者緩沖,物體不可能從一個速度突然蹦到另外一個速度。如果我們用符合自然現實的方式實現我們的動畫,那么我們的動畫看起來才會更加自然、生動、流暢。那么現在,我們就來看一下“緩動”。

五、各種緩動

緩入緩出曲線:

緩入:起始速度很慢,然后開始加速度。運動曲線(此時,斜率從0開始,並逐漸向1靠近)

緩出:起始速度很快,然后減速,直到速度為0。運動曲線(斜率從1開始,逐漸向0靠近)

緩入緩出:這個運動演示了物體運動從開始到結束的全過程(斜率從0到1,再從1到0)

image image image

 

下面我們具體的看一下各種緩動曲線及公式:

 

緩動類型:二次緩動

曲線類型:實際上就是二次方曲線(拋物線),p(t) = t ^ 2

曲線圖示:

image

動畫函數:

   1:   p = function( t, b, c, d){
   2:          return (t/=d)*t*c + b;
   3:  }

javascript實例:

   1:    /* des:tween算法。
   2:   t: 動畫已經執行的時間(實際上時執行多少次/幀數)
   3:   b: 起始位置
   4:   c: 終止位置
   5:   d: 從起始位置到終止位置的經過時間(實際上時執行多少次/幀數)*/
   6:  tween = {
   7:       quad : function( t, b, c, d){
   8:           return (t/=d)*t*c + b;
   9:       }
  10:   }

雖然我們不是搞數學的,不過這里還是有必要解釋一下這個公式,這里和我們之前的直線算法(p = t/d*c+b)一樣,也是以t為變量,求p,只不過這里計算的是變量的平方。直線算法中,t*c/d+b表示當前事件量乘以不變的速度(c/d)再加上起始位置。但緩入算法中因為每時間片內的速度不一致,所以不能直接用c/d,既然是二次方拋物線,可能有同學就會想,那我直接寫成p = t * t /d * c + b不就行了么,恩,你猜對了,這確實是一個二次方拋物線,不過,如果你嘗試一下,你就會發現,這個拋物線會直接把物體拋到一個非常神秘非常遙遠的地方。實際上我們這里的拋物線是有限制的,什么限制呢,0 <= p <= c,0 <= t <= d。整理該公式:

0 <= p <= c
0 <= t * c / d + b <= c
//b為常數,我們假設起始位置為0,得
0 <= t * c / d <= c
//兩邊處以c,得
0 <= t / d <= 1

這時候,公式從p = f(t)變成了p = f(t^2),也就是說0 <= p <=c,0 <= t^2 <= d。那么我們得到:

0 <= (t/d)^2 <= 1

這時其實我們已經可以看到,t與d的斜率為1,勻速運動;斜率從0到1變化,緩入運動;從1到0變化,緩出運動。緩入緩出運動實際上就是兩者結合,時間各為二分之一。下面給出二次方曲線算法,並解釋。

   1:      Quad: {
   2:          //緩入函數:斜率從0到1。
   3:          easeIn: function(t,b,c,d){
   4:              return c*(t/=d)*t + b;

5: },

   6:          //緩出函數:將c系數變為負值使圖形翻轉,然后對t減2,使圖形向右平移至正確位置
   7:          easeOut: function(t,b,c,d){
   8:              return -c *(t/=d)*(t-2) + b;
   9:          },
  10:          //緩入緩出
  11:          easeInOut: function(t,b,c,d){
  12:              //判斷當前時間是否在總時間的一半以內,是的話執行緩入函數,否則的話執行緩出函數 
  13:              if ((t/=d/2) < 1) return c/2*t*t + b;
  14:              //將總長度設置為一半,並且時間從當前開始遞減,對圖像進行垂直向上平移。公式變形過程如下圖

15: return -c/2 * ((--t)*(t-2) - 1) + b;

y = -1/2*(x)*(x-2) y = -1/2*((x)*(x-2)-1)
image image
將當前長度設置為總長度的一半 垂直平移使圖形使長度起始位置位於總長度的一半
  16:          }
  17:      }

下面我們就可以引用這些算法來實現簡單的緩動效果了。我們使用在《javascript動畫、運動算法詳細解釋與分析一》中的move.startMove("movingBox","quadEasyInOut",null,null,600);來實現我們的二次方緩動效果。那么你將會看到一塊兒板磚努力的從左邊移動到右邊然后再使勁兒的停下來。

下面我們一起來看一下三次方,四次方以及五次方曲線運動,因為大體思路都是一致的,只不過運動速度(也就是函數曲線斜率變化更快了一點而已)。所以這里只解釋算法以及圖形變化。

 

緩動類型:三次方緩動

曲線類型:實際上就是三次方曲線(拋物線),p(t) = t ^ 3

曲線圖示:基本圖形

image

運動函數:

   1:      Cubic: {
   2:          //緩入:t/=d,使t的取值始終在 0 至 1 之間,c作為系數來改變返回值的范圍(路程的長度范圍),圖形如下
   3:          easeIn: function(t,b,c,d){
   4:              return c*(t/=d)*t*t + b;

5: },

image

   6:          //緩出:t=t/d-1,使t的取值在 -1 至 0 之間,此時圖形如下
   7:          easeOut: function(t,b,c,d){
   8:              return c*((t=t/d-1)*t*t + 1) + b;

9: },

image

  10:          //緩入緩出:
  11:          easeInOut: function(t,b,c,d){
  12:              // t/=d/2 < 1,緩入,當前時間除以總時間的一半之后如果小於1(當前時間小於總時間的一半,只不過這里可以比較並且賦值,此時0 < t < 2),圖略
  13:              if ((t/=d/2) < 1) return c/2*t*t*t + b;
  14:              //否則,緩出,此時t值從-1向0過度(t-=2的作用僅僅在於將t的取值范圍控制在-1至0之間),圖略。貌似算法和上面兩種分開來的算法不一樣,
實際上只是t的取值根據上下文的環境發生了改變而已,圖像還是一樣的,只不過后一半路程的起始和終止點的范圍需要改變一下。
  15:              return c/2*((t-=2)*t*t + 2) + b;
  16:          }
  17:      }

 

 

緩動類型:四次方緩動

曲線類型:四次方曲線(拋物線),p(t) = t ^ 4

曲線圖示:基本圖形

image

運動函數:

   1:      //四次方曲線,各個函數圖像變化如下圖,你可以根據函數公式和x取值范圍來推斷函數曲線在y軸上的取值范圍
   2:      /*基本演變公式:
   3:   x ^ 4;
   4:   -x^4;
   5:   x^4 - 1;
   6:   -(x^4 - 1);

7: -1/2(x^4 - 2);*/

image

   8:      Quart: {
   9:          //緩入:t取值在0至1之間,
  10:          easeIn: function(t,b,c,d){
  11:              return c*(t/=d)*t*t*t + b;
  12:          },
  13:          //緩出:t取值在-1至0之間,因子數-1,圖像向上平移1個單位,系數為負數,垂直翻轉圖像。
  14:          easeOut: function(t,b,c,d){
  15:              return -c * ((t=t/d-1)*t*t*t - 1) + b;
  16:          },
  17:          //緩入緩出:
  18:          easeInOut: function(t,b,c,d){
  19:              //如果當前時間除以總時間的一半之后小於1。因為起始位置是0,所以直接可以使用緩入公式。
  20:              if ((t/=d/2) < 1) return c/2*t*t*t*t + b;

21: //但若當前時間大於總時間的一半,那么使t=t-2,t取值在(-1至0)之間,通過因子數-2使圖像向上平移2個單位,此時函數值在1至2之間,但c/2使函數值

得取值范圍變為0.5至1,這樣函數值的初值就變為總路程的一半,並且終值依然為1。

  22:              return -c/2 * ((t-=2)*t*t*t - 2) + b;
  23:          }
  24:      }

緩動類型:五次方緩動

曲線類型:四次方曲線(拋物線),p(t) = t ^ 5

曲線圖示:基本圖形

image

運動函數:

1: //5次方曲線,只給出圖像,公式不再解釋,都一個娘生的。

image

//稍微解釋下吧。紅色線是緩入圖像x取值范圍[0,1]。藍色線是緩出圖像,x取值范圍[-1,0]。綠色線是緩入緩出中的前一半緩入圖像,x取值范圍[0,1]。黃色線為緩入緩出中的后一半緩入圖像,x取值范圍[-1,0]。

   2:      Quint: {
   3:          easeIn: function(t,b,c,d){
   4:              return c*(t/=d)*t*t*t*t + b;
   5:          },
   6:          easeOut: function(t,b,c,d){
   7:              return c*((t=t/d-1)*t*t*t*t + 1) + b;
   8:          },
   9:          easeInOut: function(t,b,c,d){
  10:              if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
  11:              return c/2*((t-=2)*t*t*t*t + 2) + b;
  12:          }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM