四、線性美學
在 javascript動畫、運動演算法詳細解釋與分析 (一、Tween 運動演算法) 中我們簡單介紹了一下線性動畫在javascript中的實現,你可能會像剛開始的我一樣感覺這個動畫直白,生硬,不自然,沒有任何趣味性。而我們現實生活中也不會存在這樣的勻速,直線,從0px移動到300px的灰色箱子。。但想象一下,如果我們的箱子會緩動,會彈跳,會變形,那就會有意思的多。
現實生活中,物體的運動都存在加速度或者緩衝,物體不可能從一個速度突然蹦到另外一個速度。如果我們用符合自然現實的方式實現我們的動畫,那麼我們的動畫看起來才會更加自然、生動、流暢。那麼現在,我們就來看一下“緩動”。
五、各種緩動
緩入緩出曲線:
緩入:起始速度很慢,然後開始加速度。運動曲線(此時,斜率從0開始,並逐漸向1靠近) |
緩出:起始速度很快,然後減速,直到速度為0。運動曲線(斜率從1開始,逐漸向0靠近) |
緩入緩出:這個運動示範了物體運動從開始到結束的全過程(斜率從0到1,再從1到0) |
|
|
|
下面我們具體的看一下各種緩動曲線及公式:
緩動類型:二次緩動
曲線類型:實際上就是二次方曲線(拋物線),p(t) = t ^ 2
曲線圖示:
動畫函數:
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) |
|
|
將當前長度設定為總長度的一半 |
垂直平移使圖形使長度起始位置位於總長度的一半 |
16: }
17: }
下面我們就可以引用這些演算法來實現簡單的緩動效果了。我們使用在《javascript動畫、運動演算法詳細解釋與分析一》中的move.startMove("movingBox","quadEasyInOut",null,null,600);來實現我們的二次方緩動效果。那麼你將會看到一塊兒板磚努力的從左邊移動到右邊然後再使勁兒的停下來。
下面我們一起來看一下三次方,四次方以及五次方曲線運動,因為大體思路都是一致的,只不過運動速度(也就是函數曲線斜率變化更快了一點而已)。所以這裡只解釋演算法以及圖形變化。
緩動類型:三次方緩動
曲線類型:實際上就是三次方曲線(拋物線),p(t) = t ^ 3
曲線圖示:基本圖形
運動函數:
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: },
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: },
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
曲線圖示:基本圖形
運動函數:
1: //四次方曲線,各個函數映像變化如,你可以根據函數公式和x取值範圍來推斷函數曲線在y軸上的取值範圍
2: /*基本演變公式:
3: x ^ 4;
4: -x^4;
5: x^4 - 1;
6: -(x^4 - 1);
7: -1/2(x^4 - 2);*/
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
曲線圖示:基本圖形
運動函數:
1: //5次方曲線,只給出映像,公式不再解釋,都一個娘生的。
//稍微解釋下吧。紅色線是緩入映像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: }
13: }
OK。
到這裡簡單緩入緩齣動畫解析完畢,如果童鞋們有任何意見或者建議或者問題,都可以與本人聯絡。
本人在下一篇中將討論一下稍微複雜一點的曲線運動。