Forum Replies Created

  • If you’re talking about scripting, the only way to go about it is to add the effect to a layer, set the layer control to another layer, select “Effects & Masks” from the dropdown, then remove the referenced layer and now save the effect as a preset. Afterwards, you can apply the preset within your script and “Effects & Masks” will be selected right away.

  • Constantin Maier

    April 21, 2022 at 9:52 pm in reply to: Limit to After Effect Script Hotkeys

    Hey, it’s quite a complicated thing, so I can’t give you my full code. It’s very long, interconnected with a bunch of other stuff, and also very specific to the use of this script. It would be too time-consuming to cover everything here but I hope you can figure out the rest yourself.

    So let’s assume you’ve built your UI where people enter shortcuts that are attached to a certain script file. Now you will have to save these shortcuts to a textfile which might look like this:

    My Script 1.jsx = Shift+G
    My Script 2.jsx = Ctrl+Alt+Shift+U
    My Script 3.jsx = Ctrl+R

    Now you also have to write these shortcuts to AE’s shortcut file (and in there to the one script that will execute all other scripts). Get the name of the active shortcut file (= the current “Keyboard Layout Preset” as it’s also called within AE) like this:

    var activeKeyFile;
    if (app.preferences.havePref("General Section", "Shortcut File Location", PREFType.PREF_Type_MACHINE_SPECIFIC)){
    activeKeyFile = app.preferences.getPrefAsString("General Section", "Shortcut File Location", PREFType.PREF_Type_MACHINE_SPECIFIC);
    }

    Now you have the name but you also need the file itself. For this, we first have to determine the OS:

    // Determine Operating System
    var thisOS;
    if ($.os.indexOf("Windows") != -1 || system.osName.indexOf("Windows") != -1){
    thisOS = "Windows";
    } else if ($.os.indexOf("Mac") != -1 || system.osName.indexOf("Mac") != -1){
    thisOS = "Mac";
    }

    Now let’s find the user folder (on Mac the directory is a bit different than on Windows since it’s not directly in the folder that is to be found with “Folder.userData”):

    var userData;
    if (thisOS == "Windows"){
    userData = Folder.userData.fullName;
    else if (thisOS == "Mac"){
    userData = Folder.userData.parent.fullName + "/Preferences";
    }

    Afterwards, we can define the folder in which AE’s shortcut file lives and combine it with the name of the current shortcut file to reference the actual file:

    var aeKeyFolderString = userData + "/Adobe/After Effects/" + app.version.substring(0, 4) + "/aeks";
    var aeKeyFile = File(aeKeyFolderString + "/" + activeKeyFile);

    Now read the file with a basic function like this one for example:

    // FUNCTION: Read File and return Array
    function readFile(fileToRead){
    var fileLineArr = [];
    fileToRead.open("r");
    while (!fileToRead.eof){
    fileLineArr.push(fileToRead.readln().toString());
    }
    fileToRead.close();
    return fileLineArr;
    }
    var aeKeyArray = readFile(aeKeyFile);

    We also need a primary script file that will execute all our other scripts. Let’s say it’s called “00 Primary Script.jsx” and it’s already living in AE’s “Scripts” folder. Now we have to know what its index is within AE’s menu in order to apply shortcuts to it. We can find out the index by calling “app.findMenuCommandId()” and we have to limit it to the third and fourth number in the ID (the other numbers aren’t important to us), so like this:

    var primeScriptID = app.findMenuCommandId("00 Primary Script.jsx");
    var primeScriptIDTrim = primeScriptID.toString().substring(2, 4);

    All script menu items are noted in AE’s shortcut file like this: “ExecuteScriptMenuItem01”, all the way up to “ExecuteScriptMenuItem20”. So the correct name within the shortcut file has to look like this:

    var primeMenuName = "ExecuteScriptMenuItem" + primeScriptIDTrim;

    Now iterate through our aeKeyArray until you find section [“CEggApp”] where all script shortcuts are stored. If our “ExecuteScriptMenuItemXX” already exists, you will have to add our shortcuts to it, otherwise, you will have to create a new line within the section. The formatting will look like this:

    	"ExecuteScriptMenuItem01" = "(Ctrl+Alt+X)(Ctrl+Alt+F1)(Ctrl+Alt+F2)"

    So you will have to save your shortcuts exactly like this into our aeKeyArray. (Unfortunately, the way I did this is kind of scattered around my script and would take too long to collect. I hope you can figure it out yourself.)

    After our line has been added to the aeKeyArray, we will have to save it back to AE’s shortcut file:

    // FUNCTION: Write a String to a File
    function writeStringToFile(toFile, thisString){
    toFile.open("w");
    toFile.write(thisString);
    toFile.close();
    }
    writeStringToFile(aeKeyFile, aeKeyArray.join("\n"));

    Please note that you will have to either restart AE or open up AE’s shortcut panel where the user will have to hit “OK” in order for the new shortcut file to be loaded into AE.

    Woah, ok, now have all we need and we can start combining everything in our “00 Primary Script.jsx”. In there, first read all current keyboard states.

    var pressedShortcut = ScriptUI.environment.keyboardState.keyName;
    var pressedShift = ScriptUI.environment.keyboardState.shiftKey;
    var pressedAlt = ScriptUI.environment.keyboardState.altKey;
    var pressedCtrl = ScriptUI.environment.keyboardState.ctrlKey;

    Then build the shortcut name from those states:

    var shortcutName = "";
    if (pressedShift) { shortcutName = "Shift+" + shortcutName; }
    if (pressedAlt) { shortcutName = "Alt+" + shortcutName; }
    if (pressedCtrl) { shortcutName = "Ctrl+" + shortcutName; }

    There are some conversions that need to happen for the pressedShortcut because AE’s shortcut file uses other names for certain keys than the ScriptUI.environment.keyboardState.keyName variables returns, so we do this (the function should have been written with switch/case but the code is so old and I didn’t know about it back then ;)):

    // FUNCTION: Convert Key to Save Key (espacially convert Special Caracters)
    function convertKeyToSaveKey(existShortcut, nameToConvert){
    if (nameToConvert == "Enter"){ // Convert "Enter" to "Return"
    existShortcut = existShortcut + "Return";
    } else if (nameToConvert == "Delete"){ // Convert "Delete" to "FwdDel"
    existShortcut = existShortcut + "FwdDel";
    } else if (nameToConvert == "Period"){ // Convert "Period" to "."
    existShortcut = existShortcut + ".";
    } else if (nameToConvert == "Minus"){ // Convert "Minus" to "-"
    existShortcut = existShortcut + "-";
    } else if (nameToConvert == "Multiply"){ // Convert "Multiply" to "PadMultiply"
    existShortcut = existShortcut + "PadMultiply";
    } else if (nameToConvert == "Divide"){ // Convert "Divide" to "PadSlash"
    existShortcut = existShortcut + "PadSlash";
    } else if (nameToConvert == "Home"){ // Convert "Home" to "HOME"
    existShortcut = existShortcut + "HOME";
    } else if (nameToConvert == "End"){ // Convert "End" to "END"
    existShortcut = existShortcut + "END";
    } else if (nameToConvert == "PageUp"){ // Convert "PageUp" to "PageUP"
    existShortcut = existShortcut + "PageUP";
    } else if (nameToConvert == "PageDown"){ // Convert "PageDown" to "PageDOWN"
    existShortcut = existShortcut + "PageDOWN";
    } else if (thisOS == "Mac" && nameToConvert == "Backspace"){ // Convert "Backspace" to "Delete" (on Mac only)
    existShortcut = existShortcut + "Delete";
    } else {
    existShortcut = existShortcut + nameToConvert;
    }
    return existShortcut;
    }
    shortcutName = convertKeyToSaveKey(shortcutName, pressedShortcut);

    Alright, we have the exact name of the shortcut that called the “00 Primary Script.jsx” and now we will have to match this shortcut to the script file that we have saved into our text file. (This again is way too scattered around my script so I can’t collect it easily now. But I think if you made it that far, it should be quite straightforward.) If we have the script file that is supposed to be executed, the only thing we have to do now is run the script, for example with $.evalFile().

    Does this make sense? I’m sorry I skipped some stuff but I hope it’s still of some use to you… If there’s something you didn’t get, you can just ask. 🙂

  • Constantin Maier

    April 12, 2022 at 3:21 pm in reply to: Limit to After Effect Script Hotkeys

    There’s a workaround, however, I was only able to make it work properly on Windows. If you’re on Windows, here’s what you can do:

    Not sure what you’re doing exactly but you can, for example, create some sort of UI where you let the user define shortcuts for a variety of scripts. Now save the different shortcuts, either to a file or to the AE preferences. Now apply all those shortcuts to a single script that’s located in AE’s scripts folder. Now, every one of those shortcuts will call that script. Within that script, you can read the currently pressed keys via the environment keyboardState variables:

    https://extendscript.docsforadobe.dev/user-interface-tools/environment.html?highlight=environment#keyboard-state-object

    You should read the keys directly at the top of the script. If you have a longer script and you read the keys too far down the script, the user might have already let go of the keys at the time the script execution reaches this point.

    Now you know which keys the user pressed and can match those to the script that you defined earlier and that you can then execute.

    As I said, I only got this to work on Windows. On Mac, it can work too, however, there seems to be some sort of lag between pressing the shortcut and AE executing the script. That often leads to the fact that the keyboardState variables only return an “undefined”. You would have to keep the shortcut pressed for an unusually long time in order for the keyboardState variables to work. Now, if this script is just for you, you might find it still okay. However, if you want to distribute the script, I don’t think it’s acceptable.

    Hope this helps.

    PS: If you find a way to make it work on Mac, please, please let me know! 😀

  • Constantin Maier

    December 13, 2021 at 5:20 pm in reply to: Saving the result of a script as a global variable

    Well, when we’re talking about expressions, there is a way to declare a global variable in expressions and have them be accessible by other expressions. To do that you need to use the dollar sign to declare a variable, like this:

    $.myVar = “Yolo”;

    More about this here: https://blob.pureandapplied.com.au/the-global-object-in-after-effects/

    However, as far as I’ve experimented with this, I found it quite unstable as I don’t know whether it’s exactly clear when the variable gets declared and sometimes the expressions will break for a while because AE didn’t recognize the variable declaration yet on the other expression. In general, I think it’s best to do it like Andrei Popa suggested, to save it as a numeric value on a slider or something like that and access that from the other expression.

  • Constantin Maier

    May 29, 2020 at 3:19 pm in reply to: get mouse cursor x and y location in script

    Yeah, I’m not sure… It seems that the first screen always starts at 0. But who knows… However, you can certainly get other values for the second screen. Let’s say your second screen is set up so that it’s position is higher than the first screen, you will get a negative value for its Y coordinate. So I’d say it’s better to get top and left coordinates as well.

    http://www.constantin-maier.com

  • Constantin Maier

    May 29, 2020 at 3:07 pm in reply to: get mouse cursor x and y location in script

    Cool, would be interesting to get a look at your code! I also thought caring a bit more about exceptions would be nice.

    http://www.constantin-maier.com

  • Constantin Maier

    May 29, 2020 at 10:42 am in reply to: get mouse cursor x and y location in script

    …just noticing that the screen min-max variables should better start with the ones of the first screen. I don’t know whether it’s possible for a screen to not start at 0 but it’s certainly safer that way.

    var posTop = $.screens[0].top;
    var posBottom = $.screens[0].bottom;
    var posLeft = $.screens[0].left;
    var posRight = $.screens[0].right;
    for (i = 1; i < $.screens.length; i++){
    if ($.screens[i].top < posTop){
    posTop = $.screens[i].top;
    }
    if ($.screens[i].bottom > posBottom){
    posBottom = $.screens[i].botto
    }
    if ($.screens[i].left < posLeft){
    posLeft = $.screens[i].left;
    }
    if ($.screens[i].right > posRight){
    posRight = $.screens[i].right;
    }
    }

    http://www.constantin-maier.com

  • Constantin Maier

    May 29, 2020 at 10:30 am in reply to: get mouse cursor x and y location in script

    Hey, from all that I’ve read, unfortunately, there is no way to true way to do this within ExtendScript. However, I found a workaround to get the XY mouse coordinates by creating an invisible dialog before the actual one that fills the whole screen, then read the mouse position via mouseover EventListener and close it right away. After that show the actual dialog.
    If the cursor is very close to the edge of the screen, the mouse position won’t be read through and everything is in limbo. However, if you move the mouse a little bit, the actual dialog will show. I think it’s a good compromise still, especially if your script is accessed very frequently it is quite annoying to always have to move your mouse to some other place.
    I have tested this workaround with multiple screens and it seems to work fine. However, I haven’t done extensive testing. If there is something problematic about the code, please prove me wrong!

    Here’s my code:

    // Mouse Position Variables
    var scrPosX;
    var scrPosY;

    // Get Min-Max Points from all available Screens
    var posTop = 0;
    var posBottom = 0;
    var posLeft = 0;
    var posRight = 0;
    for (i = 0; i < $.screens.length; i++){
    if ($.screens[i].top < posTop){
    posTop = $.screens[i].top;
    }
    if ($.screens[i].bottom > posBottom){
    posBottom = $.screens[i].bottom;
    }
    if ($.screens[i].left < posLeft){
    posLeft = $.screens[i].left;
    }
    if ($.screens[i].right > posRight){
    posRight = $.screens[i].right;
    }
    }

    // Calculate Size for Position Checking Window from Points
    var sizeX = posRight - posLeft;
    var sizeY = posBottom - posTop;

    // Create the Window
    var mouseCapWin = new Window("dialog", undefined, undefined, {borderless: true})
    mouseCapWin.preferredSize.width = sizeX;
    mouseCapWin.preferredSize.height = sizeY;
    mouseCapWin.location = [posLeft, posTop];
    mouseCapWin.opacity = 0.01;

    // ...and a Group (so the Window won't be empty)
    var mouseCapGroup = mouseCapWin.add("group", undefined, {name: "mouseCapGroup"})
    mouseCapGroup.preferredSize.width = sizeX;
    mouseCapGroup.preferredSize.height = sizeY;
    mouseCapGroup.spacing = 0;
    mouseCapGroup.margins = 0;

    // Check Position via Event Listener
    mouseCapWin.addEventListener("mouseover", grabMousePos);
    function grabMousePos(m){
    scrPosX = m.screenX;
    scrPosY = m.screenY;
    mouseCapWin.close();
    }

    // ...and now "show" the Window
    mouseCapWin.show();

    http://www.constantin-maier.com

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy