1. 一维数值指数变化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 if (numKeys >1 && key (numKeys).time > time && key (1 ).time <= time){ k = nearestKey (time).index ; if (key (k).time <= time) { a = k; } else { a = k-1 ; } b= a+1 ; a_val = key (a)[0 ]; b_val = key (b)[0 ]; a_time = key (a).time ; b_time = key (b).time ; if (a_val == 0 ) { a_val = .1 ; } if (b_val == 0 ) { b_val = .1 ; } x = Math .log (b_val) / Math .log (a_val); exp = linear (time, a_time, b_time, 1 , x); val = Math .pow (a_val, exp); [val]; }else { value; }
只能适用于一维数,需要变化的数值区间必须要大,时间要长,否则看不到效果
2. cycle映射 1 valueAtTime (time%key (numKeys).time )
cycle “pingpong”映射
1 2 t=(time%(2 *key (numKeys).time )>=key (numKeys).time )?(key (numKeys).time -time%key (numKeys).time ):(time%key (numKeys).time ); valueAtTime (t);
AE中的路径动画无法使用循环表达式,使用这个来实现路径动画的循环
3.位移路径生成形状 1 2 3 4 5 6 7 8 9 10 finalPoint = []; frameDuration = thisComp.frameDuration ; compDuration = thisComp.duration ; chosenOne = thisComp.layer ("the layer name which you want to choose" ).transform .position ; for (i=0 ;i<=compDuration/frameDuration;i++){ middlePoint = chosenOne.valueAtTime (i*frameDuration); finalPoint.push (middlePoint); } createPath (points = finalPoint, inTangents = [], outTangents = [], isClosed = false );
注意
这个表达式需要放在形状层Path里面,这个Path一般只有描边没有填充
需要设置形状层的位置和锚点与目标层的位置相吻合
这个表达式很容易造成卡顿
4.循环摆动 1 2 3 4 5 6 7 8 9 freq=5 ; amp=100 ; octaves=1 ; amp_mult=0.5 ; loopTime=2 ; t=time%loopTime; wiggle1=wiggle (freq,amp,octaves,amp_mult,t); wiggle2=wiggle (freq,amp,octaves,amp_mult,t-loopTime); linear (t,0 ,loopTime,wiggle1,wiggle2);
返回的是wiggle,所以可以用于多维,可以让wiggle重复
5. 颜色随机 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 h = effect (1 )(1 ); s = effect (2 )(1 ); l = effect (3 )(1 ); freq = effect (4 )(1 ); seed = effect (5 )(1 ); seedRandom (seed,true );H = wiggle (freq,h)[1 ]; S = wiggle (freq,s)[1 ]; L = wiggle (freq,l)[1 ]; var plusOrMinus1 = random ()<0.5 ?-1 :1 ;var plusOrMinus2 = random ()<0.5 ?-1 :1 ;hsl = rgbToHsl (value); hslToRgb (hsl + [H/360 *plusOrMinus1,S/100 *plusOrMinus2,-L/200 ,1 ])
这个表达式是用在颜色属性上的,拥有颜色属性的图层要添加五个表达式控制滑块
6. 指向目标层 1 2 3 4 lookedLayer = thisComp.layer ("lookedLayer" ); myLayer = thisLayer; differencePosition = lookedLayer.transform .position .value - myLayer.transform .position .value ; radiansToDegrees (Math .atan2 (differencePosition[1 ],differencePosition[0 ]))+90 ;
这个表达式用在需要指向的图层的旋转属性上,然后填写一个被指向的图层名称
7. 弹性动画 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 amp = 0.1 ; freq = 2.0 ; decay = 2.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;}
经典弹性动画
8.反弹 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 elasticity =0.7 ; gravity =1000 ; 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 ; velocityValue = -velocityAtTime (key (n).time - thisComp.frameDuration /100 )*elasticity; velocityLength = length (velocityValue); if (value instanceof Array ){ vu = (velocityLength > 0 ) ? normalize (velocityValue) : [0 ,0 ,0 ]; } else {vu = (velocityValue < 0 ) ? -1 : 1 ;} tCur = 0 ; segDur = 2 *velocityLength/gravity; tNext = segDur; bouncesNumber = 1 ; while (tNext < t && bouncesNumber <= nMax){ velocityLength *= elasticity; segDur *= elasticity; tCur = tNext; tNext += segDur; bouncesNumber++; } if (bouncesNumber <= nMax){ delta = t - tCur; value + vu*delta*(velocityLength - gravity*delta/2 ); } else {value;} } else value;
模拟重力反弹效果,当然方向随意,一般也是用在位置上
9.弹性晃动 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 var amp = 2.0 ; var freq = 2.0 ; var decay = 4.0 ; var maxRotation = 45 ;var maxSpeed = 3000 ;var useAxis = 0 ; var timeBeforeKey = thisComp.frameDuration /10 ;var referencePropoty = position;plusorminus = 1 ; if (referencePropoty.velocity [useAxis] != 0 ) { linear (referencePropoty.velocity [useAxis], -maxSpeed,maxSpeed, -plusorminus*maxRotation,plusorminus*maxRotation); } else { var n = 0 ; if (referencePropoty.numKeys > 0 ) { n = referencePropoty.nearestKey (time).index ; if (referencePropoty.key (n).time > time) {n--;} } if (n == 0 ) {t = 0 ;} else {t = time - referencePropoty.key (n).time ;} if (n > 0 && t < 1 ) { var v = referencePropoty.velocityAtTime (referencePropoty.key (n).time - timeBeforeKey)[useAxis]; value -plusorminus* (v*(amp/100 )*Math .sin (freq*t*2 *Math .PI )/Math .exp (decay*t)); } else {value;} }
用在旋转属性上,只能本图层的位置变化才能响应,链接到父级没用
10.四方抖动 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 angle = degreesToRadians (45 ); shakeLength = 100 ; num = 5 ; mode = 0 ; modeCase = []; if (mode==0 ){modeCase=[0 ,1 ,2 ,3 ];}if (mode==1 ){modeCase=[3 ,2 ,1 ,0 ];}if (mode==2 ){modeCase=[0 ,2 ,1 ,3 ];}if (mode==3 ){modeCase=[0 ,2 ,3 ,1 ];}thisDuration = thisComp.frameDuration ; if (thisLayer.marker .numKeys ==0 ){newTime=time;}else { markerTime = thisLayer.marker .key (1 ).time ; newTime = time - markerTime; } shakeRatio = 1 - Math .floor (newTime/4 /thisDuration)/num; var plus0 = plus1 = shakeCase = 0 ;var shakeCase = Math .round ((newTime/thisDuration)%4 );if (shakeCase==modeCase[0 ]){plus0=-1 ;plus1=-1 ;}if (shakeCase==modeCase[1 ]){plus0=-1 ;plus1=1 ;}if (shakeCase==modeCase[2 ]){plus0=1 ;plus1=1 ;}if (shakeCase==modeCase[3 ]){plus0=1 ;plus1=-1 ;}if (newTime>=4 *num*thisDuration||newTime<0 ){value;}else {value + [shakeLength*shakeRatio*Math .sin (angle)*plus0,shakeLength*shakeRatio*Math .cos (angle)*plus1]; }
将物体从四个方向抖动到中间,用在位置属性上,angle指的是每次抖动物体偏移的角度增量,num指抖动次数,mode指抖动模式