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}
}
nab
Posts: 203
Joined: November 29th, 2005, 3:00 am
Location: Royan
Contact:

Take a look at this sample and see if you can modify it to fit your needs
resizeTextToFit.jsx
macattack
Posts: 5
Joined: August 5th, 2009, 3:57 pm

Thanks Nab! Works great for a single change. I didn't see variables for targetW and targetH. I added them, as well as prompts to select the Text Layer and Target Layer.

I'd still like to know how to access the comp's frame rate, as well as the layer length in frames.

Code: Select all

// Nab, Thu Aug 20 21:55:48 CEST 2009
// Resize a text layer to match a target layer size.
//
// this Script promts you to select a source layer, then resizes it to match the 100% widht/height of a target layer

function getNewTextScale(textLayer, targetW, targetH, time)
{
	var size = textLayer.sourceRectAtTime(time, false);
	var textW = size.width;
	var textH = size.height;
	
	var newXScale = targetW * 100 / textW;
	var newYScale = targetH * 100 / textH;
	var newZScale = textLayer.scale.valueAtTime(time,false)[2];
	
	return [newXScale,newYScale,newZScale];	
}

function resizeTextToFit(textLayer, targetW, targetH)
{
	var comp = textLayer.containingComp;
	var keyTimes= [];
	var keyValues= [];
	
	if (textLayer.sourceText.numKeys)
	{
		for (var t = textLayer.sourceText.keyTime(1); t <= textLayer.sourceText.keyTime(textLayer.sourceText.numKeys); t+=comp.frameDuration)
		{
			keyTimes.push(t);
			keyValues.push(getNewTextScale(textLayer, targetW, targetH, t));
		}
		textLayer.scale.setValuesAtTimes(keyTimes,keyValues);
	}
	else
	{
		textLayer.scale.setValue(getNewTextScale(textLayer, targetW, targetH, comp.time));
	}
}

/////////////<mac>
var src=prompt("Enter the Layer # you wish to resize","");
src = parseInt(src);

var goal=prompt("Enter the Layer # you wish to match in size","");
goal = parseInt(goal);
///////////////</mac>
var comp = app.project.activeItem;
var textLayer = comp.layer(src);
var targetLayer = comp.layer(goal);
////////////<mac>
var targetW = targetLayer.width
var targetH = targetLayer.height
//////////</mac>

app.beginUndoGroup("Resize Text To Fit");

resizeTextToFit(textLayer, targetLayer.width, targetLayer.height);

app.endUndoGroup();
nab
Posts: 203
Joined: November 29th, 2005, 3:00 am
Location: Royan
Contact:

Something like this:

Code: Select all

var comp = app.project.activeItem;
alert("Comp frame rate: " + comp.frameRate);

var layer = comp.layer(1);
var layerDur = Math.round(Math.abs(layer.outPoint-layer.inPoint)*comp.frameRate);
alert("Layer duration (in frames): " + layerDur);
Post Reply