•图层添加反弹效果

将下方表达式,复制粘贴到任何具有关键帧动画的属性上。

e = .3; // 弹力
g = 1; // 重力
nMax = 10; // 最大反弹次数
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*1000);
tNext = segDur;
nb = 1;
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*1000)*delta/2);
}else{
value
}
}else
value
•可以在运动停止的时候,增加一些弹性效果

将下方表达式,复制粘贴到任何具有关键帧动画的属性上。

amp = .04;//幅度
freq = 2;// 值越高, 频率越高
decay = 5;// 值越高, 延迟越小
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;
}
•为物体的缩放属性添加此表达式,让形态产生一些弹性效果

将下方表达式,复制粘贴到缩放属性上。

kaishi = 5;//开始时间
maxDev = 20; //最大形变大小
spd = 30; //速度
decay = 1; //静止快慢
guodu = 0.2;
t = time - kaishi;
x1 = value[0];
y1 = value[1];
x2 = value[0] + maxDev*Math.sin(spd*t)/Math.exp(decay*t);
y2 = value[0]*value[1]/x2;
if(time>kaishi){
[easeIn(time, kaishi, kaishi+guodu, x1, x2), easeIn(time, kaishi, kaishi+guodu, y1, y2)]
}else{[x1,y1]};
•控制wiggle表达式的作用区间,此表达式原理可以运用于控制任何表达式的作用区间

将下方表达式,复制粘贴到任何属性上

kaishi = 2;//开始时间
jieshu = 5;//结束时间
guodu = 1;//过渡时间
pinlv = 1.5;//摆动频率
fudu = 300;//摆动幅度
x1 = value[0];
x2 = wiggle(pinlv , fudu)[0];
y1 = value[1];
y2 = wiggle(pinlv , fudu)[1];
if(time<jieshu-guodu){
[easeIn(time, kaishi, kaishi+guodu, x1, x2), easeIn(time, kaishi, kaishi+guodu, y1, y2)]
}else{
[easeIn(time, jieshu, jieshu-guodu, x2,x1 ), easeIn(time,jieshu, jieshu-guodu, y2, y1)]
};
•对随机效果wiggle进行循环

将下方表达式,复制粘贴到任何想要添加随机效果的属性上。

freq = 1; // 频率 amp = 110; // 幅度 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)
•让对象的旋转始终朝向运动方向

将下方表达式,复制粘贴到旋转属性上。同时确保位置属性有关键帧动画,才会看到效果

try{
cornerEase = 3;// 角度松弛
p = transform.position;
t = Math.min(Math.max(time,p.key(1).time+.001),p.key(p.numKeys).time);
pre = position.valueAtTime(t-thisComp.frameDuration*cornerEase);
post = position.valueAtTime(t+thisComp.frameDuration*cornerEase);
delta = post-pre;
orient = radiansToDegrees(Math.atan2(delta[0],-delta[1]));
value+orient+180;// 180可调整转动角度
}catch(err){value}
•让图层旋转方向永远朝向某个对象

将下方表达式,复制粘贴到旋转属性上。同时修改 //目标点位置标注行表达式为你所需设定的目标点位置

function lookAtMe(fromPt, toPt){
lkAt = lookAt(fromPt, toPt);
if (toPt[1] > fromPt[1]){
return 180-lkAt[1];
} else {
return lkAt[1];
}
}
p0= transform.position; //look from point
p1=thisComp.layer("空 2").transform.position; //目标点位置
lookAtMe(p0, p1)+0 //0数值可调整旋转角度
•解决loopOUT表达式不能循环路径关键帧,使用此表达式即可循环路径,也可循环任何属性关键帧

将下方表达式,复制粘贴到任何想要循环的关键帧属性上。即使包括路径关键帧

try{
timeStart = thisProperty.key(1).time;
duration = thisProperty.key(thisProperty.numKeys).time-timeStart;
pingPong = false; //此处可将false改为true,则是来回反弹的循环模式
quant=Math.floor((time-timeStart)/duration);
if(quant<0) quant = 0
if(quant%2 == 1 && pingPong == true){ t = 2*timeStart+ (quant+1)*duration - time;
}
else{
t = time-quant*duration;
}
}
catch(err){
t = time;
}
thisProperty.valueAtTime(t)
•生成随时间播放的计时器

