Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Paragraph Alignment Detection

  • Paragraph Alignment Detection

    Posted by Julian Chojnacki on March 27, 2023 at 5:36 pm

    Hey folks,

    what are your workflows for detecting a text layer’s paragraph alignment, since you can’t directly access it via expressions?

    I found a solution to my case yesterday, which might be a little specific, but I thought I’d share it anyway.

    My setup consists of a text layer where one line is text, and the next line is a pipe character stretched into a box. Changing the paragraph alignment on this would only reposition the text, and not the pipe character, since that one is stretched in the opposite direction with a scaling animator.

    But now, knowing that only one part of the layer moves, we can measure it against the other part, and got something tangible to detect the paragraph alignment with. SourceRectAtTime seemed perfect for this, so the following code on anchor point grouping alignment made the stretched pipe character always follow the first line’s position:

    const a = sourceRectAtTime(-3);

    const b = sourceRectAtTime(-1);

    if (a.left > b.left) {

    rightAligned = [50, 0];

    } else if (a.width < b.width) {

    leftAligned = [-50, 0];

    } else {

    centered = [0, 0];


    One important thing to mention here is that the part we want to compare the changes in alignment to needs to remain static at all times, which means that we need to isolate its bounding box using a scaling animator set to [0, 0] (I did it at time == -3), leaving only the stretched pipe character.

    The negative time 1 in the other sourceRect is just a workaround for some minor bugs that can occur when you leave the parentheses empty.

    Another drawback is that this isn’t optimized for keyframing sourceText yet, which I found to be a little glitchy as well. Apart from that, it’s pretty solid!

    Thrilled to hear your thoughts & ideas!

    Julian Chojnacki replied 3 months, 3 weeks ago 3 Members · 10 Replies
  • 10 Replies
  • Filip Vandueren

    March 27, 2023 at 9:07 pm

    Hey Julian,

    Interesting question and a cool approach. I hadn’t given it any though.

    I had an idea, to just check the sourcerect width vs left ratio, and at first glance this simple test seems to work for me:

    let sr=thisComp.layer("txt").sourceRectAtTime();
  • Julian Chojnacki

    March 27, 2023 at 11:21 pm

    Filip, your code works brilliantly! Thanks for sharing 🤙

    I tried to generalize my code for all cases and ended up comparing a single characters rect positions in negative time with the positions of positive time source text value… but your technique is so much more straight forward…

    Would you mind explaining your thought process behind it?

  • Filip Vandueren

    March 28, 2023 at 8:07 am

    I quickly did a sourceRect on a text-layer, and watched what the numbers did when I changed alignment, and it made sense: left aligned text starts at around 0,0, center aligned puts the center at 0,0 (so left ends up in the negative range) and right aligned puts the right edge at 0,0 (so the left edge would be at -width)

    Then it clicked that the left/width ratio would give something around 0, -0.5, -1

    Depending on the font design there’s quite some margin of error, so I rounded and clamped. And multiplied by -2 to get 0,1,2 for the three options.

    I’m pretty sure there are outlier cases (maybe with very thin fonts, very short words,…) where this breaks

  • Brie Clayton

    March 28, 2023 at 7:56 pm

    Thank you, Filip!

  • Julian Chojnacki

    March 17, 2024 at 4:07 pm

    Hi Filip,

    do you have any suggestions on how to detect the paragraph alignment of a box text?

    After running some tests this is the closest I got:

    const t = sourceRectAtTime(time, false);

    const b = sourceRectAtTime(time, true);

    const tc = t.left + t.width / 2;

    const bc = b.left + b.width / 2;

    const thr = t.width * 0.01;

    let al;

    if (Math.abs(tc - bc) <= thr) {

    al = 1; // Center

    } else if (tc < bc) {

    al = 0; // Left

    } else {

    al = 2; // Right



    It kinda works, but it’s hit or miss – especially when changing the font size and text begins to overflow (thus my attempt to introduce a threshold). I genuinely have no clue how to detect center alignment with all the fluctuations 😀 Any ideas on how to nail this down? Or perhaps a different approach altogether? All ears for your expertise 😎


  • Julian Chojnacki

    March 17, 2024 at 4:57 pm
  • Filip Vandueren

    March 17, 2024 at 6:53 pm

    Is there room in the setup to manipulate/animate the text in negative or fractional time?

    I find that if you add an extreme tracking animator (say 1000 or -1000) the ratio of the sourceRect’s (left+width)/width becomes a good approximation of 0, 0.5 an 1 again for the three alignment cases.

  • Julian Chojnacki

    March 19, 2024 at 11:14 am

    Yeah for sure – it works great! 🙂 You truly thought outside the box there haha

    Could you shed some light on the mechanics of this approach? Curious what’s going on under the hood.

  • Filip Vandueren

    March 19, 2024 at 8:49 pm

    Because it is a text-animator, not a layout setting, the textbox is ignored.

    And the tracking pushes all left-aligned text away from the left margin, or vice versa. So it turns out to be very handy for exaggerating the dimensions to do some testing.

    I tested it with 3 lines that were exactly evenly kerned so nothing visually changed when choosing different alignments, but the tracking gave the correct result, so there you go… 🙂

  • Julian Chojnacki

    March 28, 2024 at 9:40 am

    Amazing, thank you Filip 🙏

    The only limitation I found so far is when using single-char strings, since tracking requires at least 2 characters to be effective. But I can’t think of a scenario where detecting the alignment of a single char would be necessary 😀

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