Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Conform Layer to scale based on Alpha

  • Dan Ebberts

    December 4, 2012 at 10:02 pm

    Try this for anchor point:


    topEdge = 0;
    for (i = 0; i <= height; i++){
    temp = sampleImage([width/2,i],[width/2,0.5],true,time);
    if (temp[3] > 0){
    topEdge = i;
    break;
    }
    }
    bottomEdge = height-1;
    for (i = height-1; i >= 0; i--){
    temp = sampleImage([width/2,i],[width/2,0.5],true,time);
    if (temp[3] > 0){
    bottomEdge = i;
    break;
    }
    }

    value + [0,(topEdge+bottomEdge-height)/2]

    Dan

  • Bryan Woods

    December 4, 2012 at 10:24 pm

    You beat me to it! I was getting held up trying to figure out how to put the data from sampleImage together at the very end.

    Yes, this is the winner right here. So looks like I’ll be writing my script to take all selected items (eg. logos), scale based on sampleImage, and reposition anchor point (if needed) to true visible center. Then I can just hit align selection to center and BAM! A flexible, uniform logo lockup that can handle any sized logo.

    I’m also using this alignment code that you put together a while back:
    https://forums.creativecow.net/thread/227/16681#17492

    and I wanted to know if its possible to have the logos position outward from the center of the comp (1 logo = center, 2 logos = next to each other, 3 logos = 1 center, 1 on either side, etc).

  • Dan Ebberts

    December 5, 2012 at 1:55 am

    That would be a bit of work, but do-able. Are you thinking about doing this piece with a script rather than expressions? If so, I think you should do the whole thing with a script (having the script apply and remove the sample image expression to get the data it needs). It should render a lot faster that way. Just select the logos, run the script, and you’re done.

    Dan

  • Bryan Woods

    December 5, 2012 at 2:51 am

    I’m using a script to implement the expressions to all selected layers, but keeping the expressions for flexibility when I need to swap out logos or add/remove them.

    My workaround at the moment is to parent the layers to a null and shift everything with that and it does the job for now. I’ll document all of this tomorrow for others to learn from. I think the sampleImage anchor point script by its self is incredibly useful just for lining up awkward images with strange bounding boxes.

  • Bryan Woods

    December 7, 2012 at 8:07 pm

    Ok Dan, home stretch here. I’ve spent a little time testing this to make sure its as easy as possible and can handle unique scenarios, and I’ve come across one issue that I’d like to have your expert eyes take a look at. Attached is an error that I get when I’m in a different comp other than the first one in the project list. Further below is my script I’ve written. Could you make any guesses as to why it works for the first comp, but not the second one? Both comps are identical. Thank you!


    //Set Undo Group
    app.beginUndoGroup("Logo_Garden_Resize");

    //Define project and and active items
    var proj = app.project;
    var theComp = proj.activeItem;

    //Create Null Object to act as controller for items
    controlNull = theComp.layers.addNull();
    controlNull.source.name = "Logo_Controller";

    //Define expression sliders for controller
    var nomHeight = controlNull("Effects").addProperty("Slider Control");
    nomHeight.name = 'Height';
    nomHeight.property(1).setValue(40);
    var gap = controlNull("Effects").addProperty("Slider Control");
    gap.name = "Spacing";
    gap.property(1).setValue(50);

    //For every layer selected resize to 4% vertical height of comp AND align with 50px of padding
    for (var i = 0; i < selectedLayers.length; i++) {
    var myLayer = selectedLayers[i];
    myLayer.property("Position").setValue([theComp.width/2,theComp.height/2]); //added this to center all layers before adding expressions incase the layers were literally thrown in randomly
    myLayer.property("Scale").expression = "nominalHeight = thisComp.layer("Logo_Controller").effect("Height")("Slider"); topEdge = 0; for (i = 0; i <= height; i++){ temp = sampleImage([width/2,i],[width/2,0.5],true,time); if (temp[3] > 0){ topEdge = i; break; } } bottomEdge = height-1; for (i = height-1; i >= 0; i--){ temp = sampleImage([width/2,i],[width/2,0.5],true,time); if (temp[3] > 0){ bottomEdge = i; break; } } value*nominalHeight/(bottomEdge-topEdge+1)*100/value[1]";
    myLayer.property("Position").expression = "x = 0; gap = thisComp.layer("Logo_Controller").effect("Spacing")("Slider"); for (i = 1; i < index; i++){ L = thisComp.layer(i); x += (L.transform.scale[0]/100)*L.width + gap;} x += (transform.scale[0]/100)*width/2; [x,value[1]]";
    myLayer.property("Anchor Point").expression = "topEdge = 0; for (i = 0; i <= height; i++){ temp = sampleImage([width/2,i],[width/2,0.5],true,time); if (temp[3] > 0){ topEdge = i; break; } } bottomEdge = height-1; for (i = height-1; i >= 0; i--){ temp = sampleImage([width/2,i],[width/2,0.5],true,time); if (temp[3] > 0){ bottomEdge = i; break; } } value + [0,(topEdge+bottomEdge-height)/2]";
    myLayer.parent = controlNull;
    }

    //The end
    app.endUndoGroup();

    }

  • Dan Ebberts

    December 7, 2012 at 8:17 pm

    What happens if you change this:

    controlNull.source.name = “Logo_Controller”;

    to this:

    controlNull.name = “Logo_Controller”;

    Dan

  • Bryan Woods

    December 7, 2012 at 8:30 pm

    “Unable to execute script at line 26. selectedLayers is undefined”.

  • Bryan Woods

    December 7, 2012 at 8:36 pm

    Damn, I’m actually getting that error now regardless of which comp I’m in. Even if I revert back to controlNull.source.name. I’m wondering if AE stores defined variables, so if you quit and reopen, stored variables are deleted…

  • Dan Ebberts

    December 7, 2012 at 8:39 pm

    I think that’s a different problem. I don’t see where you’d defined your selectedLayers variable. Maybe you meant to use theComp.selectedLayers?

    Dan

  • Bryan Woods

    December 7, 2012 at 8:48 pm

    I figured it all out. I accidentally deleted my variable for selectedLayers while trying to “clean up” my code. Everything works fine again, AND in different comps. There was no problem but the one i created on my own. Haha. Thank you though for taking a look! I think this badboy is finally ready for real world use.

    I want to thank you again for working with me on this. This is going to save so much time on my end once we start utilizing this.

    FOR THOSE INTERESTED, HERE IS THE FINAL SCRIPT! Create a new (plaintext) document, and paste this in its entirety and save with a .jsx extension, and then drop it into your plugins folder.


    {

    // Created By Bryan Woods with (a lot) of help from Dan Ebberts (https://www.motionscript.com)
    // Sets the selected layers to specific scale (4% of vertical height) and adds a control Null for adjustments.

    //Set Undo Group
    app.beginUndoGroup("Logo_Garden_Resize");

    //Define project and and active items
    var proj = app.project;
    var theComp = proj.activeItem;
    var selectedLayers = theComp.selectedLayers;

    //Create Null Object to act as controller for items
    controlNull = theComp.layers.addNull();
    controlNull.source.name = "Logo_Controller";

    //Define expression sliders for controller
    var nomHeight = controlNull("Effects").addProperty("Slider Control");
    nomHeight.name = 'Height';
    nomHeight.property(1).setValue(40);
    var gap = controlNull("Effects").addProperty("Slider Control");
    gap.name = "Spacing";
    gap.property(1).setValue(50);

    //For every layer selected resize to 4% vertical height of comp AND align with 50px of padding
    for (var i = 0; i < selectedLayers.length; i++) {
    var myLayer = selectedLayers[i];
    myLayer.property("Position").setValue([theComp.width/2,theComp.height/2]); //added this to center all layers before adding expressions incase the layers were literally thrown in randomly and weren't centered in the comp to begin with
    myLayer.property("Scale").expression = "nominalHeight = thisComp.layer("Logo_Controller").effect("Height")("Slider"); topEdge = 0; for (i = 0; i <= height; i++){ temp = sampleImage([width/2,i],[width/2,0.5],true,time); if (temp[3] > 0){ topEdge = i; break; } } bottomEdge = height-1; for (i = height-1; i >= 0; i--){ temp = sampleImage([width/2,i],[width/2,0.5],true,time); if (temp[3] > 0){ bottomEdge = i; break; } } value*nominalHeight/(bottomEdge-topEdge+1)*100/value[1]";
    myLayer.property("Position").expression = "x = 0; gap = thisComp.layer("Logo_Controller").effect("Spacing")("Slider"); for (i = 1; i < index; i++){ L = thisComp.layer(i); x += (L.transform.scale[0]/100)*L.width + gap;} x += (transform.scale[0]/100)*width/2; [x,value[1]]";
    myLayer.property("Anchor Point").expression = "topEdge = 0; for (i = 0; i <= height; i++){ temp = sampleImage([width/2,i],[width/2,0.5],true,time); if (temp[3] > 0){ topEdge = i; break; } } bottomEdge = height-1; for (i = height-1; i >= 0; i--){ temp = sampleImage([width/2,i],[width/2,0.5],true,time); if (temp[3] > 0){ bottomEdge = i; break; } } value + [0,(topEdge+bottomEdge-height)/2]";
    myLayer.parent = controlNull;
    }

    //The end
    app.endUndoGroup();

    }

Page 2 of 2

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