Back to Blog

Tutorial: Tapering A Stroke with Expressions in After Effects Part 2

No items found.

For a little more fun...

Today we're going to add some fancy final touches to our tapered stroke rig using some more expression principles. We're going to be building off of all that code that we wrote in the first lesson, so make sure you finish that off first before moving on to this one.These little bells and whistles we're going to add this time will make this rig a super multi functional tapered stroke machine.In this lesson Jake will be using a really great tool for writing expressions in After Effects called Expressionist. Go ahead and grab that here if you're ready to really dive deep into the world of code.

{{lead-magnet}}

-----------------------------------------------------------------------------------------------------------------------------------

Tutorial Full Transcript Below 👇:

Music (00:01):

[intro music]

Jake Bartlett (00:23):

Hey, it's Jake Bartlett again for school of motion. And this is lesson two of our tapered stroke rig using expressions. Now, if you made it through chapter one of this lesson, you should already have a pretty good grasp on how all of the expressions we need for this rig are working. We'll add more complexity to the rig, but it will also unlock a lot of extra features. The good news is there's a lot of repetition to this process. So even if it's a little bit confusing at first, just keep following along and it should start to click. All right. So to start just open up the project file that we had from the previous lesson, this one is exactly the same. All I've done is modified the path so that we have this nice curve here. So I thought of some extra features that would make this tapered stroke rig a lot more useful.

Jake Bartlett (01:09):

The first thing I thought of was just the ability to reverse the taper. So the thick end is on this side and tapers out in the opposite direction. Another great thing to have would be the ability to taper from the center and taper either end independently. So let's jump right in and take a look at how we could make those two features a reality. I'll start by adding a new expression control. So come up to effects, expression controls, and then checkbox control. Now a checkbox control is just that it's a checkbox that you can turn on or off. So the values that they return are zero for off and one for on. And we can use that in combination with some new expressions to enable or disable that reverse taper. So let's start by renaming. This checkbox control reverse taper, and the way that the reverse taper will actually work is by reversing the order of the stroke with offset.

Jake Bartlett (02:08):

And if you remember, when we first built this taper, the original equation we wrote for the duplicate groups, stroke width was tapering in the opposite direction. So we already kind of know how to make this work. I'm going to delete all these duplicate groups and open up the taper ones, stroke I'll load the stroke with the equation. And if we take a look at the variable for the stroke taper, remember that we put this in parentheses, total groups minus the group index to get the taper, to go in the right direction. But if I duplicate this variable and give it a new name, say reverse stroke taper, and then take off this total groups minus and the parentheses around it. That equation should give us the taper in the opposite direction. But how do we get that variable to come into effect when this reverse taper is checked?

Jake Bartlett (03:07):

Well, we need to use, what's called a conditional statement. And a conditional statement is just another type of expression that you can set conditions for. And if those conditions are met, one line of code will happen. And if those conditions are not met, it moves on to the next line of code that might've been really hard to take in. So let's just start writing it so you can see exactly how it works. I'll drop down one line and start writing my statement. So a conditional statement always starts with an F and then it open parentheses. Now my condition is going to be based off of the reverse taper checkbox, but I don't have any way to reference that yet. So I need to define it as a variable. So I'll come back up here and type VAR reverse taper equals I'll find that reverse taper, checkbox control and pick whip it, then close that out with a semi-colon and now it can reference that.

Jake Bartlett (04:03):

So if the reverse taper equals one and in a conditional statement, the syntax for equals is actually two equal signs together. And one is the value when the checkbox is checked. So if the reverse taper is checked, then I'll go outside of the parentheses and add an open curly bracket. Expressionist automatically generates the closing curly bracket because it knows that I'm going to need that at the end of whatever is contained within it. Then I'm going to press enter to drop down a line. And again, expressionist has done something for me. It's indented my line, which is the same as pressing tab. And it's dropped that curly bracket down one more line. So these are all time-saving functions of expressionists. And when you're writing a lot of code every little bit helps, none of these features are available in after effects, native expression editor, but why do I need this indentation and this curly bracket on the next line?

Jake Bartlett (05:07):

Well, when you're writing code things can get very messy and very hard to look at and using this type of indentation and the placement of these containers makes everything much more organized and easy to look at. So for example, conditional statements have a hierarchy which looks like this. You start with an if statement and the condition, then you have a line of code for whatever you want that value to be. If that condition is met and you close that off with the curly bracket, then we would type else. And then another curly bracket drop down another line indent. And then the second line of code that you would want to happen if that condition isn't meant. So else is basically saying otherwise, if that condition is not met, do this. So one more time, the basics of the conditional statement is if something is true, do this, otherwise do this.

