参考原文:https://mp.weixin.qq.com/s/wE-fDvJIWTMjv-hXkAq1ig

第四十篇原创文章


[表达式] 有趣又实用的Ae表达式 - 图1

表达式是使用 Extendscript 或 Javascript 语言来控制 AE 图层属性(位置、缩放、旋转、不透明度)的一种编程语言,庆幸的是不用真的精通编程,大部分的表达式用的时候只需修改几个简单的参数,就可实现复杂的效果。每一种表达式都是节省时间,简化工作的好帮手。

表达式用法很简单,按下 alt/option 键,鼠标点击图层属性前面的 “小码表”,然后把代码添加到时间轴里的文本区就可以了。

废话少说,来介绍 10 个常用的 Ae 表达式及其用法,建议收藏。

1.time

常用在旋转属性上,代码:time*value

value 是数值,用在元素的不透明度上,就是由透明到不透明的变化。

例如:time*15,意思就是每秒以 15% 的透明度一直到 100% 不透明。用在旋转属性上,就是每秒以 15° 的角度进行顺时针旋转,如果是 - 15,就是逆时针旋转。

[表达式] 有趣又实用的Ae表达式 - 图2

其实 time 属性也是可以用在位置属性上的,只不过要先把 “位置” 属性先拆分成 X、Y 两个单独的坐标才可以。
思路:
维度2的表达式为[a,b]
例如:[time100,time-200]

2.正弦函数 sin

代码:Math.sin(timevalue1) value2

与 time 不同的是,它多了一个旋转的频率。
value1 = 频率值;value2 = 幅度值

[表达式] 有趣又实用的Ae表达式 - 图3

例如把这行代码Math.sin(time2) 30加在旋转属性上,就是以 30° 的角度来回旋转 2 次, 可以代替手动 K 帧的繁琐。
思路:
怎么PI(3.14怎么输入?)
image.png
频率越来越快:
y=Math.sin(timetime2Math.PIf)*a;
振幅越来越短:
y=Math.sin(time2Math.PIf)a/Math.exp(time*s);

[表达式] 有趣又实用的Ae表达式 - 图5

那怎样让旋转的物体停下来呢?需要在这行正弦函数后面加上一行指数函数:

Math.sin(time value1) value2/Math.exp(time* value)

函数 exp 里面的 time 值越大,就越快停下来。

3.wiggle 抖动

最常用的 “喂狗” 表达式,一般用在 “位置” 属性上,简单写法为:wiggle(value1, value2)

value1为每秒抖动的次数,value2为每次随机波动的幅度。

例如:wiggle(5,20),意思每秒抖动 5 下,每次波动的幅度为 20。

[表达式] 有趣又实用的Ae表达式 - 图6

更完整的写法是:
wiggle(freq, amp, octaves = 1, amp_mult = 0.5, t = time)

freq = 频率(设置每秒抖动的频率);
amp = 振幅(每次抖动的幅度);
octaves = 振幅幅度(在每次振幅的基础上还会进行一定的震幅幅度,很少用);
amp_mult = 频率倍频(默认数值即可,数值越接近 0,细节越少;越接近 1,细节越多);
t = 持续时间(抖动时间为合成时间,一般无需修改);一般只写前两个数值即可。

4.index

可以理解为规律复制表达式,代码:
index*value

例如把 index*15 添加在图层的 “旋转” 属性上,则第一个图层会旋转 15 度,之后按 Ctrl+D 去复制图层时,第 2 个图层将旋转 30 度,第三个图层 45 度,以此类推……

[表达式] 有趣又实用的Ae表达式 - 图7

若想第一层图形不产生旋转保持正常形态,复制后的图形以 15 度递增,表达式这样写:(index-1)*15,“-1” 就是减去第一个图层后其他所有图层以 15° 旋转复制。

5.time 计时

常用于随便变化的数字或倒计时:time.toFixed(2)

括弧里的数字 2 代表小数点后两位,所以 0 就是整数变化。

[表达式] 有趣又实用的Ae表达式 - 图8

数字倒计时: Math.floor(value-time),value 代表从几开始,如:“20-time”,就是从 20 开始倒计时。

6.random 随机

数值变化表达式,所以经常用在数字上,当然也可以用在 “不透明度” 和“缩放”属性上。代码:random(min,max)

min 是最小值,max 最大值

[表达式] 有趣又实用的Ae表达式 - 图9

例如:random(1,100),数字就会在 1-100 间随机变化,它会带 X.xxxxxxxxxx 这样的小数位,如果不想要小数点后面的尾巴,可以这样写:

X=random(1,100);

Math.round(X)

[表达式] 有趣又实用的Ae表达式 - 图10

“X”是你自定义的名字,意思就是给这个 “X” 规定,让它只能在 1-100 之间整数变化。这个效果可用在抽奖游戏里的随机数字。

7.运动脱尾

物体运动时,有类似残影的效果,代码如下:

delay = 5; //number of frames to delay(延迟的距离)

d = delaythisComp.frameDuration(index - 1);

thisComp.layer(1).position.valueAtTime(time - d)

把上述代码添加到运动图层的位置属性里,然后多复制几个图层。

[表达式] 有趣又实用的Ae表达式 - 图11

如想要实现不透明度拖尾,就需要为元素的不透明度属性添加表达式:

