【AE表達(dá)式】制作windows加載動畫

/*表達(dá)式文末自取,以下為整體思路*/

分析
很容易看出加載動畫是由很多圓跟著一個圓旋轉(zhuǎn)一圈,形成延遲或拖尾的效果;
每個圓的角速度都是慢-快-慢的循環(huán),每經(jīng)過一次角速度的循環(huán)周期,該圓剛好轉(zhuǎn)過360°;
圓的不透明度變化與角速度變化相反

思路
角速度周期變化可以用函數(shù)1-cosX解決/*1-cosX恒大于等于0,這意味著圓不會走到一半突然調(diào)頭跑,它的速度始終為正*/
至于讓每經(jīng)過一次角速度周期剛好轉(zhuǎn)過360°,只需要先通過角速度公式確定角度公式/*根據(jù)導(dǎo)數(shù)找原函數(shù)*/
再使自變量變化一個周期時(shí)因變量變化360°
不透明度用linear直接把角速度線性映射過來
延遲效果用 .valueAtTime(time-延遲時(shí)間) 很容易實(shí)現(xiàn),但本文選擇改變?nèi)呛瘮?shù)的相位
//表達(dá)式生成動畫只需要在一個圖層里寫表達(dá)式,然后ctrl+DDDDDDDDDDDDDD…
//現(xiàn)在你只需要打開AE-按住shift畫一個正圓-保存項(xiàng)目-關(guān)閉AE就好了

實(shí)現(xiàn)
1·確定角速度公式和角度公式(之后直接寫在形狀圖層的旋轉(zhuǎn)屬性里)
角速度公式為1-cosX肯定是不行的
先給它加點(diǎn)參數(shù)成為a*(c-b*cosX),注意c>b
//方便之后化簡調(diào)參
為了確定每個參數(shù)對角度變化的影響
把它還原成角度公式a*(c*X-b*sinX)
這個角度公式圖像持續(xù)向上,符合每個圓持續(xù)向一個方向旋轉(zhuǎn)的效果

但該函數(shù)周期固定,不便控制,于是引入?yún)?shù)f
將X變?yōu)閒X
角度公式更改為a*(c*fX-b*sinfX)
角速度公式改為 a*f*(c-b*cosfX),f表示頻率
/*憑啥f就表示頻率呢,我們先把頻率定義為單位時(shí)間內(nèi)轉(zhuǎn)過的圈數(shù)
沒有f時(shí),X從0增加到單位時(shí)間時(shí),剛好轉(zhuǎn)一圈
加上f后,X從0增加到單位時(shí)間時(shí),函數(shù)中sin()括號里的數(shù)實(shí)際增加至f倍的單位時(shí)間,則因變量增加至f倍,也就是轉(zhuǎn)了f圈
既然單位時(shí)間內(nèi)轉(zhuǎn)了f圈,就認(rèn)為f表示頻率*/
//你想懂?我這下面有些好康的


2·化簡消參,使每周期轉(zhuǎn)一圈
f表示頻率,則2π/f表示周期
角度公式a*(c*fX-b*sinfX)
//JavaScript里Math.sin()括號里使用弧度值,所以這里周期為2π/f
X=0時(shí),角度為0
X=2π/f時(shí),角度為2π*a*c
則2π*a*c-0=360
//角度公式返回值應(yīng)為角度制,所以為360°
所以只要滿足a*c=180/π,該效果就可以實(shí)現(xiàn)
//接下來所有計(jì)算都基于a*c=180/π的條件下,即實(shí)現(xiàn)每周期轉(zhuǎn)一圈的前提下
我們回到角速度公式a*f*(c-b*cosfX)
探究如何進(jìn)行速度控制

思路一/*理解簡單但不好*/
a*c=180/π代入角速度公式a*f*(c-b*cosfX)得V=f*180/π-a*f*b*cosfX,減號后面是變化量,則可得出
Vmax=f*180/π+a*f*b,Vmin=f*180/π-a*f*b
發(fā)現(xiàn)V主要由f控制,而V最大變化差由a*b控制
則可以為控制器圖層/*名叫“控制器”的圖層,一般用空對象*/添加兩個滑塊控制,以控制f和a*b,為形狀圖層的旋轉(zhuǎn)屬性輸入:
f =3/*自己連接一下滑塊控制好嗎*/;
ab =60/*只會復(fù)制是不行的*/;
X = time;
X*f*180/Math.PI-ab*Math.sin(X*f)
//函數(shù)部分:acfx - ab sinfx
//這個方法壞就壞在誰知道a*b什么意思啊,過于抽象

