Resize layer at every frame to match a given layer

Find out why the . goes before the /

Moderator: Paul Tuersley

Post Reply
macattack
Posts: 5
Joined: August 5th, 2009, 3:57 pm

I'm working on a project that has a text layer whose source text changes at every frame. I want the text layer to be automatically resized and have its scale keyed so that the text is always as wide as a target solid layer. Having trouble.

I got this to work, which is very specific to the particular comp I'm working on:

Code: Select all

compW = app.project.activeItem.width
compH = app.project.activeItem.height


g = "frames per second"
g = 30

ai=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
initScale=100*maxWidth/w;
txtLayer.scale.setValueAtTime(i/g, [initScale,initScale,initScale]);
txtLayer.property("scale").addKey(i/g);
}


}


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?

(Note: In my for loop I'm using 300 for the number of frames to Keyframe, only because I haven't figured out how to say 'layer length in frames'.

Code: Select all

var src;
show_prompt1();

var gl;
show_prompt2();

ai = app.project.item(1);
srcLayer = ai.layer(src);
glLayer = ai.layer(gl);

g = 30; // frames per second

for (var  i = 1; i<300; i++){ //switch to  lsrc layer length in frames
	srcWidth= srcLayer.sourceRectAtTime(i/g, true).width;
	glWidth= glLayer.sourceRectAtTime(0, true).width;
	
	if(srcWidth != glWidth){
		initScale = 100*glWidth/srcWidth;
		app.project.item(1).layer(src).scale.setValueAtTime(i/g, [initScale,initScale,initScale]);
		app.project.item(1).layer(src).property("scale").addKey(i/g);
		}
	}


function show_prompt1(){
source=prompt("Enter the Layer # you wish to resize","");
if (source!=null ){
src = source}
}

function show_prompt2(){
gll=prompt("Enter the Layer # you wish to match in size","");
if (gll!=null){
gl = gll}
}
Paul Tuersley
Posts: 704
Joined: June 5th, 2004, 7:59 am
Location: London, UK

This seems to work ok. I think the problem was that you weren't parsing the prompt (turning a string into a number).
I changed a couple of other things too, like changing it to the selected comp (activeItem) rather than the first item in the project. And I made it read the frame rate from the comp too.

Also, it would be much quicker if you changed it so it only creates hold scale keyframes on frames where there's a source text keyframe. i.e. make your for statement loop through srcLayer.property("Source Text").numKeys.

Code: Select all

{
	var src;
	show_prompt1();

	var gl;
	show_prompt2();

	ai = app.project.activeItem; // the selected composition

	srcLayer = ai.layer(src);

	glLayer = ai.layer(gl);

	g = 1/ai.frameDuration; // frames per second - comp frame rate


	for (var  i = 1; i<300; i++){ //switch to  lsrc layer length in frames
		srcWidth= srcLayer.sourceRectAtTime(i/g, true).width;
		glWidth= glLayer.sourceRectAtTime(0, true).width;
	   
		if (srcWidth != glWidth) {
			initScale = 100*glWidth/srcWidth;
			srcLayer.scale.setValueAtTime(i/g, [initScale,initScale,initScale]);
			srcLayer.property("scale").addKey(i/g);
		}
	}


	function show_prompt1() {
		source=prompt("Enter the Layer # you wish to resize","");
		if (source!=null ) {
			src = parseInt(source);
		}
	}

	function show_prompt2() {
		gll=prompt("Enter the Layer # you wish to match in size","");
		if (gll!=null){
			gl = parseInt(gll);
		}
	}
}
Post Reply