Adobe After Effects(AE)是影视后期、动态图形和视觉效果的核心工具。多数特效师依赖关键帧手工动画,而技术型特效工程师则通过 表达式(Expression) 与 ExtendScript 脚本 实现参数化控制、批量处理和自动化工作流,大幅提升效率并实现手工难以企及的复杂效果。本文从实战出发,覆盖 表达式驱动物理动画、脚本自动化合成 以及 基于数据的动态图表生成,提供完整代码,助你从“手动师”进阶为“代码驱动”的特效工程师。
表达式基于 JavaScript 语法,可控制图层的任何属性。我们以 弹性缓动(Spring) 和 无关键帧随机运动 为例。
当图层需模拟弹簧效果(如弹窗弹出),传统方法需数十个关键帧。而表达式通过物理公式自动计算:
// 位置弹性表达式(附加在位置属性)
freq = 2.5; // 振荡频率(Hz)
decay = 1.8; // 衰减系数
amplitude = 100; // 初始振幅(像素)
t = time - inPoint; // 从图层入点开始
if (t < 0) t = 0;
// 带阻尼的弹簧模型(位移 = 振幅 * sin(2π*freq*t) * exp(-decay*t))
offset = amplitude * Math.sin(2 * Math.PI * freq * t) * Math.exp(-decay * t);
value + [0, offset] // 在 Y 轴方向弹性运动该表达式让图层在 Y 方向自动振荡并衰减,无需任何关键帧,且可实时调整参数。
// 位置随机游走,适用于摄像机晃动或粒子随机偏移
seed = 12345; // 随机种子,确保可复现
seedRandom(seed, timeless = true);
freq = 0.8; // 随机变化频率(次/秒)
amp = 50; // 随机振幅
t = time * freq;
offsetX = noise(t) * amp - amp/2;
offsetY = noise(t + 100) * amp - amp/2;
value + [offsetX, offsetY];noise() 是 AE 内置的 Perlin 噪声函数,产生平滑随机值,配合不同相位实现二维随机漂移。
ExtendScript 是 AE 的自动化脚本语言(基于 ECMA-262),可操作项目、合成、图层和属性。以下脚本实现 从 CSV 数据批量创建文字图层并设置动画,常用于数据可视化或体育赛事信息板。
// 批量生成合成.jsx
#target aftereffects
var csvFile = File("~/Desktop/data.csv");
csvFile.open("r");
var lines = csvFile.read().split("\n");
csvFile.close();
var compWidth = 1920;
var compHeight = 1080;
var frameRate = 30;
var duration = 5; // 秒
for (var i = 1; i < lines.length; i++) { // 跳过表头
var parts = lines[i].split(",");
if (parts.length < 3) continue;
var name = parts[0];
var score = parseInt(parts[1]);
var rank = parseInt(parts[2]);
// 创建合成
var comp = app.project.items.addComp(name + "_Rank" + rank, compWidth, compHeight, 1, duration, frameRate);
comp.openInViewer();
// 创建背景图层(纯色)
var bg = comp.layers.addSolid([0.2, 0.2, 0.3], "Background", compWidth, compHeight, 1);
bg.moveToBeginning();
// 创建文字图层(名字)
var txtLayer = comp.layers.addText(name);
var txtDoc = txtLayer.property("Source Text").value;
txtDoc.fontSize = 120;
txtDoc.fillColor = [1, 1, 1];
txtDoc.font = "Arial Bold";
txtLayer.property("Source Text").setValue(txtDoc);
// 位置居中(X 轴居中,Y 轴随排名变化)
var yPos = 400 + rank * 80;
txtLayer.property("Position").setValue([compWidth/2, yPos]);
// 添加缩放动画(从 0 到 100% 弹性)
var scaleProp = txtLayer.property("Scale");
// 在 0 秒设关键帧为 [0,0]
scaleProp.setValueAtTime(0, [0, 0]);
// 在 1 秒设关键帧为 [120,120](过冲)
scaleProp.setValueAtTime(1, [120, 120]);
// 在 1.5 秒设关键帧为 [100,100]
scaleProp.setValueAtTime(1.5, [100, 100]);
// 应用缓动(Easy Ease)
var key1 = scaleProp.keyframe(1);
key1.easeOut = [0.2, 0.8];
var key2 = scaleProp.keyframe(2);
key2.easeIn = [0.8, 0.2];
}该脚本自动为每行数据生成独立合成,包含背景和动态缩放文字,适用于排行榜类视频批量制作。
结合 AE 的路径属性,可生成动态数据曲线。脚本通过贝塞尔曲线连接数据点,并添加进度动画。
// 在形状图层上创建路径(数据点)
function createChart(dataPoints, comp) {
var shapeLayer = comp.layers.addShape();
var shapeGroup = shapeLayer.property("ADBE Root Vectors Group");
var pathGroup = shapeGroup.addProperty("ADBE Vector Shape - Group");
var pathProp = pathGroup.property("ADBE Vector Shape");
var points = [];
var spacing = comp.width / (dataPoints.length - 1);
var baseY = comp.height * 0.8;
var scaleY = comp.height * 0.6;
for (var i = 0; i < dataPoints.length; i++) {
var x = i * spacing;
var y = baseY - dataPoints[i] / 100 * scaleY;
points.push([x, y]);
}
// 构建贝塞尔路径(使用 Catmull-Rom 插值平滑)
var vertices = [];
var inTangents = [];
var outTangents = [];
for (var i = 0; i < points.length; i++) {
vertices.push(points[i]);
// 切线计算(简化)
if (i === 0) {
inTangents.push([0, 0]);
outTangents.push([(points[1][0]-points[0][0])/3, (points[1][1]-points[0][1])/3]);
} else if (i === points.length-1) {
inTangents.push([(points[i][0]-points[i-1][0])/3, (points[i][1]-points[i-1][1])/3]);
outTangents.push([0, 0]);
} else {
var dx = points[i+1][0] - points[i-1][0];
var dy = points[i+1][1] - points[i-1][1];
inTangents.push([-dx/6, -dy/6]);
outTangents.push([dx/6, dy/6]);
}
}
var pathValue = pathProp.value;
pathValue.vertices = vertices;
pathValue.inTangents = inTangents;
pathValue.outTangents = outTangents;
pathValue.closed = false;
pathProp.setValue(pathValue);
// 添加描边
var stroke = shapeGroup.addProperty("ADBE Vector Stroke - Group");
stroke.property("ADBE Vector Stroke Color").setValue([1, 0.5, 0]);
stroke.property("ADBE Vector Stroke Width").setValue(4);
// 添加路径修剪(Trim Paths)实现绘制动画
var trim = shapeGroup.addProperty("ADBE Vector Trim - Group");
trim.property("ADBE Vector Trim End").setValueAtTime(0, 0);
trim.property("ADBE Vector Trim End").setValueAtTime(2, 100);
}脚本可批量将合成添加到渲染队列,输出预设格式,实现夜间批量渲染。
function renderComp(comp, outputPath) {
var renderQueue = app.project.renderQueue;
var item = renderQueue.items.add(comp);
item.outputModule(1).file = new File(outputPath);
item.outputModule(1).applyTemplate("H.264 - 1080p 30");
item.render = true;
}
// 遍历所有合成,调用 renderCompconsole.log() 在表达式控制台输出(需启用 Enable JavaScript Debugger)。$.writeln() 输出到 ExtendScript Toolkit 控制台。value(会触发重算),优先使用 thisLayer 属性缓存。AE 的表达式和脚本将特效制作从“手工绘画”提升到“程序生成”的层次。本文提供的弹性运动、随机噪声、批量合成生成和数据图表绘制代码,均可直接应用到实际项目中。技术型特效工程师应熟练运用这些工具,将重复劳动自动化,把创造力释放到更复杂的视觉设计上。建议你从修改示例参数开始,逐步尝试将外部 API(如实时天气数据)接入 AE,打造真正的数据驱动动态图形。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。