[AE表達(dá)式]萬能彈性表達(dá)式分析
其實(shí)彈性表達(dá)式已經(jīng)很普遍了,幾乎到處都是,呵呵,可為啥要介紹這段表達(dá)式呢?我覺得其中有很多技巧值得我們學(xué)習(xí)!這段表達(dá)式來之J大的一篇帖子,好像是一個(gè)叫Frank的外國大神寫的!其中有一句我也沒弄懂到底是什么作用,各位大哥誰明白知會我一聲??!下面是這段表達(dá)式,說它是萬能,就是不管啥條件,拷貝下來往你的位移動(dòng)畫中位置參數(shù)里一扔就OK了!有興趣的可以試試,無論你的動(dòng)畫是怎么動(dòng)的,關(guān)鍵幀處都會產(chǎn)生彈性動(dòng)畫,而且是合理那種!
amp = .1;
freq = 2.0;
decay = 2.0;
n = 0;
if (numKeys > 0){
?n = nearestKey(time).index;
?if (key(n).time > time){n--;}
??}
if (n == 0){ t = 0;}
else{t = time - key(n).time;}
if (n > 0){
?v = velocityAtTime(key(n).time - thisComp.frameDuration/10);
?value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
???}
else{value}
下面開始解釋,前三行就不用說了,都是變量的定義,分別是振幅、頻率、衰變指數(shù)或者叫阻力阻尼啥的
n=0;
N其實(shí)是用來記錄關(guān)鍵幀序號的,這個(gè)變量很重要
if (numKeys > 0)
判斷關(guān)鍵幀個(gè)數(shù)是否大于0,如果是執(zhí)行{}中內(nèi)容
n = nearestKey(time).index
取靠近時(shí)間線的那個(gè)關(guān)鍵幀的序號,這里要注意取得的關(guān)鍵幀有可能是時(shí)間線前的最后一個(gè),也可能是時(shí)間線后的第一個(gè),所以才有下一句的IF判斷。
if (key(n).time > time){n--;}
如果取得的關(guān)鍵幀是時(shí)間線后面第一個(gè),則N的序號減1,這樣就保證里N永遠(yuǎn)代表的是時(shí)間線前的最后一個(gè)關(guān)鍵幀。
if (n == 0){ t = 0;}
如果沒有關(guān)鍵幀(N=0)時(shí),T=0。T是一個(gè)頻率改變因數(shù),也是一個(gè)阻力改變的因數(shù)。
else{t = time - key(n).time;}
如果N不為0,那么T就等于時(shí)間線與其之前最后一個(gè)關(guān)鍵幀的時(shí)間的差,也就是說時(shí)間線離這個(gè)關(guān)鍵幀越遠(yuǎn)T就越大。
if (n > 0)
當(dāng)有關(guān)鍵幀,也就是說有動(dòng)畫的時(shí)候執(zhí)行{}里的內(nèi)容,前面那些句都是鋪墊,這個(gè)大括號里的才是正戲。
v = velocityAtTime(key(n).time - thisComp.frameDuration/10);
velocityAtTime()這個(gè)函數(shù)是求在某一時(shí)刻對象的速度,AE里面叫關(guān)鍵幀數(shù)率,單位是“像素/秒”,怎么理解這個(gè)呢?其實(shí)就是你在做對象位移動(dòng)畫時(shí),關(guān)鍵幀時(shí)刻對象相對屏幕的瞬時(shí)速度,說屏幕有點(diǎn)不準(zhǔn)確,應(yīng)該說對象所在合成。
*我不明白了地方也來了,thisComp.frameDuration 的解釋是“返回畫面的持續(xù)時(shí)間”,可是我怎么試都沒弄明白,一直這個(gè)的返回值都是0。當(dāng)我把這句改成v = velocityAtTime(key(n).time); 也不影響最后的效果。不過那位大大既然寫這個(gè)應(yīng)該是有意圖的,誰知道告訴我吧!呵呵。
看到樓下的兄弟提醒,我又研究了一下,發(fā)現(xiàn)我錯(cuò)了 - thisComp.frameDuration/10 這個(gè)是不能去掉的,不然會出現(xiàn)很奇怪的彈動(dòng)現(xiàn)象。但是減號后面也不一定要是 thisComp.frameDuration/10 ,只要是一個(gè)非常小的數(shù)就可以,主要可能是取關(guān)鍵幀前很短一個(gè)時(shí)刻的速度,就算是用F9平滑關(guān)鍵幀,彈動(dòng)也能發(fā)生效果。用 thisComp.frameDuration/10 只是因?yàn)樗銐蛐?,因?yàn)槭菐蕰r(shí)間的1/10嘛。這回對了,哈哈!
value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
肉都在這句了,呵呵!
value+ 這個(gè)是在原來值的基礎(chǔ)上做彈性設(shè)置的,這么寫的好處是無論你把這段表達(dá)式放在2D還是3D圖層中都可以起作用,不用[x,y,z]這么寫是確保動(dòng)畫在三個(gè)軸向上的運(yùn)動(dòng)都會有彈性動(dòng)畫。
v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
V是對象關(guān)鍵幀的瞬時(shí)速度,這個(gè)變量是作為一個(gè)振幅變量的補(bǔ)充,這樣更符合物理現(xiàn)象,當(dāng)速度越大振幅就越大。當(dāng)對象的速度是0時(shí),那彈性表達(dá)式結(jié)果也為0。
T在Math.sin()中是作為頻率的補(bǔ)充,作用是時(shí)間線離關(guān)鍵幀越遠(yuǎn),值越大頻率越快,這樣比較符合物理規(guī)律。
T在Math.exp()中試阻力指數(shù),作用是時(shí)間線離關(guān)鍵幀越遠(yuǎn),值越大阻力越大,最后讓彈動(dòng)歸于平靜。
else{value}
如果沒有關(guān)鍵幀,原來值保持不變。
哦了,不知道大家能不能看懂!懂不懂都留句鼓勵(lì)我的回復(fù)吧!哈哈
.
補(bǔ)充一下:這個(gè)表達(dá)式在關(guān)鍵幀做平滑以后是不起作用的,因?yàn)槠交蟮年P(guān)鍵幀速度是0。再一個(gè)就是如果有兩個(gè)以上關(guān)鍵幀的時(shí)候,除第一個(gè)外都會有彈性效果,程序未做判斷,唉!這也算瑕疵吧!也許不算,呵呵!
轉(zhuǎn)載自豆瓣:https://site.douban.com/215474/widget/notes/16140669/note/493179628/
原作者:想象C 作者