Forum Replies Created

Page 2 of 6
  • David Conklin

    October 11, 2016 at 8:15 pm in reply to: Text length > transition completion?

    What you need is the linear() interpolation function. This basically lets you map one set of values to another. This is also helpful because any easing you apply to your original keys will translate to your new values. The expression would look something like what I’m posting below. I don’t know exactly how your project is set up but hopefully this is enough to point you in the right direction. I’m also attaching a simple AEP file in case the expression does not make sense on its own. You can grab that here.


    var textLyr = thisComp.layer("name");
    var pad = 20; // (in pixels);
    var skewDeg = -15; // guessing here. enter your skew val.

    var textLyr_bounds = textLyr.sourceRectAtTime(time,true); // get bounds of text layer as object.
    var textLyr_w = textLyr_bounds.width * (textLyr.scale[0]/100); // calc width of text, consider X-Scale
    var textLyr_h = textLyr_bounds.height * (textLyr.scale[1]/100); // calc height of text, consider Y-Scale

    var skewOff = textLyr_h * Math.tan(degreesToRadians(Math.abs(skewDeg))); // calculate offset for slant.

    var startWidth = 0; // value for first key.
    var endWidth = textLyr_w + skewOff + (2*pad); // value for 2nd key.

    var h = textLyr_h + (2*pad); // height remains constant.

    // this is the complicated bit.
    // Basically this says:
    // As the X value (value[0]) goes from the value of the first keyframe to the
    // value of the second keyframe, interpolate between and return a value from
    // the value of variable startWidth to the value of variable endWidth.
    var w = linear(value[0],key(1).value[0],key(2).value[0],startWidth,endWidth);

    // set values
    [w,h];

    David Conklin
    mographcode.tumblr.com

  • David Conklin

    October 10, 2016 at 4:57 pm in reply to: Color from external txt-file

    The reason your expression is not working is because doing color+number is simply concatenation. This means that if it’s basically looking for the value of the variable color, and then adding a number to it, not dynamically calling the variable color01. There are 2 ways to fix this.

    The first way (and this is the WRONG way) is to use eval(). Using eval() basically forces whatever is inside the parenthesis to execute as code, so the string “color02” wrapped in eval() would actually return the value of the color02 variable. Again, this is NOT THE RIGHT WAY to do this, as eval() is typically considered dangerous for security reasons. While it most likely would be okay in a small project that you never plan on sending out, it’s typically best to try and develop without relying on eval().

    The expression w/ eval() would look like this:
    number = 01;
    myPath = "~/Desktop/colors.txt";
    try{
    $.evalFile (myPath);
    r = parseInt((eval(color+number)).substr(0,2),16)/255;
    g = parseInt((eval(color+number)).substr(2,2),16)/255;
    b = parseInt((eval(color+number)).substr(4,2),16)/255;
    [r,g,b,1]
    }catch (err){
    [1,1,1,1]
    }

    The second, and better, method is to construct a new variable inside $.evalFile() which can then be used in the r,g and b variable lines as a shorthand. This way you just change the variable c to whatever color you would like to retrieve. The code for this method looks like this:
    myPath = "~/Desktop/colors.txt";
    try{
    $.evalFile (myPath);

    var c = color01;

    r = parseInt(c.substr(0,2),16)/255;
    g = parseInt(c.substr(2,2),16)/255;
    b = parseInt(c.substr(4,2),16)/255;
    [r,g,b,1]
    }catch (err){
    [1,1,1,1]
    }

    Best of luck, friend.

    David Conklin
    mographcode.tumblr.com

  • Here’s the most bare bone code. You could (should), of course, do things like checking that the project exists before making comps inside of it, as well as move a lot of the composition properites (size, name, etc) into variables. Hopefully this is enough to get you going.


    (function nestedComp(){

    var proj = app.project;

    // make a new comp and save it in a variable.
    // the arguments to 'addComp()' are name, width, height, par, dur, frame rate.
    var preComp = proj.items.addComp("Precomp", 1920, 1080, 1, 1, 30);

    // make the main comp.
    var mainComp = proj.items.addComp("Main Comp", 1920, 1080, 1, 1, 30);

    // add pre-comp to main comp.
    mainComp.layers.add(preComp);

    })();

    David Conklin
    mographcode.tumblr.com

  • David Conklin

    August 29, 2016 at 5:23 pm in reply to: Audio to Keyframe fade out

    Try something like this:

    //This gets the audio from the audio Amplitude layer that 'Convert Audio to Keyframes' made
    var aud = thisComp.layer("Audio Amplitude")("Effects")("Both Channels")("Slider");

    // This gets the value of the Opacity property BEFORE you applied the expression. Basically returns the value you'd see when
    // you click the 'opacity' value box to enter a value. It then divides that by 100 to give you a range 0-1 instead of 0-100.
    var offset = value/100;

    // Now, we multiply the audio data by our offset.
    aud*offset

    What this does, is that it allows you to keyframe your opacity from 0-100, and have that compound on top of the data that’s being created by the Audio to Keyframes. So, just paste this expression onto opacity, set a keyframe at 100 for when you want the fade out to begin, and a keyframe at 0 when you want the fade to be complete. This works because when your opacity is 100, we divide it by 100 and get a value of 1. The audio data multiplied by 1 is just the audio data. When our opacity is 0, we multiply the audio value by 0 and get 0. When our opacity is 50, we divide that by 100 to get 0.5, and 0.5 times our audio data is half of the value.

    I hope that makes sense. Give it a try and let me know if it doesn’t work!

    David Conklin
    mographcode.tumblr.com

  • Hey there.

    It seems like you have a somewhat complex system. I think posting your project file (if you’re able to) might help us see the specifics. It’s hard to say what the issue may be, but I have a guess.

    Inside of your ‘face’ comp, the expression you’ve written references the layer ‘Face’ in order to find the current time. t=comp("Main_comp").layer("Face").inPoint However, you have 3 layers named ‘Face.’ I think this is confusing the expression. The ‘Face’ comp doesn’t know you have 3 instances of it in the Main_comp, and that expression is evaluating based on the inPoint of the top most ‘Face’ layer only. This means that the ‘t’ in your expression is equal to about 21 seconds, and therefore not working properly for layers that exist before 21 seconds.

    I think if you used just one ‘Face’ layer and started it at frame 0 it would work more correctly. You can always hide the mask in the shots where it’s not needed by keyframing the opacity. The other option would be to triplicate the ‘Face’ comp into ‘Face-Sh01,’ ‘Face-Sh02’ and ‘Face-Sh03’ and then change your expression inside each of those comps to be more explicit. Something like t=comp("Main_comp").layer("Face-Sh02").inPoint

    I am not 100% sure that this is causing your issue, but I think the expression in the ‘Face’ comp is getting confused because there are 3 layers called “Face” in your “Main_comp.”

    Give that a try and see if it works. If not, maybe a file or any other info you can give might help us to find a solution.

    Best of luck!

    David Conklin
    mographcode.tumblr.com

  • David Conklin

    March 23, 2016 at 5:25 pm in reply to: Select / Find a file in Project Panel by Word

    Hey there,

    Here’s an example of how to do something like this.

    The main method you’ll be using here is “indexOf()“, which basically checks if a string contains another string, and returns where in the string that new string is. For instance, “MyComp_FullHD”.indexOf(“FullHD”) will return 7. The nice part of indexOf() is that it returns -1 if it can’t find your string. For instance “MyComp”.indexOf(“FullHD”) will return -1, since it doesn’t appear in the string. This is what I’m doing on Ln 31 and is what’s filtering your comp items.

    The only other tricky part is that making a composition requires 6 parameters (name, width, height, PAR, duration and frame rate). Since certain project items (like a still, or audio) don’t have all of these parameters, you need to supply the .addComp() method with fallbacks to handle these situations.

    This is what the ‘defaults’ object on line 6 does. In case the source file you’re using doesn’t have a frame rate, for example, the script will use defaults.frameRate instead. You can do this by supplying your ideal argument, then an || (or), followed by your default.

    For instance projItem.name||defaults.name first tries to use the name of the projItem object, but should it not exist instead uses defaults.name.

    Other than that, just change the function call on ln 55 to to use your preferred text filter. Keep in mind, it’s case sensitive!

    Good luck!

    (function makeCompsFromFilesWithWord(thisObj){

    // Shortcuts
    var proj = app.project;

    var defaults = {
    name: "Comp",
    width: 1920,
    height: 1080,
    pixelAspect: 1,
    duration: 1,
    frameRate: 30
    }

    // function findItemsByWord(theWord)
    // This function finds every project item containing theWord
    // Args:
    // theWord - String - the word to search for.
    // Returns
    // An array containing all project items with theWord
    // in their name.
    function findItemsByWord(theWord){

    // Holder for items with theWord in their name.
    var itms = [];

    // Loop through entire project/
    for (var i = 1; i <= proj.numItems; ++i){

    // does the name of this item have theWord in it?
    if(proj.item(i).name.indexOf(theWord) != -1){
    itms.push(proj.item(i));
    }
    }

    return itms;

    } // end findItemsByWord();

    // function makeComps(projItem)
    // This function makes a composition out of the project item.
    // Args:
    // projItem - Project Item - the item to make the comp from.
    // Returns:
    // The newly created Comp.
    function makeComps(projItem){

    var theComp = proj.items.addComp(projItem.name||defaults.name, projItem.width||defaults.width, projItem.height||defaults.height, projItem.pixelAspect||defaults.pixelAspect, projItem.duration||defaults.duration, projItem.frameRate||defaults.frameRate);
    theComp.layers.add(projItem)
    return theComp;

    }

    // Filter project items.
    var getComps = findItemsByWord("FullHD");

    // Make a comp for each project item retuned by findItemsByWord()
    for(var i = 0; i < getComps.length; ++i){
    makeComps(getComps[i]);
    }

    })(this);

    David Conklin
    Motion Designer

  • If you’re able to collect all of the files you want to import into a folder, extend script has a ‘Folder’ object which you can use to import multiple files. We can do this by following the steps below:

    1. Have user select folder.
    2. Check that folder exists.
    3. Get the files from the folder.
    4. Make sure there were files.
    5. Loop through each file and perform some action on it (import it).

    I’ve written a little script that gets all files from a folder and prints their name. You can, of course, change the name-printing bit to the import script you have already written.

    If you’re looking for some additional control, you can use a ‘filter’ when running Folder.getFiles() to control what type of files you get (only MOVs, only PSDs, PSDs and MOVs, etc). Simply feed it an argument like “*.psd” to only get files with the .PSD extension.

    Here’s the script:
    (function importFilesFromFolder(){
    app.beginUndoGroup("Import files from folder");

    var fldr = Folder.selectDialog("Choose a folder of files to import");
    if(fldr==null) return;

    var files = fldr.getFiles("*.jsx");
    if (files.length == 0) return;

    for each (var file in files){
    $.writeln(file.fsName)
    }

    app.endUndoGroup();
    })();

    Good luck!

    David Conklin
    Motion Designer

  • David Conklin

    March 4, 2016 at 12:07 am in reply to: Expression based on Layer Color

    You can use the name of the layer itself. Just prefix the layers with some descriptor and then a universal character that ‘splits’ the name. For instance:

    Grp1/My Layer
    Grp1/My other layer
    Grp1/My third layer
    Grp2/My Layer
    Grp2/My other layer
    Grp2/My third layer
    Grp3/My Layer
    Grp3/My other layer
    Grp3/My third layer

    You can then use thisLayer.name.split(“/”)[0] to get just the “Grp#” part of the name. From there you can apply whatever rules based on the groups name. If you want the part after the slash, you’d do thisLayer.name.split(“/”)[1].

    There are some other options here, too, such as using .parseInt(1,10) to extract the “1” from “Grp1” (might freak out if you have other numbers in your layers name). Additionally, you could use .indexOf() or a regex to check which ‘grp’ each layer lives in. Unfortunately I don’t know which of these is optimal in terms of calculation speed. I use .split() because I’m used to it, and you can get both sides of the “/” (as it separates the string into an array).

    AE Global Renamer, if you don’t already use it, will speed up this process a ton. I recommend grabbing it. It’s free.

    Good luck!

    Hope this was helpful. Feel free to follow up if you have any more questions.

    David Conklin
    Motion Designer

  • David Conklin

    March 3, 2016 at 11:31 pm in reply to: Expression based on Layer Color

    Your expression is evaluating as true because you’re using a single equals sign (assignment.) instead of a double equal sign. If you change your expression to ‘thisLayer.label == 1’ it throws an error saying ‘layer’ has no property ‘label.’

    The reason this works is because ‘layer’ is an object, and my saying thisLayer.label = 1 you’re adding a new property to thisLayer. You could also do thisLayer.appple = 1. If you were then to call (thisLayer.apple == 1) you would get a ‘true’ value.

    I don’t see any mention of labels in the expression reference, so you may be out of luck. External scripts can access labels, though, so there may be a script oriented solution rather than an expression oriented one.

    If you give some more details on the problem you’re trying to solve perhaps we can offer another solution.

    David Conklin
    Motion Designer

  • David Conklin

    March 3, 2016 at 7:54 pm in reply to: Checkbox to select X value or Y Value of a Layer

    Hey.

    In re-purposing my code, I think some typing/syntax errors may have occurred. For instance on line 1, you have ‘x = var lyrControl = thisLayer’. I think you need to retype this as ‘var lyrControl = thisLayer’ or ‘var x = thisLayer’.

    Syntax errors also exist on lines 6 and 10, where the ‘//’ (signifying a comment) have caused the closing curly brace to not be computed.

    I’ve re-typed the code below. I can’t check it because I don’t have your project setup; however, it is evaluating without syntax errors.

    Good luck!

    var x = thisLayer("Effects")("Parent Select")("Layer");
    var chkbxControl = thisLayer("Effects")("Map")("Checkbox");

    if(!chkbxControl.value){
    x.position[0]; // use X-position.
    }
    else{
    x.position[1]; // use Y-Position
    }

    scaleobject=linear( x, effect("Parent Input 02")("Slider"), effect("Parent Input 01")("Slider"), effect("Child Output 02")("Slider"), effect("Child Output 01")("Slider"));
    [scaleobject,effect("Fixed Scale")("Slider")]

    David Conklin
    Motion Designer

Page 2 of 6

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