有時你可能想美化您的動畫動作有位物理真實感。例如,你可能有一個快速層從零擴展到100%,并要加一點過沖和振蕩,有它最終定居在100%。另一個例子是,如果你有一個對象落入框架,你想,當它擊中了底部反彈了一點。這兩種情況看起來相似,但它們代表了完全不同的物理過程。任一這些模擬可以使用表達式來創建,但選擇正確的一方面,這是很重要的。在這篇文章中,我將詳細討論這些動畫工具以及就如何以及何時使用它們的一些技巧。
在這兩個彈跳和緩沖的情況,你正在處理的衰減幅度。過沖,你一般都處理一個諧波振蕩,就像你有一個擺或彈簧。這意味著頻率保持不變(在對象的共振頻率)作為振幅衰減。這通常是用模擬的指數衰減正弦波。這是一個簡單的解決辦法,但肯定是有竅門能讓初始幅度正確匹配與傳入的動畫)。
基本衰減的正弦波振蕩應用到旋轉屬性。反彈是一個完全不同的野獸。當一個對象的反彈,它失去在每個反彈,這會影響二者的幅度和頻率的能量。作為反彈的幅度降低,它們發生更頻繁。這意味著正弦波模擬不足以反彈。事實上,反彈的波形實際上是一系列降幅的拋物線。物體停止在反彈的頂部,然后加速(由于一些重力狀現象的力),因此所涉及的數學運算是完全不同的。
該波形通過模擬反彈表達式生成。請注意,反彈出現較多的對象失去能量。一個基本的反彈表達已應用到旋轉屬性。
緩沖詳情
看一看基本表達式為指數衰減正弦波:
amp = 80;
freq = 1;
decay = 1;t = time - inPoint;
amp*Math.sin(t*freq*Math.PI*2)/Math.exp(t*decay);
因為它位于,這種表達會引發衰減的正弦波振蕩圖層的入點。前三行只需設定的波形參數進行:80最大振幅,每秒一個振蕩的頻率,和一個衰減(多快的振幅減小)之一值。變量t是用來計算由于層的In點的時間。所有真正的數學發生在最后一行。
注:
javaScript函數Math.sin()和Math.cos()實現都產生正弦波,但他們的目的不同表達作家。該Math.sin()函數從零開始,增加價值。 Math.cos()實現為90度的相位差Math.sin(),這意味著它開始于最大值和減小。
你通常會選擇Math.cos()實現當你想一開始就在完全伸展,或完全旋轉狀態的對象。例如,您可能要開始與擺在最高轉速,而不是零鐘擺運動。我們不會在這里使用它,但它是一個很好的工具來了解。
有三樣東西,在最后一行回事。所述Math.sin()片產生頻率頻率而變化的正負之一之間振幅的正弦波。該Math.exp()件產生的曲線,在可變衰減所確定的速率成倍增加。正弦波得到由幅值變量(安培)相乘,并且該結果被由指數曲線的值除以,產生所希望的指數衰減正弦波。
這是一個方便的表達,有時是你所需要的。更多的時候,你會想用指數衰減正弦波提供一些振蕩尖峰另一個運動結束。訣竅是讓沖振蕩的幅度,以進向速度相匹配。你做到這一點的方式取決于您的動畫的性質。在某些情況下,可能必須即輸入的速度由表達式本身確定的動畫。例如,假設您想要一個層從零到200%的比例增加在很短的時間段,然后沖過一點點,并定居在200%。所以動畫觸發器的層的在一點上,我們會對其進行設置。這里有一個基本的表達,將圖層從規模0到100%超過十分之一秒,開始在一層的分析:
t = time - inPoint;
startVal = [0,0];
endVal = [200,200];
dur = 0.1;
linear(t,0,dur,startVal,endVal);
計算緩沖
現在,我們將添加一些超調。在這種情況下,由于進入的動畫是通過一個linear()函數生成,我們可以很容易地計算速度進入過沖。事實證明,該速度是剛結束值減去開始值,由持續時間,在這種情況下將是分割(endVal - startVal)/dur。因此,我們需要修改規模化表達,使其持續上升直到它達到endVal,然后切換到超調振蕩。最終的表達式如下所示:
freq = 3;
decay = 5;t = time - inPoint;
startVal = [0,0];
endVal = [200,200];
dur = 0.1;
if (t < dur){
linear(t,0,dur,startVal,endVal);
}else{
amp = (endVal - startVal)/dur;
w = freq*Math.PI*2;
endVal + amp*(Math.sin((t-dur)*w)/Math.exp(decay*(t-dur))/w);
請注意,從linear()坡道的過沖振蕩(其中發生在5f)的過渡完美匹配。
緩沖動畫匹配傳入動畫的速度。
訣竅使這兩個動畫比賽的速度就是神秘的可變瓦特這里,w表示角速度振蕩。沒有進入很多細節,事實證明,除以輸入速度與角速度的振蕩給出了一個匹配完美的超調。具體而言,這意味著更高的振蕩頻率越低,產生的過沖的幅度。記得有過沖的一個重要的事情是,你沒有直接控制超調幅度(放大器變量由下式計算)。如果你想有一個較大的超調,你或者需要增加進來的速度,或者減少其振蕩頻率。這是值得擺弄表情看頻率,傳入速度,并導致超調幅度之間的相互作用。
這是一個非常有用的和通用的表達。這里有好玩的,你可以使用文本圖層來獲取文本字符,隨機從零到100%的比例增加,有超調的變化。為了得到這個工作,你想補充一個動畫縮放你的文字層,縮放值設置為百分之零,添加表達式選擇器,(那么你可以刪除范圍選擇),最后,更換式的默認表情選擇的物業數量與此:
freq = 3;
decay = 5;
maxDelay = 1.0;seedRandom(textIndex,true);
myDelay = random(maxDelay);
t = time - (inPoint + myDelay);
startVal = [100,100];
endVal = [0,0];
dur = 0.1;
if (t < dur){
linear(t,0,dur,startVal,endVal);
}else{
amp = (endVal - startVal)/dur;
w = freq*Math.PI*2;
endVal + amp*(Math.sin((t-dur)*w)/Math.exp(decay*(t-dur))/w);
}
這里是你可以用它來獲得文字層的3D人物依次擺成視圖沖另一種變體。 你會發現,這和以前版本的表達之間的唯一真正的區別是計算基于角色的textIndex值隨機延遲變量(myDelay)的線。使用textIndex作為隨機種子,確保每個角色都會獲得一個獨特的,隨機延遲。在這里,過沖表達已結合隨機文本縮放。
首先,你需要你的文字層的錨點移動到文本的頂部。你可以用一個錨點動畫做到這一點。此外,請確保您已啟用每個字符3D。添加一個新的動畫為旋轉(不使用你用來調整錨點是同一個)。設置X旋轉,使得文本(垂直于屏幕)旋轉出的角度值。添加表達式選擇和刪除功能選擇。更換表達選擇的財產金額與此默認的表達式:
freq = 2;
decay = 5;
delay = .15;
dur = .12;myDelay = (textIndex-1)*delay;
t = time - (inPoint + myDelay);
startVal = 100;
endVal = 0;if(t < dur){
linear(t,0,dur,startVal,endVal);
}else{
amp = (endVal - startVal)/dur;
w = freq*Math.PI*2;
endVal + amp*(Math.sin(t*w)/Math.exp(decay*t)/w);
}
3D人物旋轉到順序來看,有緩沖。
關鍵幀緩沖
或許是一種較為普遍的超調的應用將增加超調,以一個關鍵幀動畫。這實際上是相當簡單的,因為表達式語言,您可以訪問屬性的速度。在這種情況下,我們將使用velocityAtTime()函數來獲得進入的速度在最近的關鍵幀。這是關鍵幀沖表達式:
freq = 3;
decay = 5;n = 0;
if (numKeys > 0){
n = nearestKey(time).index;
if (key(n).time > time) n--;
}
if (n > 0){
t = time - key(n).time;
amp = velocityAtTime(key(n).time - .001);
w = freq*Math.PI*2;
value + amp*(Math.sin(t*w)/Math.exp(decay*t)/w);
}else
value
與以前一樣,前兩行只定義控制振蕩的頻率和衰減的變量。接下來的部分是一個方便的小程序,發現最新的關鍵幀。表達的其余部分提取屬性的速度在那個關鍵幀并使用該速度作為計算過沖的幅度。需要注意的是表達實際獲取速度的關鍵幀之前0.001秒,以確保它拿起傳入的(而不是傳出)的速度。
其中該表達的非常好的特點是,它是PRoperty-agnostic無關的,這意味著它應該工作,原樣,具有可關鍵幀幾乎所有的property-agnostic。看到兩個欄的電影動畫關鍵幀的兩個例子,其中的表達提供過沖。首先演示了一個流行的X旋轉過沖,其中層關鍵幀以快速旋轉100度至零,以表達提供超調動畫。第二個演示過沖應用于關鍵幀的位置屬性。
彈跳的表達已經被應用到了關鍵幀的X軸旋轉性能。
這里,緩沖表達已施加到關鍵幀位置屬性。
彈跳概述
我們的最終目標是在這里要結束了,將模擬反彈在關鍵幀運動結束的表達。要了解一個反彈仿真工作,雖然,這是非常有用開始與一個場景,可能是比較熟悉的,一個彈丸的反彈,當它擊中地面/地板。為了讓事情簡單,我們將其限制為兩個維度。當啟動一個2D彈丸,有若干在起作用的因素:在重力的作用,對象的彈性,發射角度,初始速度,有時摩擦。模擬這種運動的表達基本上具有分裂初始速度到x和y分量。重力工作在y方向上。在每個彈跳,對象失去根據基于所述摩擦的彈性以及x速度ÿ速度。考慮到所有這些因素考慮進去給你的2D反彈,看起來像這樣的表達式:
elev = degreesToRadians(75);
v = 1900;
e = .7;
f = .5;
g = 5000;
nMax = 9;
tLaunch = 1;
vy = v*Math.sin(elev);
vx = v*Math.cos(elev);
if (time >= tLaunch){
t = time - tLaunch;
tCur = 0;
segDur = 2*vy/g;
tNext = segDur;
d = 0; // x distance traveled
nb = 0; // number of bounces
while (tNext < t && nb <= nMax){
d += vx*segDur;
vy *= e;
vx *= f;
segDur *= e;
tCur = tNext;
tNext += segDur;
nb++
}
if(nb <= nMax){
delta = t - tCur;
x = d + delta*vx;
y = delta*(vy - g*delta/2);
}else{
x = d;
y = 0;
}
value + [x,-y]
}else
value
有幾件事情需要注意的這一表達。彈跳參數發射角(海拔),初始速度(ⅴ),彈性(e)所示,摩擦(f)和比重(g)-are所有限定在表達的頂部。請注意,您還必須定義,以保持從表情到消失的小反彈無盡計算反彈(n最大)的最大數量。這個版本的表達還包括一個變量來控制發射時間(tLaunch)。
二維模擬反彈使用發射角度,初速度,重力,彈力,和摩擦。
關鍵幀反彈
現在,我們來看看這樣的論點:這確實是本節的點。該表達式使用屬性的速度進入一個關鍵幀來計算一個反彈(方向相反的到傳入動畫)的一系列減少反彈的。表達式使用大部分邏輯從基本2D彈跳表達,所不同的是,沒有必要擔心發射角和初始速度(那些從關鍵幀中檢索),或磨擦。這種表達已經用老式大多數屬性的工作。見邊欄為影片加在規模,位置(2D和3D),并且旋轉屬性的例子。這里的表達式:
e = .7;
g = 5000;
nMax = 9;n = 0;
if (numKeys > 0){
n = nearestKey(time).index;
if (key(n).time > time) n--;
}
if (n > 0){
t = time - key(n).time;
v = -velocityAtTime(key(n).time - .001)*e;
vl = length(v);
if (value instanceof Array){
vu = (vl > 0) ? normalize(v) : [0,0,0];
}else{
vu = (v < 0) ? -1 : 1;
}
tCur = 0;
segDur = 2*vl/g;
tNext = segDur;
nb = 1; // number of bounces
while (tNext < t && nb <= nMax){
vl *= e;
segDur *= e;
tCur = tNext;
tNext += segDur;
nb++
}
if(nb <= nMax){
delta = t - tCur;
value + vu*delta*(vl - g*delta/2);
}else{
value
}
}else
value
該彈回表達應用于位置,旋轉和縮放屬性。
和以前一樣,你可以通過調整彈性(E)和重力(G)變量控制反彈的特點。
新聞熱點
疑難解答