--本篇导航--

如何使用表达式(打开删除,查看图形,错误)

表达式的数组、赋值

输入表达式、优先级

一些常用的表达式(value,time,index,wiggle,random,loopOut,Math,if…else)

表达式控制

一些现成的表达式(可以直接粘贴使用)

如何使用表达式

AE中的表达式通过javascript语句来实现一些效果,比K帧要更高效。

打开表达式

按住Alt的同时点击秒表,可以打开表达式,然后输入内容。

如果有表达式存在时,按Alt点击秒表是删除表达式。也可以直接选中表达式Delete删除。

如果一个图层有表达式,可以连续按下2次E键,快速展开表达式。

不启用/删除表达式

查看表达式图形

默认点击【图表编辑器】图标展示的是关键帧的曲线。

在此基础上,再去点击表达式的波形开关,才会显示出表达式的波形。

有时候在查看其它关键帧曲线时,有其他表达式的曲线,此时,需要去把表达式的曲线显示关掉,就不会干扰了。

表达式错误

如果表达式有错误,AE会检测出来,并提示错误代码的位置。只有无错了,表达式才可以生效。

表达式的数组、赋值

表达式是代码,会有数据结构。

赋值

默认输入就等于属性的值,不需要a=1这种等于(需要注意数据结构要一致)。可以将值或一个表达式赋值给一个变量:var=1;

数据结构

默认一维的数,就是普通的写法。如非3D下的旋转属性。

二维的数,如非3D下的旋转、位置属性。

三维的数,以此类推,就是[var[0],var[1],var[2]]

文字也可以强制设为表达式,是字符串类型。需要用双引号 " " 括起来。

输入表达式

AE中可以手动输入表达式,也可以使用菜单添加。

添加后,有些需要自己手动填写如数值,有些可以直接使用螺旋线去链接已有属性或新建的表达式滑块属性。

表达式关联器,可以跨合成进行连接,也可以跨图层连接不同效果器的属性,还可以连接到某一个属性的不同值,如位置的x,y,z。此时需要锁住目标图层效果器面板,以便拉螺旋线。

有时一些属性值是多维数组,如果只想关联其中某一维度,可以单独出属性值。

优先级

表达式的优先级是最高的。

一些常用的表达式

value

表示当前属性的值,根据属性的维数而定。如一维的旋转,value就是一维的,二维的位置,value就是二维的

value = [value[0],value[1]]

可以加在任何表达式的后面,这样表达式就可以随意修改数值了。

当value为数组时,可以直接和数组形式的表达式相加:

value+[index+200,0];

时间表达式 time

time是1秒,与合成的时间轴长度是一一对应的。后面乘的数值可以看作是换算的旋转度数秒:time*6 (秒针1圈360度,1秒的度数为360/60=6度)分:time*6/60 = time/10时:time*6/60/12

索引表达式 index

获取当前图层在时间轴上的序列号。

抖动表达式 wiggle(freq,amp)

freq:抖动频率/秒amp:抖动幅度(像素)wiggle(freq,amp)是二维数组,默认情况是会影响所有的数组的值,因此获取单个影响值可以使用数组的方式

wiggle(freq,amp)[0],wiggle(freq,amp)[1]

也可以直接使用AE的预设【摆动-位置】来实现

随机表达式 random(m,n)

m:最小边界值n:最大边界值

虽然每个随机表达式的值都是不一样的,但如果想更随机,可以使用seedRandom(随机种子,0/1);随机种子可以写成index,time等false=0 随时间变化而变化true=1 不随时间变化而变化

循环表达式loopOut

是作用在关键帧上的,所以需要先有关键帧,之后再循环关键帧的动画。

loopOut("Cycle") 重头开始循环 A→B,A→B

loopOut("Continue") 在末尾沿着路径一直运动下去

loopOut("PingPong") 往复循环 A→B→A→B 如钟摆

loopOut("Offset") 这一次结束的位置成为下一次运动的起始位置

直接循环属性上的关键帧,循环尽量保持首尾的关键帧数值一致

数学表达式

Math.floor(x),对x向下取整Math.round(x),对x向上取整,也就是四舍五入

Math.sin()往往会与翅膀等运动规律按正弦曲线的动画中使用。数学里的π的表达:Math.PI

给旋转K帧(绕锚点旋转):

Math.sin(time*freq)*angle; // freq是旋转频率,angle是旋转角度

