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