将下方表达式,复制粘贴到文本图层的源文本属性上

rate=1;// 速率
clockStart=0;// 开始时间点
function minZero(n){
if(n<10)return"0"+n
else
return""+n
};
function secZero(n){
if(n<10)return"0"+n
else
return""+n
};
clockTime=Math.max(clockStart+rate*(time-inPoint),0);
t=Math.floor(clockTime);
min=Math.floor((t%3600)/60);
sec=Math.floor(t%60);
minZero(min)+":"+secZero(sec)
•生成随意跳动的乱码文本效果

将下方表达式,复制粘贴到文本图层的源文本属性上

posterizeTime(10);//可改频率数值10,也可链接滑块控制
var probability = 60 / 100;//文字改变幅度,默认60%,可修改60数值。也可以连接滑块控制
var characters = ["░","▒","▓","<",">","/"];//乱码符号,可修改双引号里面的乱码符号
var textLines = value.split("\r");
var numTextLines = textLines.length;
for (var l = 0; l < numTextLines; l++) {
var oldLine = textLines[l];
var newLine = getNewLine(oldLine);
textLines[l] = newLine;
}
function getNewLine (oldLine) {
var newLine = "";
for (var i = 0; i < oldLine.length; i++) {
if (random() <= probability) {
newLine += getRandomCharacter(characters);
} else {
newLine += oldLine.charAt(i);
}
}
return newLine;
}
function getRandomCharacter (a) {
return a[Math.floor(random() * a.length)];
}
textLines.join("\r");
•随位置移动而产生摆动效果

将下方表达式,复制粘贴到图层的旋转属性,并为图层位置添加关键帧

let amp = 2.0; //晃动幅度
let freq = 2.0; //晃动速度
let decay = 4.0; //晃动时间
let rotateOnMovement = 42; //最大角度
let useAxis = 0; // 设置为0择使用X轴速度,1则使用Y轴速度
let timeBeforeKey = thisComp.frameDuration/10;
let refValue = position;
if (refValue.velocity[useAxis] != 0) {
linear(refValue.velocity[useAxis], -3000, 3000, -rotateOnMovement, rotateOnMovement);
} else {
let n = 0;
if (refValue.numKeys > 0) {
n = refValue.nearestKey(time).index;
if (refValue.key(n).time > time) { n--; }
}
if (n == 0) {
t = 0;
} else {
t = time - refValue.key(n).time;
}
if (n > 0 && t < 1) {
let v = refValue.velocityAtTime(refValue.key(n).time - timeBeforeKey)[useAxis];
value - (v*(amp/100)*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t));
} else {
value;
}
}
•快速为文本添加电脑输入打字的效果

将下方表达式,复制粘贴到文本图层的源文本属性上。

var blinkControl = Math.sin(time*Math.PI*5);//闪烁速度,可提高数值5来加快光标闪烁速度
var inTime = 1;//开始时间
var outTime = 2;//结束时间
var animTime = linear(time, inTime, outTime, 0, text.sourceText.length);
var animation = text.sourceText.slice(0, animTime);
if (time <= inTime) {
(blinkControl < 0)? "|" : "";
} else {
(time < outTime)? animation+"|" : animation;
}
•快速创建可控卷曲样条
numsegments = Math.max(2, Math.floor(effect(1)(1)));
totallength = Math.max(0.001, effect(2)(1));
seglength = totallength / numsegments;
sepdist = Math.max(0.001, effect(3)(1) * 0.5) / (Math.PI * 2);
roll = clamp(effect(4)(1)/100, 0, 1);
pos = [0, 0];
cv = [];
firsttheta = Math.sqrt(numsegments * seglength / sepdist);
f = numsegments;
for(i=0; i<numsegments; i++)
{
u = (i - 1) / numsegments;
u = linear(u, roll, 1, 0, numsegments);
f -= clamp(u, 0, 1);
theta = Math.sqrt(f * seglength / sepdist);
theta -= firsttheta;
if(i != 0)
{
x = Math.cos(theta) * seglength;
y = Math.sin(theta) * seglength;
pos += [x, y];
}
cv.push(pos);
}
createPath(cv, [], [], false);