保留小数的位数.value.toFixed(n)

effect("滑块控制")("滑块").value.toFixed(0)

if条件表达式

就是if…else的那些

time = 15;

if (time <= 10) {

"早上好";

} else if (time <= 14) {

"中午好";

} else if (time <= 18) {

"下午好";

} else {

"晚上好";

}

判断可更复杂点

if (2 < time && time < 4) {

90;

} else {

0;

}

表达式控制

属于效果,都是将图层表达式中的一些数链接到表达式控制的滑块(某一个)数值上。

一些现成的表达式

随机循环移动

给位置加表达式

freq = 2; //频率

amp = 500; //振幅

loopTime =3; //循环时间,单位位秒

t = time % loopTime;

wiggle1 = wiggle(freq, amp, 1, 0.5, t);

wiggle2 = wiggle(freq, amp, 1, 0.5, t - loopTime);

linear(t, 0, loopTime, wiggle1, wiggle2)

路径循环表达式

valueAtTime(time%key(numKeys).time)

朝向跟随表达式

function lookAtMe(fromPt, toPt){

lkAt = lookAt(fromPt, toPt);

if(toPt[1] > fromPt[1]){

return 180-lkAt[1];

}else{

return lkAt[1];

}

}

p0 = transform.position;

p1 = thisComp.layer("圆形").transform.position; // 设置目标层名

lookAtMe(p0,p1)+value; // 改变旋转值可调整角度改变

弹性表达式

想要表达式正常工作,就要给最后一个关键帧一个速度值,最后一个关键帧的速度值将会很大程度的影响表达式的抖动效果。当感觉抖动效果不明显时,也可以试试改变一下关键帧速率。最后一帧的速度越大抖动效果越明显。

弹力1

amp=0.1;

freq=2;

decay=2;

n=numKeys;

if(n==0){value;}

else{

t=time-key(n).time;

if (n > 0){

v = velocityAtTime(key(n).time - thisComp.frameDuration/10);

value+v*amp*Math.sin(freq*2*Math.PI*t)/Math.exp(decay*t);

}

else{value};

}

弹力2

amp = 0.4;//幅度

freq = 2.0;// 频率,值越高, 晃地越快

decay = 5.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;

}

【通过控制滑块控制参数】

amp = effect("amp")("滑块");//幅度

freq = effect("freq")("滑块");// 值越高, 频率越高

decay = effect("decay")("滑块");// 值越高, 延迟越小

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;

}

弹力3(惯性回弹)

在要设置动画的图层的位置属性中添加关键帧。在该图层的位置属性中添加以下表达式:

// 设置值以控制抖动。

// 将这些值链接到滑块表达式控件以快速预览不同的设置。

var amp = 40;

var freq = 30;

var decay = 50;

// 查找最新的关键帧

var nK = nearestKey(time);

var n = (nK.time <= time) ?nK.index : --nK.index;

var t = (n === 0) ?0 : time - key(n).time;

// 如果当前时间晚于一个关键帧,则计算抖动。

// 反之,则使用原始值。

if ( n > 0 && t < 1 ) {

var v = velocityAtTime( key( n ).time - thisComp.frameDuration /10 );

value + v * amp * .001 * Math.sin(freq * .1 * t * 2 * Math.PI) / Math.exp(decay * .1 * t);

} else {

value;

}

Overshoot(果冻抖动的效果)

freq = 3;

decay = 5;

n = 0;

if (numKeys > 0){

n = nearestKey(time).index;

if (key(n).time > time)

n--;

}

if (n > 0){

t = time - key(n).time;

amp = velocityAtTime(key(n).time - .001);

w = freq*Math.PI*2;

value + amp*(Math.sin(t*w)/Math.exp(decay*t)/w);

}

else

value

Bounce(小球重力下降弹跳)

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){

vu = (vl > 0) ? normalize(v) : [0,0,0];

}

else{

vu = (v < 0) ? -1 : 1;

}

tCur = 0;

segDur = 2*vl/g;

tNext = segDur;

nb = 1; // number of bounces

while (tNext < t && nb <= nMax){

vl *= e;

segDur *= e;

tCur = tNext;

tNext += segDur;

nb++

}

if(nb <= nMax){

delta = t - tCur;

value + vu*delta*(vl - g*delta/2);

}

else{

value

}

}

else

value