Jake Bartlett (06:07):

So what do we want to happen? If the reverse taper is checked while I want a similar equation to what we already had. So I'll copy and paste that inside that curly bracket and another feature of expressionists, I want to point out really quick is you see that when I have my cursor, right after a curly bracket or any type of container, the corresponding closing or opening container is highlighted blue. So I know that everything between these two highlighted brackets is what's included in this conditional statement. Same thing is true for these parentheses. If I click on that, both of the parentheses light up blue, so that's super handy. All right, back to our equation. If reverse taper is checked, we want to do the same linear equation, but instead of tapering to the stroke taper variable, we want to go to the reverse stroke, taper variable.

Jake Bartlett (06:58):

So I will write that in reverse stroke taper. Otherwise if reverse taper is not checked, then I want to do my regular equation. So I'll cut and paste that in between these two curly brackets and that finishes off the conditional statement. So let's apply this to the stroke with the duplicate group, and then I'll make a bunch of duplicates. And we'll see what happens when I turn the reverse taper checkbox on. Well, for the most part it's working, it looks like that taper has been reversed. The problem is that master group at the end, there hasn't changed at all. And that's because the master stroke with doesn't have any of that conditional expression applied to it. So we need to go add that conditional statement. So I'll just load that up. And this is just being driven directly by the stroke with slider. So let's define the slider as a very, so VAR stroke width equals, then that affects slider. Next, we're going to need some variables that we've already defined other places. So I'm just going to open up the stroke width for the duplicate group, and we're going to need the taper out. So I'll copy that and paste it. We're going to need the total groups. So I'll copy that and paste it. And then we're going to need the reverse taper checkbox. So let's copy that.

Jake Bartlett (08:27):

And now we should be able to write her conditional statement. So let's drop down and start again by typing if open parentheses reverse taper equals. And again, you have to put two equal sign to represent equals one, which again, just means that the checkbox is checked. Zero is unchecked. One is checked, then we'll go outside the parentheses and type my open curly brackets, enter down an indent. So if reverse taper is checked, then this happens. So what happens? Well, we need to use linear interpolation. So linear parentheses, and we need to look at the taper out slider comma with a range of zero to 100 interpolated, to a range of stroke, width, to stroke with divided by total groups and end that all with a semi-colon. So when the taper out is set to zero, we want the stroke with, and when it's set to 100, we want it to be the stroke with divided by the total groups, nothing really new in that equation.

Jake Bartlett (09:45):

Then we'll drop down after this curly bracket and say else, open curly bracket drop down in indent stroke width, which is the same as what we had before. We just wrote this a conditional statement. So let's look at this one more time. If the reverse taper is checked, do this, otherwise do this simple as that. Let's go down to our stroke width for the master group and apply it. And just like that, our stroke with now fits at the tail end. Now something strange is happening. If I turn on a multiply for all of the duplicate groups, you'll see that the last duplicate group is 28 pixels wide, but so is the master group. And that's because we accounted for this extra master group in the variable for the total groups within the duplicate stroke width. So let me load that up and show you right there.

Jake Bartlett (10:43):

At the end of total groups, we added one to compensate for the fact that the taper should be starting with the master group. So to fix that, all we have to do is add a one to the group index on this reverse stroke taper equation. So if I just put group index within parentheses and then add plus one after group index, that will automatically increase the group index of every group when the reverse stroke taper comes into play. So that should solve the problem. Let's apply that to the duplicate, delete all the other duplicates and then reduplicate that group. This is a process we'll be doing a lot through this lesson. So just bear with me. It's a lot of back and forth of deleting groups. And then reduplicating alright. So now that looks like it's working, I'll get rid of all the multiplies and now you can clearly see that the master group is as different stroke with, than the group before it.

Jake Bartlett (11:48):

And if I uncheck the reverse taper, the taper goes back to normal. So that is functioning exactly the way that we needed to awesome. One feature down. We just learned the basics of conditional statements, which is really what we'll be using for all of the other features that we're going to implement into this rig. So if that went a little bit over your head, don't worry, we're going to be using a lot of different conditional statements. So if you don't already have the hang of it, you probably will by the end of this lesson. All right, so next we want to taper the stroke on either end independently from the center. So I'm going to need another checkbox. I'll duplicate this one and name it taper in slash out, and then I'll need another slider. So I'll duplicate this taper out and rename it taper in.

Jake Bartlett (12:39):

