Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions AE expression – split text in 2 seperate equal text lines

  • AE expression – split text in 2 seperate equal text lines

    Posted by Roy St on October 9, 2017 at 2:59 pm

    Hey,

    I would love to have some assistance – I have one line of source text, and I want to use that text to create 2 different text layers that split the original text as equal as possible. For example:
    1. one layer that is the input text: “Once upon a time there was a princess”
    2. one layer that shows the first half of the sentence: “Once upon a time”
    3. another layer that shows the second half of the sentence: “there was a princess”

    I’m not very good with coding but I was able to build something according to previous threads I’ve read and came up with expressions below. But I do have a couple of questions:
    A. Is there a better way to do it?
    B. If my input text has only one word, how can make the first text layer show that word and leave the second text layer empty?

    Hope I made myself clear,
    Thanks in advance,
    /Roy

    For the first half of the text:

    txt = thisComp.layer("TextBox").text.sourceText;
    n = Math.round(txt.length/2);
    for (i = n; i > 0; i--) if (txt[i] == " ") break;
    txt.substring(0,i)

    For the second half of the text:

    txt = thisComp.layer("TextBox").text.sourceText;
    n = Math.round(txt.length/2);
    for (i = n; i > 0; i--) if (txt[i] == " ") break;
    txt.substring(i+1)

    Paul Connors replied 7 years, 3 months ago 6 Members · 15 Replies
  • 15 Replies
  • Dan Ebberts

    October 9, 2017 at 8:09 pm

    That looks pretty good. I might change the algorithm a little so that when looking for a space, it looks one character to the left of the middle, then one character to the right, then two to the left, two to the right, etc. Otherwise it can look unbalanced if there’s a long word that ends near the center.

    I think I would also set the center to Math.round((txt.length-1)/2).

    Dan

  • Roy St

    October 9, 2017 at 10:04 pm

    Thanks for the swift reply Dan!

    Your idea sounds great, but I have no idea how to do that – any suggestions?

    Plus – any idea how to set it up if there’s only 1 word in the input text? so only the first layer would show the word and the second layer would be empty?

    Thanks,
    /R

  • Dan Ebberts

    October 9, 2017 at 10:48 pm

    Give this a try for the first layer:


    txt = thisComp.layer("TextBox").text.sourceText;
    i = Math.floor((txt.length-1)/2);
    j = (txt.length%2) ? i : i+1;
    n = -1;
    while (i >= 0 && j < txt.length){
    if (txt[i] == " "){
    n = i;
    break;
    }else if (txt[j] == " "){
    n = j;
    break;
    }
    i--;
    j++;
    }
    if (n < 0) txt else txt.substr(0,n)

    For the second layer, replace the last line with this:


    if (n < 0) "" else txt.substr(n+1)

    Dan

  • Roy St

    October 9, 2017 at 11:03 pm

    Thanks a bunch Dan, will go experiment with it right away!

    /R

  • Jarle Leirpoll

    October 21, 2017 at 2:49 pm

    Dan, thank you for this code. I tried to use your code and expand it with a slider. The goal is to make the text auto-split like in your expression when the slider is set at 0. But if the slider is set at something else, the line break should come at that point, overriding the original behavior. Slider set to 2 should break the text after word 2, etc.

    But my code doesn’t work properly.

    txt = thisComp.layer("Source").text.sourceText;
    k = Math.round(thisComp.layer("Controls").effect("Text Split After (words)")("Slider"));
    i = Math.floor((txt.length-1)/2);
    j = (txt.length%2) ? i : i+1;
    n = -1;

    while (i >= 0 && j &lt; txt.length){
    if (txt[k] == " ") {
    n = k;
    break;
    }else if (txt[i] == " "){
    n = i;
    break;
    }else if (txt[j] == " "){
    n = j;
    break;
    }
    i--;
    j++;
    }
    if (n &lt; 0) txt else txt.substr(0,n)

    Jarle Leirpoll
    PremierePro.net

  • Dan Ebberts

    October 21, 2017 at 4:51 pm

    I’d set it up as two separate loops, with a new loop (if your slider is non-zero) that starts at the first character and loops through the text until it finds the number of spaces that matches the slider (or reaches the end of the text). If the slider is zero, it does the other loop.

    Dan

  • Jarle Leirpoll

    October 21, 2017 at 6:53 pm

    Thanks Dan, that sounds like a good approach. But I’m not familiar enough with loops to understand what your loop does, and certainly not how to build a different one. ☺
    I guess I could make two different text layers, and make Opacity expressions turn them on/off depending on the slider value – but I think that would make the comp a bit slower. There will be more layers doing the same thing, so it adds up.

    Jarle Leirpoll
    PremierePro.net

  • Dan Ebberts

    October 21, 2017 at 7:31 pm

    Something like this:


    txt = thisComp.layer("Source").text.sourceText;
    nWords = Math.round(thisComp.layer("Controls").effect("Text Split After (words)")("Slider"));
    if (nWords > 0){
    count = 0;
    for (i = 0; i < txt.length; i++){
    if (txt[i] == " "){
    count++;
    if (count == nWords) break;
    }
    }
    if (count < nWords) txt else txt.substr(0,i)
    }else{
    i = Math.floor((txt.length-1)/2);
    j = (txt.length%2) ? i : i+1;
    n = -1;
    while (i >= 0 && j < txt.length){
    if (txt[i] == " "){
    n = i;
    break;
    }else if (txt[j] == " "){
    n = j;
    break;
    }
    i--;
    j++;
    }
    if (n < 0) txt else txt.substr(0,n);
    }

    Dan

  • Jarle Leirpoll

    October 21, 2017 at 7:59 pm

    Thanks Dan – getting really close! Now the first layer does its thing correctly. Great!
    The lower layer showed the same output as the first layer after I changed only the last line of code. So I guessed that this line also need to be changed.

    if (count < nWords) txt else txt.substr(0,i)

    So I changed it to the following, and the split now kinda works.

    if (count < nWords) txt else txt.substr(i,txt.length)

    The result has two problems, though:

    1. The second line always starts with a space
    2. When the slider value is higher than the number of words, the lower layer shows the same as the upper layer

    /jarle

    txt = thisComp.layer("Source").text.sourceText;
    nWords = Math.round(thisComp.layer("Controls").effect("Text Split After (words)")("Slider"));
    if (nWords > 0){
    count = 0;
    for (i = 0; i &lt; txt.length; i++){
    if (txt[i] == " "){
    count++;
    if (count == nWords) break;
    }
    }
    if (count &lt; nWords) txt else txt.substr(i,txt.length)
    }else{
    i = Math.floor((txt.length-1)/2);
    j = (txt.length%2) ? i : i+1;
    n = -1;
    while (i >= 0 && j &lt; txt.length){
    if (txt[i] == " "){
    n = i;
    break;
    }else if (txt[j] == " "){
    n = j;
    break;
    }
    i--;
    j++;
    }
    if (n &lt; 0) "" else txt.substr(n+1)
    }

    Jarle Leirpoll
    PremierePro.net

  • Jonathan Moxness

    August 2, 2018 at 6:46 pm

    Is there any way to split the text in half at a line break instead of at a space or character? I have a list of names that I’d like to split up into two text boxes just like this but I need to keep first and last names grouped together. Thanks in advance!

Page 1 of 2

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