【AE自制脚本分享】效果不透明度控制器
AdoreLowen
2026年05月23日 20:03

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

在这里!好绝望啊

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

脚本界面
演示1:分别使用滑块控制
演示2:统一使用复选框控制

是啊,很简单的脚本,只是用来水小站申请的,但是我觉得还是挺有用的(逃)。代码在下面,可以直接复制到扩展,或者自行存为 .jsx 使用。

代码块
JavaScript
自动换行
复制代码
(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);
复制成功