Now, there are a lot more things you can do with conditional statements than just checking to see if a checkbox is enabled. And we're going to have to get a little bit more complex to make this taper in and out function. But again, it's going to be based on the stroke with so we can keep working on this same expression. We need to add in variables for the new controllers that we just made. So I'll type in VAR taper both for the taper in and out. So I'll find that checkbox pick whip semi-colon and then we need a variable for the taper in. So I would just copy and paste this expression, and then just by hand, update it to V taper in, and then the name of that slider is taper in. So that's all I have to do to define that variable. And we're going to add another condition to our expression.

Jake Bartlett (13:29):

So right now we just have a single if statement and then a final LC statement. But if I drop this L statement down one line, I can write another curly bracket to close up the expression above it and type else if, and start writing another condition. So that's exactly what I'll do. I'll type parentheses. And this condition is going to be based on the taper in and out checkbox. So taper both equals one. So if the taper both is checked, then drop down an indent. And I actually don't need this second curly bracket because I've already got one on the next L statement. And if I let that extra curly bracket in there, it would mess up the conditional statement. So I'm going to get rid of that one, bring that back up and go to my indented line. So if taper both is checked, then what needs to happen?

Jake Bartlett (14:30):

Well, here's where we're going to get clever and even a little bit more complex. You don't have to just write a single equation as a result of a condition. You can actually put a condition within a condition. Some might say it's an expression. Ception all right. That was terrible. But let's go ahead and write another condition within this condition. So I will start by saying if just like normal open parentheses. And then the condition I want to know is if the group index for the group, this expression is contained in, is greater than the total groups divided by two, or in other words, half of the total groups, then I want something to happen else or otherwise I want something else to happen. So let's take a look at this condition. The reason why this is a clever expression is because it's going to be based on what the group index is that the expression is written on.

Jake Bartlett (15:28):

So depending on where the group is in this stack, one thing will happen. And if it's in another location, another thing will happen. So one half of this line is going to be affected by the first line and the other half will be affected by the other line. So what do we want to happen on the groups that are in index value greater than half of the groups? Well, let's make sure we know which groups those are taper. Oh, one should be an index value of 11 because there are 10 duplicate groups. Plus one right here, we've got plus one to account for that master group. So taper one should be a value of 11. So yes, that is greater than half of the total groups. So group one is on this tail end. So if taper both is checked, we want the taper to go in the same direction for that half of the line.

Jake Bartlett (16:20):

So really I can just copy the expression for the regular taper and paste that into that section. If the group index is not greater than half the total groups, then I want it to taper in the other direction or reverse the taper, which I have the line of code for right up here. So I'll just copy and paste that, and we can apply that to the stroke width. Then I'll delete all of the duplicates, reduplicate them, and then enable the taper in and out. Now it's kind of working again. The master group is outside of these expressions, so it's not being affected by it. So I'm just going to shut it off for now. And it actually does look like it's tapering from the center onto both ends. There are a few issues. Number one is that if I adjust the taper in slider, nothing is happening. And if I adjust the taper out, it's affecting both ends at the same time. Now that is because when I copied and pasted these expressions from the reverse taper and the regular taper, I did not update the linear expression to target the taper in instead of the taper out. So I'll take this a linear equation and change taper out to taper in. Now, if I reapply that that should fix the problem, I'll delete these groups and reduplicate.

Jake Bartlett (17:49):

And there we go. Now that slider is affecting the first half and the taper outsiders effecting the second half. That's great. It's working the way that it should, but there is another issue when these two numbers aren't the same. You see that they don't flow together very nicely in the middle. Now, the reason this is happening is because the way that this expression is dividing the groups in half, or basically cutting the number of groups for each taper in half. So if I disable this, you see that the taper keeps getting larger. And when I check it, it leaves this part of the taper, the way it was and shrinks down the front half of the taper to mirror it. Instead, I want this middle section to be the stroke width, and that's actually another really easy fix. All I have to do is come in here and account for the fact that there are half the number of groups. So at the end of each linear interpolation, I will just add a times two, and I'll do that up here on this one as well. And that will double the taper amount for each half of the line when the taper both is checked. So we'll reapply this to the stroke width, delete the duplicates and reduplicate.

Jake Bartlett (19:05):

Now the line is thicker at the middle. If I uncheck you see that now the stroke with is just shifted to the center rather than shrinking down the front half of the line. And again, the taper out slider is affecting that half the taper in is affecting this half and they fit together nicely. Now we need to turn on our master group and account for that. So let's go ahead and load up that stroke width. And I can copy over some of the variables that we just defined for the duplicate groups. So I'm going to need to know this taper both. So I'll copy that and paste it here. And I just noticed that that was missing a semi-colon. So I'm just going to finish that off. Like I said, after effects is generally pretty smart and knows when things should end and begin, but be consistent and just end lines with those semi-colons all right.

Jake Bartlett (20:00):

