Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Forums Adobe After Effects Expressions CenterMultiple Lines of Text Vertically While Ignoring Descenders

  • CenterMultiple Lines of Text Vertically While Ignoring Descenders

  • Al Edwards

    September 2, 2021 at 9:12 pm

    I am trying to add an expression to my text layer anchor point to keep the text centered vertically regardless of how many lines of text there are. I don’t want to use sourceRectAtTime because the text moves vertically when there are descenders. I’m trying to use the fontSize and leading to find the center of the layer, but it’s not doing what I expect it to do. I just changed my expressions engine to JavaScript (apparently I was still in ExtendScript) so this syntax is new to me.

    Thanks in advance!

    Code below:

    const layer = thisLayer;

    const numLines = layer.text.sourceText.value.split(‘\n’).length;

    const { fontSize, leading } = layer.text.sourceText.style;

    const xHeight = fontSize / 2;

    const height = xHeight + leading * (numLines – 1);

    [0, height/2]

  • Trent Armstrong

    September 3, 2021 at 12:29 pm

    Al,

    I had this problem recently. I’m not sure if there is a simple solution for ignoring the descenders. My solution was:

    1) Duplicate the text layer, have it read the sourceText of my main layer, and make it All Caps.

    2) Parent the Main Text Layer to the All Caps layer.

    3) Do all of the sourceRectAtTime() stuff to the All Caps layer, and then turn it off

    Whatever you type into the Main Text Layer will be shared to the All Caps layer. Then the All Caps layer centers itself correctly and brings the Main Text Layer with it.

    I hope that helps!

    Trent

  • Andrei Popa

    September 3, 2021 at 3:37 pm

    Some observations:

    1. The words layer, height, leading are reserved, you can’t name variables or constants like that. You can notice they are yellow in the expression editor.

    2. Layers in AE are split by \r not by \n

    3. You can call layer functions in the layer without saying layer at start.

    4. The size of the first row is not always your font size (I noticed you used fontSize/2). Most of the fonts are a little smaller than the actual font size. Some (like the noto family from google, the versions for arabic for example) are bigger than the actual font size. I suggest using a variable and adjusting it. You should only re-adjust it if you change the font size.

    I think this should work.

    Adjust the diff constant for your case. Start with half the font size and go up or down from there (only if necesarry).

    const diff = 100;
    const numLines = text.sourceText.value.split('\r').length;
    const myStyle = text.sourceText.style;
    const myFontSize = myStyle.fontSize;
    const myLeading = myStyle.autoLeading ? myFontSize * 1.2 : myStyle.leading;
    const myHeight = myLeading * (numLines - 1)-diff;
    [0, myHeight/2]

  • Al Edwards

    September 8, 2021 at 8:06 pm

    Thanks for the suggestions.

    The invisible all caps layer sourceRectAtTime workaround is what I went with, but I had to change the horizontal scale on the all caps text to 80% to get the lines to break in the same place. The diff constant code didn’t adjust the anchor point based on the number of lines in the text box; it kept the layer in the same place rather than shifting it vertically like I wanted. Perhaps I didn’t understand it thoroughly enough–my knowledge of expressions is self-taught with the aid of helpful forums like this one!

  • Andrei Popa

    September 9, 2021 at 8:16 am

    You did not say you have a textBox. The textbox case is more complicated as you need to find the number of lines not by splitting by \r. Here, try this is you have a textbox. You can link the diff to a slider for an easier setup. Once you figure out the correct diff, it should work if you don’t change the font size or box size. I hope this helps.


    function getNumRows(myLeading, myFontSize, height) {

    H = height - myFontSize * 0.5;

    return Math.floor(H / myLeading);

    }

    const diff = 100;

    H = sourceRectAtTime(time, false).height;

    const myStyle = text.sourceText.style;

    const myFontSize = myStyle.fontSize;

    const myLeading = myStyle.autoLeading ? myFontSize * 1.2 : myStyle.leading;

    const numLines = getNumRows(myLeading, myFontSize, H);

    const myHeight = myLeading * (numLines - 1)-diff;

    [0, myHeight/2]

Viewing 1 - 5 of 5 posts

Log in to reply.

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