Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Comparing Values from infinite amount of Layers

  • Comparing Values from infinite amount of Layers

    Posted by Andy Kreutzberg on February 21, 2013 at 2:47 pm

    Hi again,

    i am going through a little experiment here where i wondered if it is possible to have an infinite range of layers as a part of an expression. The expression in question is the following for scale property of a text layer:

    txt = thisComp.layer(index).text.sourceText.split(“r”);
    max = thisComp.layer(“CONTROLLER”).effect(“characters”)(“Slider”);
    n = 0
    for (i = 0; i < txt.length; i++) n = Math.max(n, txt[i].length);

    if (n>max)
    {[(value[0]/n)*max,(value[1]/n)*max]}
    else
    {value}

    This is an auto scaler that will automatically reduce the size of a text layer when reaching a max characters value (to be set by a slider).

    Now say if i duplicate this layer, each scale expression will just consider its own layer’s source text as a basis for the calculation. Would it be possible to modify the above code so that each time the text layer is duplicated, the expression will compare the values from all duplicates and give the smallest value?

    For instance, say the above expression sits on the scale property of layer 7. Now if i create a layer 8 by duplicating layer 7, the expression should look at both layer 7 and 8 and compare their values to find the smallest. If i duplicate yet again and create a layer 9, the expression should look at the results from layer 7, 8 and 9… and so on, and so on…

    i am thinking the solution might either be terribly simple or terribly complicated. I just can’t figure it out. Obviously it would involve Math.max at some point. But the addressing part of the layers is a mind job.

    Dan Ebberts replied 13 years, 2 months ago 2 Members · 12 Replies
  • 12 Replies
  • Dan Ebberts

    February 21, 2013 at 9:17 pm

    The expression would need some way to figure out the range of layers it needs to examine. It’s pretty easy if all layers in the comp are participating, otherwise you might need some distinguishing feature in the layer’s name (maybe the name of each participating layer starts with an underscore character, for example). The logic would be somewhat simplified if the participating layers were contiguous, but it should still be do-able if not.

    Then you just have to create a loop that looks at all participating layers.

    Dan

  • Andy Kreutzberg

    February 22, 2013 at 4:24 pm

    Hi Dan, thanks for your input. I will continue working on this by monday and then see how i can manage it. The layers in question would be duplicated in an index range between layer 7 and layer index thisComp.numLayers-5. Subtracting (thisComp.numLayers-5)-7 should give the amount of duplicated layers. So i guess somewhere in there is the solution. The index range for the duplicates is definitely defineable.

  • Andy Kreutzberg

    February 25, 2013 at 11:36 am

    So here is the details of the situation:

    the first layer carrying the expression mentioned before always has the index of 8 (duplicating this layer will move the duplicate to index 8 and the original down to 9 though, not sure if thats important). After this index 8 layer that needs to be duplicated, there is a total of 5 layers with an index range from 9 to 13. When Layer 8 is duplicated, the index numbers for these layers are increasing of course. So basically, the range of the layers that need to be looked at is 8 to (number of layers) -5. Now i have the problem that i don’t know how to define this range and keep it infinite.

    The thing is, each new layer will add an individual value to the calculation. How would the expression from post one look like with this defined range of layers, with each individual value from each new duplicate of layer 8 adding into the calculation?

  • Dan Ebberts

    February 25, 2013 at 3:33 pm

    I haven’t tested this, so it may not be perfect, but I think it will look like this:


    startIdx = 8;
    stopIdx = thisComp.numLayers - 5;
    max = thisComp.layer("CONTROLLER").effect("characters")("Slider");
    n = 0;
    for (idx = startIdx; idx <= stopIdx; idx++){
    txt = thisComp.layer(idx).text.sourceText.split("\r");
    for (i = 0; i < txt.length; i++) n = Math.max(n, txt[i].length);
    }
    if (n>max)
    value*max/n
    else
    value

    Dan

  • Andy Kreutzberg

    February 25, 2013 at 3:54 pm

    Hey Dan, thank you very much for looking into this. Your expression seems to do what it should, however, i get an error “After Effects Error: invalid text transaction (26::386) after duplicating Layer 8 and double clicking the duplicate. So this error basically appears whenever i want to change the text of the duplicate while changing the originals text seems to yield no errors. I had that before with some expressions referring to sourceText as a floating variable.

  • Andy Kreutzberg

    February 25, 2013 at 4:14 pm

    No worries, Dan! I have assigned an on/off switch in the form of a checkbox for this auto-scaler and wrapped your expression with an if/else statement. Now the error seems to have been gone. If it should happen again, i will just use the on/off switch to apply the feature. That should work. Thanks!

  • Andy Kreutzberg

    March 7, 2013 at 12:16 pm

    Hey again,

    i just tried to play with the above code a little.

    startIdx = 8;
    stopIdx = thisComp.numLayers – 5;
    n = 0;
    for (idx = startIdx; idx <= stopIdx; idx++){
    txt = thisComp.layer(idx).text.sourceText.split(“r”);
    for (i = 0; i < txt.length; i++) n = Math.max(n, txt[i].length);

    I wanted to change it into a counter for the largest amount of line breaks in any of the text layers within the index range and output that amount as a number on a slider control. So i replaced the following line

    txt = thisComp.layer(idx).text.sourceText.split(“r”)

    by this line:

    thisComp.layer(idx).text.sourceText.split(/n|r/);

    However, the output for the variable n is a fixed number 17. I have tried to play around with this a bit further, but no matter what i change, i either get a fixed number, an error or the number of line breaks of the text layer with the highest index. I think i am missing a detail somewhere. Whenever i think i got it, something just does not work out.

  • Dan Ebberts

    March 7, 2013 at 1:04 pm

    I’m not sure what you’re trying to do with your change to the .split() argument. It needs to be a string (in double or single quotes) and whatever you put in there, the text will be split wherever there’s an occurance of that entire string.

    Dan

  • Andy Kreutzberg

    March 7, 2013 at 1:28 pm

    Basically, the line thisComp.layer(index).text.sourceText.split(/n|r/).length gives me the number of line breaks for a text. So i just wanted to put that into the code that looks at the range of layers to give me the maximum value for the line breaks of all the participating layers. So basically, i want to get the number of line breaks from the layer with the most line breaks.

  • Dan Ebberts

    March 7, 2013 at 3:34 pm

    Ah. I didn’t realize that you could use a Reg Exp as the argument to split(). So do the “n” and “r” have backslashes in front of them (they don’t show up here in your post)?

    Dan

Page 1 of 2

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