What other variables do we need? We'll need that taper in. So I'll copy that paste and I think that's it. So after the reverse taper condition, I will drop down this else and type closing bracket else. If parentheses taper both equals one curly bracket, dropdown and indent, I can delete this curly bracket because I have one right here to close that statement. And I don't need to add that second level to find out which half of the line it's on. I already know which equation it should be using. It's the same as the reverse taper. So I'll copy and paste that expression and then multiply this by two at the end. That should be, I have to do so. I'll go to the master stroke. Now that master stroke fits in with the rest of the taper. So if I adjust these sliders, everything is working just the way it should.

Jake Bartlett (20:57):

Now here's an interesting problem with conditions. If I check the reverse taper checkbox taper in and out, no longer functions, even though it's still checked. And the reason why that happens is because a conditional statement, as soon as it's met the equation underneath, it will be applied and then after effects will stop, it will completely ignore everything after that condition is met. So, because reverse taper is first in this list. If that statement is true, it's going to apply this equation and it's going to stop right there. Now I want this to function so that even if the reverse taper is checked, the taper in an out checkbox takes priority, and we can actually do that pretty easily. All I have to do is come up to this reverse taper condition and add another condition to it. So you can actually have multiple conditions within any conditional statement.

Jake Bartlett (21:52):

So I want to add, after this reverse taper equals one, two ampersands, which translates to, and, and then I'll type taper, both equals zero or taper. Both is unchecked, then reverse the taper. But if either of these statements is not true, so the reverse taper is off or taper. Both is on ignore this line of code and go to the next statement. So this should work exactly how I want it to so apply this to this master stroke. And then I will come into my duplicate strokes and I'll do the same thing. If reverse taper equals one and taper both equals zero reapply that delete the duplicates and reduplicate.

Jake Bartlett (22:49):

All right, now both check boxes are checked, but taper in and out is what's getting the priority. If I uncheck taper in and out, my stroke still tapers in reverse, and I can uncheck reverse taper, and it goes back to normal. If I check just taper in and out, that still works. All right, we're in business. We've got two of these features already completely functioning. Now let's say that you were using this taper on something like a right-on where you had letters that you were revealing through the tapered path. You would probably want a trail to be left out the same width as the smallest stroke. Well, believe it or not, that is actually really simple to do. All I have to do is load up the trim paths, start value of the duplicate groups, and we're going to need an extra checkbox. So I'll duplicate this and rename it trail.

Jake Bartlett (23:41):

And then we'll define that as a variable in this list, VAR trail equals I'll get that checkbox in the list and pick a bit, and then we'll write a conditional statement. So this one's pretty simple. We'll start by typing. If trail equals one and group index equals total groups, then zero else, the equation we already had. So what this is saying is if the trail is checked and the group index that this expression is applied on equals the total number of groups, or in other words, if the group index is the last group in the line, make the start value equal to zero, not a variable, not in another property, simply just a value of zero. Otherwise do exactly what you've already been doing. And before I go any further, I need to make sure that I actually define total groups as a variable up here. Otherwise, there's nothing for it to reference. So I think the stroke with the master stroke has that. Yep, right there, total groups we'll copy and paste that in here. And this line of code is accounting for the master group. I actually don't need that to happen. In this instance, I'm only concerned with the total number of groups within this duplicate groups stack. So I'm going to delete that plus one, and that should be everything we need for this expression to work. So I will apply it to the start value, delete the duplicates and reduplicate.

Jake Bartlett (25:36):

Now, when I click the trail checkbox, the last duplicate in this list has a start value of zero on its trim paths because we hard-coded that value zero for when that checkbox is checked. And it still reacts to the taper out because this expression is written on the trim paths. So it's not effected by the other conditions we have on the stroke width. So that means that I can reverse the taper and it still works. I can do the taper in and out, and it still works. So that was pretty painless. Now I just want to talk about how you might animate this align a little bit. So if you set a key frame on the end value and, and started at zero and then go forward a little bit in time and set it to 100, maybe I'll just easy ease these key frames and Ram preview.

Jake Bartlett (26:29):

All right. So very simple animation, but right here at the front end, you see that as soon as this value goes past zero, the front end of the taper just pops on. It just appears. And I'm not really happy with the way that looks. So I guess it would need to animate the stroke width along with that, and possibly the segment length at the same time. So let me go to right about here, where it's the first frame that you can see the entire line, and I'll set a key frame for the stroke, with an, a segment link, and then I'll go back to the first frame and change those values down to zero. Then I'll probably want to easy ease these key frames as well, and then we'll Ram preview. All right. So that definitely looks better. It doesn't just appear out of nowhere.

