Activity › Forums › Adobe After Effects Expressions › Changing Source Text: Resize layer at each frame to fit comp width
-
Changing Source Text: Resize layer at each frame to fit comp width
Posted by Mac Ward on August 14, 2009 at 11:41 pmHi,
I’m using the Buzzword animation preset to make the source text for a layer change at every x number of frames. What I’d like to do is make the width of that layer (which changes as often as the source text) fit the comp width at every frame. Can this be done with an expression? Or do I need a script that goes frame by frame and fits to comp width?
Thanks,
Mac
Mac Ward replied 16 years, 11 months ago 3 Members · 10 Replies -
10 Replies
-
Filip Vandueren
August 14, 2009 at 11:56 pmUnless its’ a fixed WIdth font, and you can count the letters, this can only be achieved with a script.
-
Mac Ward
August 15, 2009 at 12:02 amWell, I’m getting familiar with Photoshop Scripting and would be happy to give it an attempt in the ESTK. Do you happen to know how to access the Fit to Comp Width command?
-
Dan Ebberts
August 15, 2009 at 4:27 amThere is a way to use an expression to detect the width of a text layer by using sampleImage() to sample an area 1 pixel wide by the height of the layer. You movie in from the left edge, column by column until you get back a non-zero alpha and then do the same from the right edge. It’s a little messy and can be a little slow.
I think you might be better off with a script though. Use sourcRectAtTime() to get the extents of the text layer at each frame.
Either way, you still have a little math to do to calculate the scale value required for the layer to fill the comp.
Dan
-
Filip Vandueren
August 15, 2009 at 12:33 pmHere’s a script I did a few weeks ago that does something like this,
it constrains the first TXTlayer of the comp to a max of 1400*130 pxThis should set you on your way.
-
Mac Ward
August 15, 2009 at 5:18 pmFilip, Thank you for offering your script. I am not seeing it attached, though. Am I missing it?
-
Filip Vandueren
August 16, 2009 at 3:47 amOh,
apparently there’s something wrong with the expressions code box. Nothing I paste there gets posted ?
{
ai=app.project.activeItem;for (l=1; l<=ai.layers.length; l++) { if (ai.layers[l].matchName=="ADBE Text Layer") { break; } } txtLayer=ai.layers[l]; w=txtLayer.sourceRectAtTime(0,true).width*txtLayer.scale.value[0]/100;; maxWidth=1400; if (w>maxWidth) {
initScale=100*maxWidth/w;
txtLayer.scale.setValue([initScale,initScale,initScale]);
}h=txtLayer.sourceRectAtTime(0,true).height*txtLayer.scale.value[1]/100;
maxHeight=130;if (h>maxHeight) {
initScale=100*maxHeight/h;
txtLayer.scale.setValue([initScale,initScale,initScale]);
h=maxHeight;
}
w=w*txtLayer.scale.value[0]/100;
}
-
Mac Ward
August 18, 2009 at 9:41 pmWell Filip, I’m close.
I got this to work, which is very specific to the particular comp I’m working on:
compW = app.project.activeItem.width
compH = app.project.activeItem.heightg = "frames per second"
g = 30ai=app.project.item(1);
txtLayer=ai.layer("ngngv");
for (i=0; i<500; i++){
w=txtLayer.sourceRectAtTime(i/g,true).width//*txtLayer.scale.value[0]/100;;
maxWidth= compW;if (w
But I'm trying to make a varsion that's not comp specific, and that fits to a given layer's width, rather than to the comp width. But it keeps giving me an error at the first "sourceRectAtTime" line, saying "Null is not an object". What am I doing wrong?
show_prompt1()
var src;function show_prompt1()
{
src=prompt("Enter the Layer # you wish to resize","");}
show_prompt2()
var goal;function show_prompt2()
{
goal=prompt("Enter the Layer # you wish to match in size","");}
ai = app.project.item(1);
srcLayer = ai.layer(src);
goalLayer = ai.layer(goal);g = "frames per second";
g = 30;for (var i = 0; i<50 /*switch to lsrc layer length in frames*/; i++){
srcWidth = app.project.item(1).layer(src).sourceRectAtTime(i/g,true).width;
goalWidth = goalLayer.sourceRectAtTime(0, true).width;if(srcWidth != goalWidth){
initScale = 100*goalWidth/srcWidth;
srcLayer.scale.setValueAtTime(i/g, [initScale,initScale,initScale]);
srcLayer.property("scale").addKey(i/g);
}
} -
Mac Ward
August 18, 2009 at 9:44 pmPS
In my for loops I’m using 500 and 50 for the number of frames to Keyframe, only because I haven’t figured out how to say ‘layer length in frames’.
-
Mac Ward
August 20, 2009 at 6:50 pmIt seems that in the sourceRectAtTime line, src is not being seen as an integer. Does anyone know how to force it to be an integer? Because this does return the desired value:
show_prompt1();ai = app.project.activeItem;
srcLayer = ai.layer(src);function show_prompt1(){
source=prompt("Enter the Layer # you wish to resize","");
if (source!=null ){
src = 1} //substituting the integer for source}
alert(ai.layer(src).name)
but this does not:
show_prompt1();ai = app.project.activeItem;
srcLayer = ai.layer(src);function show_prompt1(){
source=prompt("Enter the Layer # you wish to resize","");
if (source!=null ){
src = source}}
alert(src)
alert(ai.layer(1).name)
alert(ai.layer(src).name)
-
Mac Ward
August 20, 2009 at 7:52 pmGot it!
/* seed: https://forums.creativecow.net/thread/227/13876
Thank you Filip Vandueren and Dan EbbertsThis takes the 'Layer you wish to Resize' and matches its width, at every frame to the width
of the 'Layer you wish to match*/show_prompt1()
var src;function show_prompt1()
{
src=prompt("Enter the Layer # you wish to resize","");
src = parseInt(src)
//~ if (src!=null )
//~ {
//~ src -= 1
//~ }
}show_prompt2()
var goal;function show_prompt2()
{
goal=prompt("Enter the Layer # you wish to match in size","")
goal = parseInt(goal)
//~ if (goal!=null)
//~ {
//~ goal -= 1;
//~ }
}ai = app.project.activeItem;
srcLayer = ai.layer(src);
goalLayer = ai.layer(goal);
//alert(srcLayer)
g = "frames per second";
g = 30;//~ srcWidth = srcLayer.srcRectAtTime(20/g,true).width;
//~ alert(srcWidth)for (var i = 0; i<500 /*switch to lsrc layer length in frames*/; i++){
srcWidth=srcLayer.sourceRectAtTime(i/g,true).width;
goalWidth = goalLayer.sourceRectAtTime(0, true).width;if(srcWidth != goalWidth){
initScale = 100*goalWidth/srcWidth;
srcLayer.scale.setValueAtTime(i/g, [initScale,initScale,initScale]);
srcLayer.property("scale").addKey(i/g);
}
}
Reply to this Discussion! Login or Sign Up