// 解读:Musicminion
// 注释:原始的代码里面有一些冗余代码,我做了一些删除
// 首先要理解这个表达式表达的是什么:这个表达式表示的是动画完成的
// 以位置参数为例子:
// 真实的位置参数 = 该图层在变换中的位置 + 偏移量(动画制作/表达式选择器中的位置值) * 表达式选择器里面的数量百分比
// 这个数量百分比可以从 0% -> 100%, 也可以从 100% -> 0%
// 而我们这个表达式就是为了表示上面所述的 【表达式选择器里面的数量百分比】
// 首先获取该合成的设置参数
freq = effect("frequency")("滑块"); //(频率)
decay = effect("decay")("滑块"); //(衰退,减缓)
duration = effect("duration")("滑块"); //(持续时间)
// 计算延迟,也就是每两个字之间延迟多久开始动画
// 注意:表达式里面的依据是字符,也就说每个字符都是一个独立个体来计算轨迹
// thisComp.frameDuration 代表合成中1帧的持续时间
// inPoint的返回类型是数值,返回图层的入点(以秒为单位)。
retard = textIndex * thisComp.frameDuration * 2;
// t 代表每个字已经开始了多少时间,如果小于0,没开始,大于0就是已经开始
// 值得注意的是,每个文字的开始时间是不同的!
t = time - (inPoint + retard);
startVal = [100,100,100];
endVal = [0,0,0];
// 判断当前时间线,如果在动画的时间,那么返回一个三维数组(三维数组的值全都是X) X 范围是 0-100,对应最终的百分比
if (t < duration)
{
// 如果 t < 0 表达式返回 [100,100,100] 如果 t > duration 表达式返回 [0,0,0]
// 如果 t = duration / 2 ; 表达式返回 [50,50,50],
// 如果 t = duration / 4 ; 表达式返回 [75,75,75],
// 总之就是 小学学过的 y = kx + b 的线性函数
linear(t,0,duration,startVal,endVal);
}
// 如果超出了动画时间,那么就要做一个震动,作为动画的结束,避免突兀
else
{
// amp 代表振幅
amp = (endVal - startVal)/duration;
// 这句话就是小学物理,窝米噶 = 2派 除以 T; T = 1/f f 就是频率
w = freq*Math.PI*2;
// 返回一个修正后的震动值,这个值我们后续再说:
endVal + amp*(Math.sin((t-duration)*w)/Math.exp(decay*(t-duration))/w);
}
linear 函数相当于线性映射的工具,把一个从
[
m
i
n
,
m
a
x
]
[min,max]
[min,max]区间的数字映射到
[
s
t
a
r
t
V
a
l
,
e
n
d
V
a
l
]
[startVal,endVal]
[startVal,endVal]。
l
i
n
e
a
r
(
t
,
m
i
n
,
m
a
x
,
s
t
a
r
t
V
a
l
,
e
n
d
V
a
l
)
=
{
s
t
a
r
t
V
a
l
,
t
≤
0
e
n
d
V
a
l
−
s
t
a
r
t
V
a
l
m
a
x
−
m
i
n
×
(
t
−
m
i
n
)
+
s
t
a
r
t
V
a
l
,
m
i
n
<
t
<
m
a
x
e
n
d
V
a
l
,
t
≥
m
a
x
linear(t,min,max,startVal,endVal)= \left\{
如果说,表达式选择器的数量 这个值我们用
H
(
t
)
H(t)
H(t) 表示,那么就是:
w
=
2
π
T
=
2
π
f
w=\frac{2\pi}{T}=2\pi f
w=T2π=2πf
如果你不理解表达式选择器的数量含义,请看这里:
H
(
t
)
=
{
0
,
t
≤
t
0
100
−
100
d
u
r
a
t
i
o
n
×
(
t
−
t
0
)
,
t
0
<
t
<
d
u
r
a
t
i
o
n
−
100
d
u
r
a
t
i
o
n
×
s
i
n
[
w
(
t
−
d
u
r
a
t
i
o
n
)
]
w
×
e
d
e
c
a
y
×
(
t
−
d
u
r
a
t
i
o
n
)
,
t
≥
d
u
r
a
t
i
o
n
H(t)= \left\{
翻译成人话就是:
这个函数巧妙的地方在于,它完美的让二阶导在临界值的时候保证了连续,我们不妨求导一下:
H
′
(
t
)
=
{
0
,
t
≤
t
0
−
100
d
u
r
a
t
i
o
n
,
t
0
<
t
<
d
u
r
a
t
i
o
n
−
100
d
u
r
a
t
i
o
n
×
w
×
w
⋅
c
o
s
[
w
(
t
−
d
u
r
a
t
i
o
n
)
]
−
s
i
n
[
w
(
t
−
d
u
r
a
t
i
o
n
)
]
d
e
c
a
y
e
d
e
c
a
y
×
(
t
−
d
u
r
a
t
i
o
n
)
,
t
≥
d
u
r
a
t
i
o
n
H^{'}(t)= \left\{
当 t = d u r a t i o n t=duration t=duration 的时候,你会发现第二行的表达式结果完全等于第三行的结果,也就是保证了运动的速度的连续性变化!