Jake Bartlett (27:17):

It kind of grows, but because these key frames are eased and these key frames, aren't in the exact same place, and they're also eased. It's not as fluid as I would like it to be. And if I went into the graph editor and modified these at all, then where these two key frames are positioned has to be completely changed. So this is not a very easy way of dealing with this very simple animation. It'd be great if I didn't even have to think about the stroke with, or the segment length and that scaling automatically happened based on how much of this path was actually visible. Well, that's exactly what we're going to do next. So let me get rid of these key frames and we'll start with the segment length. And the nice thing about the segment length is that it's all being determined by the master trim paths. Remember all of these segments are the exact same length as the master group's length. So if I modified this one expression, it will reflect in all of the other duplicates. So I need another check box and I'm going to name it auto shrink in, and then I need to make a variable for that checkbox. So VA R auto shrink in equals then pick whip and I need to write a condition. So if auto shrink in equals one, then, and we'll write something there. But first I'll finish off this conditional statement else.

Jake Bartlett (28:58):

This line of code we've already got, okay. So now let's go back up and write the actual equation. So if auto shrinking is checked, then we want to do a linear interpolation. So linear, and we're going to look at the end value. So end comma. I want the range to be zero to segment length, comma, and comma, this equation right here, but I need to move that semi-colon on the outside of that parentheses. All right. So what is this expression saying? Take the end sliders range from zero to segment length, and I'm going to move that segment length. So whatever the segment link is set to and remap the values from the end value to the equation we're already using. So let's apply this to the start value and see what happens if I turn auto shrink in on, and then back this end slider up, you see that as soon as this slider hits the segment length of 50, the segment link starts to collapse and none of the path actually disappears.

Jake Bartlett (30:11):

It's all just collapsing down on each other. If I change the blend mode of the duplicates to multiply, this will be easier to see. And maybe I'll knock down the number of duplicates to five. So as the end slider closes in from the segment length down to zero, you see that the segment link is actually collapsing. That's exactly what I wanted. So that's the first part of the problem. I'll change these back to normal. The next part of the problem is that the stroke with also needs to collapse down, but the duplicate stroke with are not based on the master stroke with, so there's going to be a few more steps. Let's start with the master stroke though. I'll extend this out so I can see the whole line. And then I'll go into the master stroke, uh, load that up. And this is what I'm going to point out that these conditional expressions can get very complex.

Jake Bartlett (31:03):

The more features you add, because remember, if one set of conditions is met, then all the other conditions are ignored. So I'm going to write this condition as if none of the other check boxes are checked a little later, we'll come back to figuring out how to get it, to work with the other check boxes. But for now let's just say these check boxes are unchecked. So I'm going to add another conditional expression rate before else. So I'll add the closing bracket, ELLs if parentheses and I need to get that variable that I defined for the auto shrink in, from the master start. So let's find that variable, there we go, auto shrink in, I will copy that and paste it here. And then I will type auto shrink in equals one. Then I'll get rid of this extra curly bracket. So if auto shrinking is one, I want another linear interpolation, so linear and comma. And again, I don't have the end value defined in my variables list. So let me grab that copy and paste it. So linear end zero to segment length, comma, zero comma stroke width, then I'll end that with the semi-colon. So for the master stroke, it's not that complicated at all. I'll apply that. Oh, and it looks like I forgot to the segment length variable. So let me just copy and paste that real quick.

Jake Bartlett (32:46):

You see that expression. It gives me the same error message that after effects does, but it conveniently places it directly below the line that the error is coming from. So that's another really great time-saver all right. So I put my segment length variable in there. I should be able to re update that expression and there we go. The error goes away. Now, if this end value goes below 50, you can see that that master stroke with is getting smaller and shrinking down to zero. Great. So let's make that same functionality happen to the rest of the stroke widths. I'll load up the stroke with, for the first duplicate.

Jake Bartlett (33:26):

And again, assuming all these check boxes are unchecked, I'll drop down and type another condition else. If auto shrink out equals one, then, and get rid of that curly bracket. And again, we need those extra variables. So we need the end. I'll put that at the top. We need the auto shrink in and we need the segment length. So we've got a decent list of variables, but that's totally fine. It's making everything a lot easier to code. All right. So let's go back to our condition. If auto shrink out is one, then we want to linear the end value from zero to SEG length to zero to this linear interpolation down here. So we're actually putting a linear interpolation within a linear interpolation. Now that might seem a little bit crazy. And if you do stuff that's super, super complex with lots of math happening within those linear interpolations, it can really slow down your render, but in this case, it's really not that complex and it doesn't add much render time at all.

Jake Bartlett (34:55):

