小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
效果图
设计部分
首先添加文字,并为该文字设置了三个关键帧位置,如下所示
同时还通过 F9 增加了缓动效果
然后在位置属性上应用如下表达式
表达式与详解
具体请看代码注释
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) {
/// @note vl 如果大于 0 的话就对向量 v 进行归一化
vu = (vl > 0) ? normalize(v) : [0, 0, 0];
} else {
vu = (v < 0) ? -1 : 1;
}
/// @note 根据每个衰减阶段,计算衰减时间和跳跃次数
tCur = 0;
segDur = 2 * vl / g;
tNext = segDur;
nb = 1; // 跳跃次数
while (tNext < t && nb <= nMax) {
/// @note 衰减
vl *= e;
segDur *= e;
/// @note 更新衰减时间和跳跃次数
tCur = tNext;
tNext += segDur;
nb++
}
if (nb <= nMax) {
delta = t - tCur; ///< 计算剩余时间
/// @note 加号的右半部分的函数示意图其实就是个(倒)抛物线
value + vu * delta * (vl - g * delta / 2);
} else {
value
}
} else
value
改进与优化
为了增加趣味性,还可以加一点尺寸上拉伸的效果
将以下表达式应用在缩放属性上即可。
freq = 3;
amplitude = 20;
decay = 1.0;
t = time - inPoint;
x = scale[0] + amplitude*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
y = (1/x)*10000;
[x,y]