opacityFactor = .75;// 不透明度值

Math.pow(opacityFactor,index - 1)*100

8.万能弹性表达式

弹性表达式有两个,OvershootBounce 。可以轻而易举地实现各种弹性动画,如抖动、弹跳动画等。

Keyframe Overshoot

  1. amp = .1;
  2. freq = 2.0;
  3. decay = 2.0;
  4. n = 0;
  5. if (numKeys > 0){
  6. n = nearestKey(time).index;
  7. if (key(n).time > time){n--;}
  8. }
  9. if (n == 0){ t = 0;}
  10. else{t = time - key(n).time;}
  11. if (n > 0){
  12. v = velocityAtTime(key(n).time - thisComp.frameDuration/10);
  13. value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
  14. }
  15. else{value}

*amp表示振幅,freq表示频率,decay表示衰减(根据不同需求做不同的调整)

图片.gif

Keyframe Bounce Back

  1. e = .7;
  2. g = 5000;
  3. nMax = 9;
  4. n = 0;
  5. if (numKeys > 0){
  6. n = nearestKey(time).index;
  7. if (key(n).time > time) n--;
  8. }
  9. if (n > 0){
  10. t = time - key(n).time;
  11. v = -velocityAtTime(key(n).time - .001)*e;
  12. vl = length(v);
  13. if (value instanceof Array){
  14. vu = (vl > 0) ? normalize(v) : [0,0,0];
  15. }else{
  16. vu = (v < 0) ? -1 : 1;
  17. }
  18. tCur = 0;
  19. segDur = 2*vl/g;
  20. tNext = segDur;
  21. nb = 1; // number of bounces
  22. while (tNext < t && nb <= nMax){
  23. vl *= e;
  24. segDur *= e;
  25. tCur = tNext;
  26. tNext += segDur;
  27. nb++
  28. }
  29. if(nb <= nMax){
  30. delta = t - tCur;
  31. value + vu*delta*(vl - g*delta/2);
  32. }else{
  33. value
  34. }
  35. }else value

*e表示衰减,g表示重力,nMax表示弹跳最大值(根据不同需求做不同的调整)

9.loopOut 循环

较常用的循环表达式,常用的类型有 “pingpong” 和 “cycle”,详细规则如下:

  • loopOut(type=“类型”,numkeyframes=0) 对一组动作进行循环
  • loopOut(type=”pingpong”,numkeyframes=0) 是类似像乒乓球一样的来回循环;
  • loopOut(type=”cycle”,numkeyframes=0) 是周而复始的循环;
  • loopOut(type=”continue”) 延续属性变化的最后速度,
  • loopOut(type=”offset”,numkeyframes=0) 是重复指定的时间段进行循环;
  • numkeyframes=0 是循环的次数,0 为无限循环,1 是最后两个关键帧无限循环,2 是最后三个关键帧无限循环

与 loopOut 相对应的是 loopIn,如果说 loopOut 是在最后一个关键帧之后循环,那 loopIn 就是在最后一个关键帧之前做循环。

[表达式] 有趣又实用的Ae表达式 - 图13

loopOutduration 和 loopInduration

这两个里面都有一个 “duration”:

duration = 0 时候一切遵循以上 Out 和 In 的基本解释。

duration = 1,这里分为两种:

第一种,loopInDuration(type = “cycle”, duration = 1)

duration = 1 表示循环该套动作的前 1 秒内(绿色框内 2s-3s) 的动作。

[表达式] 有趣又实用的Ae表达式 - 图14

第二种,loopOutDuration(type = “cycle”, duration = 1)

duration = 1 表示循环该套动作的最后 1 秒内(绿色框内 3s-4s) 的动作。

[表达式] 有趣又实用的Ae表达式 - 图15

10.linear 线性函数

控制器动画,很适合用在一些需要多维联动的动效里。

代码: linear(t,tMin,tMax,value1,value2)

t = 某属性(位置、缩放、不透明度…)线性变化值(tmin 最小,tmax 最大)

value1,value2 代表给当前添加表达式的参数的一维变化。

[表达式] 有趣又实用的Ae表达式 - 图16

如何产生联动呢?

t=(拖动螺旋线指向你想要绑定的那个图层的某个属性,比如 x/y 某一个方向的值)

但是这个只适用于一维上的某一个值,如果同时应用,比如等比缩放属性上怎么办呢?

在 linear 前面加定义的名字,以 “缩放” 为例:

t=(你想要绑定的那个图层的某个属性)

kuan=linear(t,tMin,tMax,value1,value2);

gao=linear(t,tMin,tMax,value1,value2);

[kuan,gao]

以上就是本文要介绍的 10 个常用表达式,当然还有更多,当你掌握越多的 “语法” 就越能理解其中的奥秘。甚至可以尝试自己编写更实用的表达式,随时调用省时省力。

如果觉得对你有帮助不妨 “一键三连” 吧~

动效设计第三次打卡
这一期学到不少,收获满满,设计的过程是一个痛并快乐的过程,做出来不错的效果的时候,感觉所有的坚持都是值得的,真好。
感谢印迹老师的耐心答疑,感谢老师和群里同学们的陪伴,动效设计之路才刚刚开始,大家一起加油!

神秘光晕~~看见好运~~(11/100)