So I want to make sure that I end this line with a semi-colon and I will apply that to the stroke with, oh, and I got another error I accidentally typed auto shrink out that will come in a little bit. I need to change that back to auto shrink in reapply it now we're good. All right. Let's delete the duplicates and reduplicate and see if it worked as I bring this down, not only does the segment length gets smaller, but the stroke with also gets smaller. So that is working exactly the way it needs to. And if I adjust the segment, length it kick in until the end value reaches the segment links value, which also just happens to be the exact amount of how much of the line is visible. So as soon as that tail end of the line hits the front of the path, it starts to scale down.

Jake Bartlett (35:55):

So that's working perfectly, but what if we want it to happen on the opposite end as well, while we can be a little bit clever and get that to work fairly simply, let's add another checkbox called auto shrink out and go back to our master trim paths. We'll start there again, load that up and we need to define that new variable. So I'll just duplicate this auto shrink in and rename it auto shrink out and auto shrink out to reference the right checkbox. And first I'll start by assuming that auto shrink in is not checked and I will drop down, add another condition else. If auto shrink out equals one, then linear and comma. And this is where it's going to get a little bit different. I need a different range. If this is going to work properly, the way that I want it to behave is say the segment length is 25.

Jake Bartlett (37:04):

So I want the auto shrink out to kick in as soon as it's 25% away from 100. So 75. So the way that we'll do this is by saying 100 minus the segment length, rather than just the segment length comma 100, because I want it to go from that point to the end, which is a hundred, not zero. And I want to remap those numbers from this equation right here, which is determining the segment length and make sure that I delete this duplicate curly bracket or else the expression will break comma and, and end it with a semi-colon. So once the slider reaches 100, the start value should be equal to the end value. All right, let's apply that to the master trim paths start and see if it worked again. This is assuming that auto shrink in is off. So I will uncheck that and let's test it out. Yep. It's working awesome. So how do we get it to work with auto shrink in, well, we need to put another condition within this condition and it's going to get a little bit more complex, but it's still pretty easy to understand. So inside of this auto shrink in statement, we need to first check for another condition. So I will indent and type if auto shrink out is on and the end, the slider is greater than the segment length slider. Then give me this auto shrink out equation.

Jake Bartlett (38:58):

Al's give me the auto shrink Ian equation. So adding the two ampersands next to each other within this condition is allowing me to have two conditions that need to be met in order for this to be carried out. And the way that this is used is pretty clever, because what it's saying is if the auto shrink is checked and the end slider is greater than the segment length, then apply the auto shrink out equation. If the end slider is less than the segment length, then give me just my auto shrink in expression. So that's how we can apply both the auto shrink out and auto shrink in expressions at the same time. So let's apply this to the master start and see if it worked. I'll check both boxes and move the end slider back, and it shrinks down perfect. And I'll go this other direction and it also shrinks down.

Jake Bartlett (40:00):

So yes, that is functioning perfectly. And let's just double check the controls to make sure that the auto shrink instill works. Yep. And the auto shrink out still works on the trim pads on its own. Awesome. So we can move on from the master trim paths. Let's go to the master stroke width, load that up. I need to start by defining the variable for the auto shrink out. So I'll just duplicate this variable and adjust the naming. So auto shrink out and the name of the checkbox is auto shrink out. Then let's start with just the single shrink auto shrink out check box. Checked, drop this down a line and add a else. If auto shrink out equals one, then get rid of that extra curly bracket, linear and comma, 100 minus SEG length comma, 100 comma stroke, width, comma, zero. And then semi-colon, let's apply that to the stroke width and see if it works. The auto shrink out scales down. Yes, the front master group you can see is scaling down. Now let's account for the auto shrink in also being checked because right now that cancels it out. So we'll go up to auto shrink in and drop down in dent and make a new condition. If auto shrink out equals one and, and is greater than segment length, then we want this equation right here that we just wrote else this equation right here.

Jake Bartlett (42:11):

All right, let's apply that to the master stroke and double check that it's working shrinks out that way. And it shrinks out that way. Great. That is working. Let's move on to the duplicate groups, stroke width. And again, I need that auto shrink out variable. So I will just copy it from the one we were just using and paste it right here. Then I'll start down here again. We'll make the condition else. If auto shrink out equals one, then get rid of that extra curly bracket, linear and comma, 100 minus segment length comma, 100 comma. This equation right here, comma zero semi-colon. Then I'll copy that entire line of code. And we'll come up into the auto shrink in condition, drop down in indent and say, if auto shrink out equals one, and the end value is greater than the segment length then, and I will paste the expression. I just copied from the auto shrink out else.

Jake Bartlett (43:45):

