大家好啊,这里是 AdoreLowen。众所周知(心虚),使用 After Effects 时,在时间轴面板左侧的“合成选项”下,可以分别调整图层上各效果的不透明度。但是,展开时间轴面板的这个部分十分麻烦,AE 也没有提供快捷键来方便地调出这个参数。而且许多时候,我们只是想要给某个效果的可见性打上关键帧,这样一来操作就十分麻烦。

所以,我制作了这个简单的脚本,可以把“效果不透明度”参数绑定到滑块控制或复选框控制,同时提供了分开控制和统一控制两种选项。这样一来,调整效果的不透明度就很方便了。推荐将脚本绑定到快捷键,或者放置到 KBar / Motion Tools Pro 中使用。



是啊,很简单的脚本,只是用来水小站申请的,但是我觉得还是挺有用的(逃)。代码在下面,可以直接复制到扩展,或者自行存为 .jsx 使用。
(function(thisObj) {
function buildUI(obj) {
var w = (obj instanceof Panel) ? obj : new Window("palette", "效果不透明度控制器", undefined, {resizeable: true});
w.orientation = "column";
w.alignChildren = ["fill", "top"];
w.spacing = 10;
w.margins = 15;
var pType = w.add("panel", undefined, "控制器类型");
pType.orientation = "row";
pType.alignChildren = ["left", "center"];
pType.margins = 15;
pType.add("radiobutton", undefined, "滑块控制 (0-100%)").value = true;
var rCb = pType.add("radiobutton", undefined, "复选框开关 (0或100%)");
var pMode = w.add("panel", undefined, "多选绑定模式");
pMode.orientation = "row";
pMode.alignChildren = ["left", "center"];
pMode.margins = 15;
pMode.add("radiobutton", undefined, "分别生成控制").value = true;
var rMaster = pMode.add("radiobutton", undefined, "生成统一主控");
var btn = w.add("button", undefined, "执行绑定");
btn.preferredSize.height = 35;
btn.onClick = function() {
app.beginUndoGroup("生成不透明度控制");
var isSuccess = false;
try {
isSuccess = apply(rCb.value, rMaster.value);
}
catch (e) { alert("发生错误:\n" + e.toString() + "\n(行: " + e.line + ")"); }
finally { app.endUndoGroup(); }
if (isSuccess && (w instanceof Window)) {
w.close();
}
};
w.onResizing = w.onResize = function() { this.layout.resize(); };
return w;
}
function apply(isCb, isMaster) {
var comp = app.project.activeItem;
if (!comp || !(comp instanceof CompItem)) {
alert("执行中止:请先打开一个合成。");
return false;
}
var layers = comp.selectedLayers;
if (!layers.length) {
alert("执行中止:未选中任何图层。");
return false;
}
var success = 0, errs = [], total = 0;
var sParade = "ADBE Effect Parade", sBuiltIn = "ADBE Effect Built In Params", sOpac = "ADBE Effect Mask Opacity";
for (var i = 0; i < layers.length; i++) {
var lr = layers[i], props = lr.selectedProperties, tIdx = [];
for (var j = 0; j < props.length; j++) {
var p = props[j];
while (p && p.parentProperty && p.parentProperty.matchName !== sParade) p = p.parentProperty;
if (p && p.parentProperty && p.parentProperty.matchName === sParade) {
var idx = p.propertyIndex, dup = false;
for (var k = 0; k < tIdx.length; k++) if (tIdx[k] === idx) dup = true;
if (!dup) { tIdx.push(idx); total++; }
}
}
if (!tIdx.length) continue;
var newIdx = [], cName = isCb ? "ADBE Checkbox Control" : "ADBE Slider Control";
if (isMaster) {
var vIdx = [];
for (var m = 0; m < tIdx.length; m++) {
var bIn = lr.property(sParade).property(tIdx[m]).property(sBuiltIn);
if (bIn && bIn.property(sOpac)) vIdx.push(tIdx[m]);
}
if (vIdx.length) {
var mIdx = lr.property(sParade).addProperty(cName).propertyIndex;
newIdx.push(mIdx);
lr.property(sParade).property(mIdx).name = "主控 不透明度 (" + vIdx.length + "个)";
lr.property(sParade).property(mIdx).property(1).setValue(isCb ? 1 : 100);
var safeName = lr.property(sParade).property(mIdx).name.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
var exp = isCb ? 'effect("' + safeName + '")(1) == 1 ? 100 : 0;' : 'effect("' + safeName + '")(1);';
for (var v = 0; v < vIdx.length; v++) {
lr.property(sParade).property(vIdx[v]).property(sBuiltIn).property(sOpac).expression = exp;
success++;
}
}
} else {
for (var n = 0; n < tIdx.length; n++) {
var efx = lr.property(sParade).property(tIdx[n]);
var bIn = efx.property(sBuiltIn);
if (!bIn) { errs.push("'" + efx.name + "':无合成选项"); continue; }
var opac = bIn.property(sOpac);
if (!opac) { errs.push("'" + efx.name + "':无不透明度属性"); continue; }
var orig = opac.value !== undefined ? opac.value : 100;
var eName = efx.name;
var cIdx = lr.property(sParade).addProperty(cName).propertyIndex;
newIdx.push(cIdx);
lr.property(sParade).property(cIdx).name = eName + " 不透明度";
lr.property(sParade).property(cIdx).property(1).setValue(isCb ? (orig > 50 ? 1 : 0) : orig);
var safeName = lr.property(sParade).property(cIdx).name.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
var exp = isCb ? 'effect("' + safeName + '")(1) == 1 ? 100 : 0;' : 'effect("' + safeName + '")(1);';
lr.property(sParade).property(tIdx[n]).property(sBuiltIn).property(sOpac).expression = exp;
success++;
}
}
var fParade = lr.property(sParade);
if (fParade) {
for (var pIdx = 1; pIdx <= fParade.numProperties; pIdx++) fParade.property(pIdx).selected = false;
for (var cIdx = 0; cIdx < newIdx.length; cIdx++) fParade.property(newIdx[cIdx]).selected = true;
}
}
if (!total) {
alert("执行中止:未在选中图层上找到选中的效果。");
return false;
} else if (errs.length) {
var msg = errs.slice(0, 15).join("\n");
if (errs.length > 15) msg += "\n... (及其他 " + (errs.length - 15) + " 个)";
alert("部分完成。成功 " + success + " 个。\n报错:\n" + msg);
return true;
}
return true;
}
var win = buildUI(thisObj);
if (win instanceof Window) { win.center(); win.show(); }
})(this);