思路二/*控制Vmax/Vmin*/
根據(jù)角速度公式a*f*(c-b*cosfX)得出
Vmax=a*f*(c+b),Vmin=a*f*(c-b)
就可以看出Vmax/Vmin=(c+b)/(c-b)=1+2b/(c-b)=1+2/(c/b-1)
于是Vmax/Vmin只與c/b有關(guān),則說明可以用一個參數(shù)代替c/b,但c/b的參數(shù)含義不便理解,于是選擇用k代替Vmax/Vmin
參數(shù)k的含義即最低點(diǎn)速度/最高點(diǎn)速度,可得
c=(k+1)/2,b=(k-1)/2進(jìn)而化簡角度公式/*交給表達(dá)式做吧*/
同上,輸入:
f = 3 ;k = 50 ;X = time;
c = (k+1)/2 ; b = (k-1)/2 ; a=180/Math.PI/c ;
a*( X*f*c-b*Math.sin(X*f))?
//函數(shù)部分:a(cfx -b sinfx)
//你甚至可以把k改為負(fù)數(shù)


3·不透明度
在最高點(diǎn)使不透明度為100,最低點(diǎn)為0,恰好最高點(diǎn)也是速度最低點(diǎn),則采用映射
映射分線性映射linear和非線性映射ease,這里用linear
/*linear(映射源,映射源min,映射源max,對象min,對象max)為線性映射,ease為非線性映射,兩者參數(shù)一致*/
映射即一個量跟著另一個量變化,這里是不透明度跟隨角速度變化,則在圖層不透明度屬性里輸入:
linear(
transform.rotation.speed/*獲取旋轉(zhuǎn)角度實(shí)時(shí)變化速率*/,Vmin,Vmax,100,0)
//后來我發(fā)現(xiàn)把Vmin和Vmax調(diào)換位置并不影響效果,至今不理解
//把100和0位置互換是因?yàn)樗俣茸畹蜁r(shí)不透明度最高
再把上面的公式拿點(diǎn)下來
Vmin=a*f*(c-b),c=(k+1)/2,b=(k-1)/2? 可得? Vmin=a*f,則在linear表達(dá)式的上方添加:
f = 3 ; k = 50 ;
c = (k+1)/2 ; a = 180/Math.PI/c ;
Vmin = a * f ; Vmax = k * Vmin ;

4·動畫延遲
/*valueAtTime的方法你肯定會*/
把代碼中的X = time; 改為X = time + s * .001 * index ;
/*time返回時(shí)間線所處的時(shí)間值,單位:秒;
0.001使調(diào)節(jié)精度增加;
index返回圖層序號,使每個圖層延遲量不同;
s * .001 * index 即自變量的延遲量*/
不要忘了為s添加滑塊控制
//valueAtTime用于拖尾動畫很方便


總結(jié)
如果你喜歡的話還可以用表達(dá)式控制每個圓的大小、顏色、形狀??//過于基礎(chǔ)就不講
一開始做這個動畫的參數(shù)有f、a、b、c,后來在不斷調(diào)參的過程中發(fā)現(xiàn)參數(shù)間的某種聯(lián)系,就分析代碼,最終提煉成兩個參數(shù):f和k,于是寫下這個表達(dá)式基礎(chǔ)教程
?
AE初學(xué),大佬輕噴
?
//下面這個表達(dá)式動畫是我最近一個視頻里用到的思路,更基礎(chǔ)一點(diǎn),不知道需不需要出教程


代碼/*與上文有一點(diǎn)出入*/
旋轉(zhuǎn):
f=thisComp.layer("控制器").effect("頻率")("滑塊");
k=thisComp.layer("控制器").effect("最大值/最小值 速度")("滑塊");
s=index*.001*thisComp.layer("控制器").effect("偏移")("滑塊");
Vmin=1;Vmax=k;c=(k+1)/2;b=(k-1)/2;
//Vmin/af = c - b,Vmax/af = c + b
a=360/(2*c*Math.PI);
//a=360/(2*c*PI),使每一個周期旋轉(zhuǎn)360°
a*(-b*Math.sin((time+s)*f)+(time+s)*f*c)
//函數(shù)部分:a(-b sinfx + cfx);導(dǎo)數(shù):af(c - b cosfx)
//V=0.5*af*(k+1-(k-1)cosfx),由導(dǎo)數(shù)化簡所得
不透明度:
f=thisComp.layer("控制器").effect("頻率")("滑塊");
k=thisComp.layer("控制器").effect("最大值/最小值 速度")("滑塊");
pi=Math.PI;
Vmin=f*360/(k*pi+pi);Vmax=k*Vmin;
//V = 0.5*af*(k+1-(k-1)cosfx),速度公式
//Vmin = af
linear(transform.rotation.speed,Vmin,Vmax,100,0)