This equation right here, we should be able to apply that to the stroke width and delete and reduplicate that group and check to see if it worked. So let's move the end value and sure enough, it is scaling out and the segment links are decreasing on the out and the N perfect. So let's just double check to make sure these work on their own as well. Auto shrink out officer, just the auto shrink in yep. That works. And the auto shrink out only auto shrink in is disabled auto shrink out is working perfect. These features are working great. Now, one little problem that I need to bring up is that if I increase the segment length past 50%, so say 60 and both auto shrink in and auto shrink out are enabled. Then when I get to that threshold of 60 on the end value, you see that boom, it pops right there.

Jake Bartlett (44:52):

Now, the reason this is happening is because both the auto shrink in and auto shrink out values are based on where that segment length is. And because the segment length is greater than half of the entire range, the taper out equation takes place before we reach that threshold. And so it snaps as soon as that condition is met and that equation kicks in. So what I'd like to do is to give priority to the auto shrink in so that if both are checked and the segment length is greater than 50, it ignores the auto shrink out. That's actually really simple to do. So let's just jump back to the master trim path, start value. And we're going to go to the auto shrink out within the auto shrink in condition. And we're going to add one last condition, which is, and SEG length is less than or equal to 50.

Jake Bartlett (45:52):

So this is how you can say less than or equal. You just use the less than sign, followed it up with an equal sign. So I'm going to copy that line of code, cause we're going to reuse that, but I'll apply that to the master trim path. Start in already. We see that things are happening. Then we'll go to the master stroke, load that up and again, find the auto shrink out within the auto shrink in and paste this code right here. It looks like I forgot to copy my ampersand. So let me add those back in and then copy that line of code again. So auto shrink out is one and N is greater than segment length. And the segment length is less than or equal to 50. Great. I'll apply that to the stroke with that updated. Now let's go to the stroke for the duplicate groups, find that same condition.

Jake Bartlett (46:45):

So auto shrink out after the segment length, I will paste and apply that they don't delete the duplicates and reduplicate. And now the segment length is greater than 50. So the auto shrink in works, but the auto shrink out is disabled. Great. If I drop this down below 50, then again, that kicks back in and it works. So let's take a look at how this could be animated. Now I'll set a key frame on the end value, start it at zero, go forward, maybe a second or so. And we'll set that to 100, then I'll Ram preview this.

Jake Bartlett (47:34):

And with just two key frames, I'm able to animate this taper in and out, and it will automatically scale up and scale down based on how much of that line is visible. So I could go in here now and adjust my value curves and everything else happens for me automatically. So that is a huge time saver when it comes to animating lines like this. Now I mentioned earlier that adding all these extra check boxes is making things a lot more complex. And I coded the last couple of features, assuming that other check boxes weren't on the reason why is because if I enable say the reverse taper that is now going to break the expression that controls the stroke width auto shrink in and out, because remember, if a condition is met after effects applies the expression and then ignores everything after it, since reverse taper is in the top of this list, that condition is met with that check box being checked and everything else is disregarded.

Jake Bartlett (48:40):

So every time you add another checkbox control, it adds another layer of conditions that you have to take into account. And it can get really complex really quickly. On top of that, some of these combinations of checkboxes required completely different equations. For example, if you had betrayal enabled and reverse taper was off and you animated this out and had auto shrink out enabled, it's going to shrink that trail out to zero. And that's probably not what you would want instead of automatically shrinking everything down to zero, it would be way more functional if the taper shrunk down to be the stroke with, of the trail rather than zero and the same way, if it was reversed, then you would want the taper to scale up into that thickest stroke width. So it's definitely a lot more complicated and you have to take a lot more things into account.

Jake Bartlett (49:37):

I'm going to spare walking you through every single line of code and instead jumped to the final rig and just show you how it's working. All right. So here is my final tapered stroke rig with all the controls working exactly the way that they're supposed to and all the different combinations of these checkboxes are also going to behave properly. So let's take a look at that combination of the trail being checked and the auto shrink out being checked. Now you already see that this is a single width line instead of it scaling down to zero. So if I back this up from the end, you see that that taper now scales down to the smallest stroke width or the trail width instead of down to zero, that makes things like write ons with text so much easier because you end up with a single with line by the time the animation is finished.

Jake Bartlett (50:25):

And this works with every of checkbox. If I reverse the taper, instead of scaling down the taper scales up to be the width of the trail, same thing with the taper in and out, I'll back that up. And you see that both halves are scaling down to be the trail width. So let's uncheck all these boxes and take a look at what happened to the code. I'll go into the contents in the duplicate groups, and I'll just load up the stroke with that. The first duplicate. Now there are so many more lines of code here so much so that I can't even fit it all on one screen. I have to scroll down. I think we went from around 35 lines of code down to 108. And the reason why there are so many more lines of code is because all of these different combinations of checkboxes forced me to account for so many more conditions within my conditional statements.

