Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Automatically scale text layer to accomodate the length of text

  • Automatically scale text layer to accomodate the length of text

    Posted by David Newman on October 12, 2019 at 6:59 pm

    Hi all,

    I’m trying to scale a text layer automatically so that when I type text into it (or refer to it from an outside source), the text layer automatically scales so that it doesn’t clip off the sides (if it’s long) or look too small (if it’s short).

    I found an expresssion online which contains the below code. It sort of works for a few words, but if the text gets too long it seems to shrink exponentially and looks way too small. If there are only a few characters it also looks too big.

    I figure if there was an expression that was slightly more advanced then this wouldn’t happen. What would also be ideal would be to be able to set a maximum height for the text, so that if there was only one word or one letter, then it wouldn’t look massive.

    So in other words, I would like an expression that told the text to never be wider than 90% of the comp or higher than 15%, for example.

    Alas, my programming ability is poor to say the least. So any help would be greatly appreciated! Thanks.

    layerWidth = thisLayer.sourceRectAtTime(time).width;
    compWidth = thisComp.width;
    maximumWidth = compWidth * .9;
    percentageOfMaxWidth = layerWidth / maximumWidth * 100;
    leeway = 100 - percentageOfMaxWidth;
    [100 + leeway, 100 + leeway]

    Brie Clayton
    replied 2 years, 7 months ago
    5 Members · 13 Replies
  • 13 Replies
  • Dan Ebberts

    October 12, 2019 at 8:36 pm

    Something like this maybe:

    maxW = thisComp.width*0.9;
    maxH = thisComp.height*0.15;
    r = sourceRectAtTime(time);
    w = r.width;
    h = r.height;
    s = w/h > maxW/maxH ? maxW/w : maxH/h;
    [100,100]*s

  • David Newman

    October 12, 2019 at 9:26 pm

    I can’t thank you enough, Dan! This works perfectly. I am in awe of the simplicity of this, too.

    Could you please explain in layman’s English what the line beginning s= does? I’m trying to get my head around the syntax of it all. Try as I might, after nearly 40 years using computers, I do not jive very well with code.

  • Dan Ebberts

    October 12, 2019 at 9:32 pm

    That line compares whether the width to height ratio of the text is greater than the maximum width to maximum height ratio. If so, it sets the scale factor to achieve maximum width, otherwise it sets the scale factor to achieve maximum height. It’s a little coding trick that comes naturally when you’ve done it hundreds of times. ☺

    Dan

  • David Newman

    October 12, 2019 at 9:46 pm

    Thanks again. Going to study things like this in the hope that something will click in my brain and all will become clear!

  • Adam Walker

    October 20, 2019 at 5:38 pm

    Hey guys,

    Thanks for the post David I had a similar issue and thank you Dan for the solution!

    In the hope that this is not seen as hijacking the post I have a query if this code can be incorporated into a script.

    I have used the code as an expression on the scale transform of the text layer which of course works as intended, however is it possible to add this expression to the following script?
    (This was a script of yours (Dan) that I found on your website – https://www.motionscript.com/ae-scripting/create-text-layers-from-file.html)

    Named – Creating Text Layers From File

    The idea being that I can import long lines of text from the file and ensure they do not go beyond the comp borders, I believe the combination of these two pieces of code would do just that.

    FYI I have little to no understanding of javascript.

    Thanks in advanced to you both.

    Adam

    //
    // createTextLayersFromFile.jsx
    //

    //
    // This script reads a user specified text file and
    // creates a text layer for each line of text in a
    // new comp called "my text comp"
    //

    {

    // create undo group

    app.beginUndoGroup("Create Text Layers From File");

    // Prompt user to select text file

    var myFile = File.openDialog("Please select input text file.");
    if (myFile != null){

    // open file
    var fileOK = myFile.open("r");
    if (fileOK){

    // create project if necessary

    var proj = app.project;
    if(!proj) proj = app.newProject();

    // create new comp named 'my text comp'

    var compW = 160; // comp width
    var compH = 120; // comp height
    var compL = 15; // comp length (seconds)
    var compRate = 24; // comp frame rate
    var compBG = [48/255,63/255,84/255] // comp background color

    var myItemCollection = app.project.items;
    var myComp = myItemCollection.addComp('my text comp',compW,compH,1,compL,compRate);
    myComp.bgColor = compBG;

    // read text lines and create text layer for each
    // until end-of-file is reached

    var text;
    while (!myFile.eof){
    text = myFile.readln();
    if (text == "") text = "\r" ;
    myComp.layers.addText(text);
    }

    // close the file before exiting

    myFile.close();

    }else{
    alert("File open failed!");
    }

    }else{
    alert("No text file selected.");
    }

    app.endUndoGroup();
    }

  • Dan Ebberts

    October 20, 2019 at 6:27 pm

    I think you’d just have to change the section that reads the file and creates the text layers to something like this:


    var text;
    var maxW, maxH, r, w, h, s, myTextLayer;
    while (!myFile.eof){
    text = myFile.readln();
    if (text == "") text = "\r" ;
    myTextLayer = myComp.layers.addText(text);
    maxW = myComp.width*0.9;
    maxH = myComp.height*0.15;
    r = myTextLayer.sourceRectAtTime(0,false);
    w = r.width;
    h = r.height;
    s = w/h > maxW/maxH ? maxW/w : maxH/h;
    myTextLayer.property("Scale").setValue([100*s,100*s]);
    }

    Dan

  • Adam Walker

    October 20, 2019 at 6:56 pm

    Appreciate the speedy response Dan, I would have never have got this!

    The expression now works in the script ????

    The only thing I need to adjust is the variation in scale (I understand this is a result of the script itself).

    Is there a way to keep the typography the same scale yet still restrict it from going beyond the comp border, so if the line is too long it becomes two lines on one text layer and if the line is only say 3 words it just stays the original size specified in the character tab?

    Thanks again!

    Adam

  • Dan Ebberts

    October 20, 2019 at 8:12 pm

    Rather than messing with scale, I think you might be better off creating a box text layer like this:

    var maxW = myComp.width*0.9;
    var myTextLayer = myComp.layers.addBoxText([maxW,200],”some text”);

    Then the word wrap would be automatic.

    Dan

  • Adam Walker

    October 20, 2019 at 8:29 pm

    You absolute legend, Dan you are the man.

    Thank you for your time and direction with this, it really is appreciated.

    Below is how i have edited the code from your previous answer in case anyone else is looking for this in the future.

    P.s. Do you have any recommended java/AE scripting tutorials/courses, looking through the forum I can see you are a wizard at this stuff.

    Thank you once again Dan

    var text;
    var maxW, maxH, r, w, h, s, myTextLayer;
    while (!myFile.eof){
    text = myFile.readln();
    if (text == "") text = "\r" ;
    var maxW = myComp.width*0.9;
    var myTextLayer = myComp.layers.addBoxText([maxW,200],text);
    }

  • George Henderson

    September 23, 2023 at 6:28 pm

    Hi Dan,

    This works as described, but I get this error ‘invalid numeric result (divide by zero?) when the text field is empty. Is there a way not to get an error with an empty text field?

    maxW = thisComp.width*0.9;

    maxH = thisComp.height*0.15;
    r = sourceRectAtTime(time);
    w = r.width;
    h = r.height;
    s = w/h > maxW/maxH ? maxW/w : maxH/h;
    [100,100]*s

Page 1 of 2

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