After Effects Scripting (ExtendScript)

I realized I haven’t written on this blog for a while, so I’m going to share something I made for a project WIP.

So I had to work in a huuuuuuuge comp, there was like a couple hundred layers in there, honestly this is not a good way to work in this program but you know sometimes you just have to.

bigCompHelper.jsx, usage is self-explanatory , just dont get the matchnames wrong, paths are relative from layers selected.
{
        function bigCompHelper(thisObj) {
            function bigCompHelper_buildUI(thisObj) {
                var mainPanel = (thisObj instanceof Panel) ? thisObj : new Window("palette", "Big Composition Helper", undefined, {resizable: true, closeButton: false});

                res = "group{orientation:'column',\
                groupOne: Group{orientation:'row',\
                sendToTopButton: Button{text:'Send selected to top'},\
                sendToBottomButton: Button{text:'Send selected to buttom'},\
                },\
                groupTwo: Panel{orientation:'row',\
                applyExpressionButton: Button{text:'Apply expression to selected'},\
                expressionText: EditText{text:'expression'},\
                propertyText: EditText{text:'effect.property(\"\")()'},\
                },\
                groupThree: Panel{orientation:'row',\
                applyEffectButton: Button{text:'Apply effect to selected'},\
                effectText: EditText{text:'effect to be applied (or matchname)'},\
                },\
                groupFour: Panel{orientation:'row',\
                tweakButton: Button{text:'Change Value'},\
                propText: EditText{text:'effect.property(\"\")()'},\
                valueText: EditText{text:'value to change to'},\
                },\
                groupFive: Panel{orientation:'row',\
                removeEffectButton: Button{text:'Delete effect from selected'},\
                effectText: EditText{text:'effect to be removed (or matchname)'},\
                },\
                groupSix: Panel{orientation:'row',\
                selectLayerButton: Button{text:'Select Layers'},\
                fromText: StaticText{text:'from'},\
                fromIndexText: EditText{text:'index'},\
                toText: StaticText{text:'to'},\
                toIndexText: EditText{text:'index'},\
                },\
                }";
                
                mainPanel.grp = mainPanel.add(res);
                
                mainPanel.grp.groupOne.sendToTopButton.onClick = function() {
                        sendToTop();
                    }

                mainPanel.grp.groupOne.sendToBottomButton.onClick = function() {
                        sendToBottom();
                    }
                
                
                mainPanel.grp.groupTwo.applyExpressionButton.onClick = function() {
                        var expression = mainPanel.grp.groupTwo.expressionText.text;
                        var property = mainPanel.grp.groupTwo.propertyText.text;
                        applyExpression(expression, property);
                    }
                
                mainPanel.grp.groupThree.applyEffectButton.onClick = function() {
                        var effect = mainPanel.grp.groupThree.effectText.text;
                        applyEffect(effect);
                    }
                
                 mainPanel.grp.groupFour.tweakButton.onClick = function() {
                        var propertyPath = mainPanel.grp.groupFour.propText.text;
                        var newValue = mainPanel.grp.groupFour.valueText.text;
                        tweak(propertyPath, newValue);
                    }
                
                mainPanel.grp.groupFive.removeEffectButton.onClick = function() {
                        var effect = mainPanel.grp.groupFive.effectText.text;
                        removeEffect(effect);
                    }
                
                mainPanel.grp.groupSix.selectLayerButton.onClick = function() {
                        var from = Number(mainPanel.grp.groupSix.fromIndexText.text);
                        var to = Number(mainPanel.grp.groupSix.toIndexText.text);
                        selectLayers(from, to);
                    }

                mainPanel.layout.layout(true);
                
                return mainPanel;
            }
        
            var myScriptPal = bigCompHelper_buildUI(thisObj);
            
            if(myScriptPal != null && myScriptPal instanceof Window) {
                myScriptPal.center();
                myScriptPal.show();
            }
        }
    bigCompHelper(this);
}

function sendToTop() {
        app.beginUndoGroup("Move Layers to Bottom");
        var currentLayers = app.project.activeItem.selectedLayers;
        for (var i=0; i < currentLayers.length; i++){
            currentLayers[i].moveToBeginning();
            }
        app.endUndoGroup();
    }

function sendToBottom() {
        app.beginUndoGroup("Move Layers to Bottom");
        var currentLayers = app.project.activeItem.selectedLayers;
        for (var i=0; i < currentLayers.length; i++){
            currentLayers[i].moveToEnd();
            }
        app.endUndoGroup();
    }
function applyExpression(exp, prop) {
        app.beginUndoGroup("Mass Expression Application");
        var bruh = app.project.activeItem.selectedLayers;
        var bruhStr = "app.project.activeItem.selectedLayers";
        for (var i=0; i < bruh.length; i++){
            var newPath = eval(bruhStr + "[" + i + "]." + prop);       
            newPath.expression = exp;
        }
        app.endUndoGroup();
    }

function applyEffect(n) {
        app.beginUndoGroup("Mass Effect Application");
        var bruh = app.project.activeItem.selectedLayers;
        for (var i=0; i < bruh.length; i++){
            bruh[i].effect.addProperty(n);
        }
        app.endUndoGroup();
    }

function tweak(prop, val) {
        app.beginUndoGroup("Mass Tweak");
        var bruh = app.project.activeItem.selectedLayers;
        var bruhStr = "app.project.activeItem.selectedLayers";
        for (var i=0; i < bruh.length; i++){
            var newB = eval( bruhStr + "[" + i + "]." + prop);
            if (newB.value instanceof Array) {
                var val = val.split(",")
                }
            newB.setValue(val);
        }
        app.endUndoGroup();
    }

function removeEffect(n) {
        app.beginUndoGroup("Mass Effect Removal");
        var bruh = app.project.activeItem.selectedLayers;
        for (var i=0; i < bruh.length; i++){
            bruh[i].effect.property(n).remove();
        }
        app.endUndoGroup();
    }

function selectLayers(from, to) {
        for (i = from; i < (to+1); i++) {
            app.project.activeItem.layer(i).selected = true;
        }
    }

on a side note, I did also look into HTML panels, but they’re slightly more sophisticated and not super necessary for this project.

someone mentioned that AE doesnt have a color wheel, I tried to make one with HTML panels and failed miserably because I’m not proficient enough in HTML/CSS and how digital colors work. I had thought that I know a lot more about digital color than most people, but turns out they’re still so fucking complicated.

Second attempt at making something useful, didn’t think most people would need this, and I was pretty sure other people have made the exact same plugin before. Very basic stuff, used a “”parser”” to throw when things that arent numbers are entered, hated that.

2 thoughts on “After Effects Scripting (ExtendScript)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s