Jake Bartlett (51:14):

So for example, that trail combined with auto shrink out while I'll scroll down to the bottom where we have auto shrink out, which is right here, there's our condition. And you'll see that the first thing I do is check to see if the trail is also enabled. If the trail is enabled, then we get a linear expression, the result of all of the conditions. And you can see this all the way through my entire expression is a linear interpolation that hasn't changed. The only thing that has changed is how that range of values is being interpolated. So if the auto shrink out is on and trail is on, then we want to interpolate to the trail width rather than zero. If trail is not checked, then we do want to interpolate down to zero. Now the trail width, if we go up to the variable list, they see that I defined this as a variable.

Jake Bartlett (52:05):

This is just the stroke with, of the first duplicate taper group. And the reason why I can define it as that stroke width is because that group is never going to be deleted. This is the group that you duplicate to increase the resolution basically of your taper. So that's always going to be there, which made it okay to turn that into a variable. But once I had that as a variable, I can use it as part of my interpolation so that whatever size it is, no matter which one of these checkboxes is turned on, it will always interpolate down to that size or up to that size instead of zero. And like I said, you can see this same format repeated through every single one of my conditions. The expression itself is pretty simple. It's just checking to see if a check box is checked.

Jake Bartlett (52:50):

And then in this instance, it's seeing if auto shrink is checked and then the third level is to see if auto shrink out is checked and then check to see if trail is checked. And if all of those things are checked and all the conditions are met, then apply this linear interpolation expression. Otherwise, if this condition right here, isn't met, apply this. If this condition isn't met, then skip everything between this curly bracket and this curly bracket and go onto the next thing, which would be right here. If this condition isn't met, ignore everything between this curly bracket and this curly bracket and check for the next condition. So this is a great example of why having this structure of putting line breaks after curly brackets in, in denting for every level of condition is so important because it allows you to follow this hierarchy visually through your code to make it a lot easier to follow and understand it makes absolutely no difference to after effects.

Jake Bartlett (53:44):

If you drop down a line and indent, I could have written this entire 108 lines of code on a single line and after effects still would have interpreted exactly the same way, but that would make it impossible for me to wrap my head around what exactly is going on in this code. Now, all of that code is just for the stroke with of the duplicate groups, but we had to take a lot of these conditions into account for the master group as well. So if I open that up and take a look at the master stroke width, you see that I had to build a bunch of conditions into this as well in order to get it to behave properly for all of those combinations of check boxes. It wasn't as complicated for the trim pads on the master group or on the duplicate groups, but there were some things I needed to take into account.

Jake Bartlett (54:26):

So feel free to download this project and dig through the code to see how everything is functioning, if you're curious, but the basic format is always the same. You always start with a condition and sometimes there's multiple levels of conditions. And if all of those conditions are met, apply this expression, otherwise apply this expression. And that structure is the foundation for every single one of the features in this tapered stroke. Rick, one last thing I want to point out is that you'll see some gray text up here next to some of the variables and other lines of code within the rig. These two slashes means that it's a comment and after effects will not read this as code. So I just gave a few explanations of some of the choices I made, for example, this numb properties. Plus one, I added the comment that explains that we had to account for that extra group, the master group, outside of the duplicate groups folder. This style of commenting will make everything after these two slashes on that line, a comment. So if I were to put this before the variable, that will comment out the variable and it will no longer work.

Jake Bartlett (55:29):

So if you use one line comments, make sure they go after a line of code or in between line of code. Now you can make a comment, not extend an entire line. If I change this from a slash slash two, a slash star, and then ended it with a star slash then everything between that becomes a comment. And I can even drop this down a line and add more text on as many lines as I need to. So that's how you can add notes to your expressions for your own benefit or for other people's benefit. If you pass it on to somebody else. Oh my gosh, congratulations. I'm making it through all of that lesson. I'll give you a virtual high five. You should probably go outside and take a block around the block because that was probably way too much code to be taking in at one time.

Jake Bartlett (56:16):

Not only have you created a completely customizable reusable and streamlined tapered stroke rig you learned is so much about using really powerful expressions to come up with solutions to pretty complex problems. You can now use expressions as a problem-solving tool instead of just applying the wiggle to any property, to get some random mess out of it. I can't say enough great things about expressionists. So again, if you think you're going to be getting into this world of expressions, I highly recommend you go check it out. Thanks so much for watching and I'll see you next time.