Bryan Woods
Forum Replies Created
-
Man, I was so close. So simple I completely over look just overwriting the expression with a blank. hahaha.
Thank you once again for your help.
Could I get your opinion? The way I went about it… does that seem the most efficient? I’m trying to learn how to optimize my code instead of brute-forcing it. If you can think of a simpler way to accomplish what I have, by all means please let me know!
-
Check this tutorial out and see if this helps you some:
Some contents or functionalities here are not available due to your cookie preferences!This happens because the functionality/content marked as “Vimeo framework” uses cookies that you choosed to keep disabled. In order to view this content or use this functionality, please enable cookies: click here to open your cookie preferences.
-
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();}
-
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…
-
“Unable to execute script at line 26. selectedLayers is undefined”.
-
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();}
-
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.
-
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#17492and 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).
-
Maybe I’m going about it the wrong way. It might actually be easier to sample the image, then move the anchor point to the true center of the logo. From there, I can just grab all my logos and align to selection from the Align pallet. Because the biggest issue is making sure that all the logos are not only the same size, but also aligned horizontally. Is there a way to assign a new dimension to a layer based from what sampleImage finds and then position the anchor point at the center of that new dimension?
-
Ok, so working with it last night, I can’t come up with an elegant solution for logos that have extra negative space. I can offset a logo if I already know what center should be, but I need that extra bit of ease of just swap out logos and know that it will be resized AND aligned properly based on the other logos around it. I don’t know how that could be calculated though.
The majority of my script is working out well though! I can currently throw in any logos and it will space them out equally and resize them properly, and if I need more or less, I just duplicate or remove layers and alt+replace layers as I need.
