Text Breakup Advanced

Joe Clay | Apr 9, 2018

In Tutorial 118: Text Breakup I noted that it should be possible to do that effect with one text animator instead of one per character. That makes sense, since the expression selector allows us to use the textIndex variable in order to write per-character expressions. So guess what?

Here's the first part of how to do it with an expression selector—note that it may scroll on your screen. I'll explain this code in more detail below. The setup for this is basically the same as in the tutorial as far as the sliders go.

group = thisProperty.propertyGroup(3).name.slice(-1);
amt = effect("Slide " + group)("Slider");
d = effect("Frame Delay " + group)("Slider");
seed = effect("Random Seed " + group)("Slider")+textIndex;

d = textIndex*d*thisComp.frameDuration;
amt = amt.valueAtTime(time-d);
seedRandom(seed,true);

amp = random(0,100)*amt;

if(random(0,1) > .5) {
    [amp,0,0];
} else {
    [0,amp,0];
}

This code is added to an Expression Selector's Amount property. The text animator is named Slide A. It doesn't matter what it's named as long as that A is at the end. I'll explain why next.

group = thisProperty.propertyGroup(3).name.slice(-1);
amt = effect("Slide " + group)("Slider");
d = effect("Frame Delay " + group)("Slider");
seed = effect("Random Seed " + group)("Slider")+textIndex;

The first line looks up from our Amount property using propertyGroup(countup) to get the name of the parent group this property resides within. In this case, it's 3 groups up and the name of the text animator is Slide A. So we take the name and use javascript's slice() method to get just the final character of the string—A.

If you looked at the image above, or watch the tutorial, you'll notice that I named all the sliders with an A at the end. This way, if we want to add multiple text animators, we can duplicate and rename those sliders (unfortunately you have to do that). Then we can just rename our text animator and it can look at a new group of sliders. The expression will fail when you duplicate the animator since After Effects will name the next one something like Slide A 2, so you'll just have to toggle it off and then back on again once you've named it something like Slide B. That's quicker than having to modify the expression at least.

So that's what we use to grab all of our sliders. We take the name and append the group variable to the effect name so we can grab the slider that matches the name of our text animator. amt and d just grab their slider values. seed takes the slider value and adds to it our textIndex value so that we get a different seed for each character—otherwise they'd just move together completely.

textIndex is a variable the Expression Selector gives us. After Effects evaluates this expression for each character of the text, so the value is just the index of the character that it's currently running our expression for.

d = textIndex*d*thisComp.frameDuration;
amt = amt.valueAtTime(time-d);
seedRandom(seed,true);

amp = random(0,100)*amt;

Next, we set up our delay so that each character waits a little bit after the previous character before it starts moving—unless you set the Frame Delay slider to 0 of course. So we take our textIndex and multiply it by d which is our slider value in frames. Doing this makes sure that each character is delayed by that number of frames. This needs to be converted to time, so we multiply that whole thing by thisComp.frameDuration which is how long a frame is in seconds according to our composition. If we're at 24fps, this value is 1/24. But if we use this property instead of hardcoding it, it'll change to whatever the comp is set to.

Then we set up amt. amt is a value from 0-1 representing our animation—1 is the extent of our animation, and 0 is the base position of our characters. We're taking the value of that slider at time-d so that we can get the value offset in time by our characters. This is what sets each character's delay until the previous one begins.

Next, we set up our random seeds using seedRandom(seed,timeless). We pass that our seed value and we set timeless to true. This means that our random value will stay constant. Normally, a new random value is calculated per frame. With timeless set to true it only happens once.

Now that we have our seed set up, amp—short for amplitude—is then set to a random value from 0-100 and then multiplied by amt. As amt is basically our animation offset for each character but represented by the range 0-1, multiplying those two values remaps that range to the values we need to output for the Amount property—an array of three values from 0-100%.

In this case we're randomizing that percentage range so that each character can move up to 100% of the max value we have set.

if(random(0,1) > .5) {
    [amp,0,0];
} else {
    [0,amp,0];
}

Finally, we grab a new random value from 0-1 so that we can use a conditional to make values above .5 affect the x value, and those below affect the y value. If you had 3D characters you could make this affect all three values since the Amount property is 3-dimensional. But I only want to use 2 dimensions. So we just output an array with values for x, y, z and we're done with that property.

We just have one more expression to do. You might have noticed that I mentioned a max value, but we didn't bring that slider in. Well, the issue is that we can only output a percentage for Amount, not a value. But that's actually a nice flexibility. That means we can set all sorts of different values for the properties in our text animator and they will scale accordingly.

group = thisProperty.propertyGroup(2).name.slice(-1);
max = effect("Max Value " + group)("Slider");
mul(value,max);

I've added this simple expression to a Position property within the animator containing our Expression Selector. We set up a group variable as before though this time it's just 2 groups up.

Then we grab our max slider value, and then we use mul(vec,scalar) to multiply our value array by that maximum value. The cool thing about this is that we're using value so you can change the value of the property to modify what we get from the max slider. So if the slider is 500, you can set the property to [2,.5] and the final value will be [1000,250]. In my case, I wanted my text to possibly go right and up so I set my Position value to [1,-1].

You can also set it to [1,1] and set the random for amp in the Amount property to go from -100 to 100 so the text can move in either direction. There's a lot of different combinations of things you can do with this effect. I've added another project file to the download for Tutorial 118: Text Breakup so if you purchased that, you should've gotten an email about that. And if you didn't you can grab this setup from our Gumroad shop if you like.

Become a Patron

If you'd like to help support Workbench, check out our Patreon page. For $5 a month, you get access to all of the tutorial project files we've made available as well as other monthly projects, rigs, R&D, elements, early product previews, and BTS content not available anywhere else!

Check out our Patreon Today

Latest tutorials