Create A Tapered Stroke in After Effects: Part 1


Hey, this is Jake Bartlett for School of Motion,
and I am going to be teaching you how to make a tapered stroke rig in After Effects using
expressions. Now, expressions are a very intimidating topic,
let’s face it. Code is just not a language that most motion
designers speak. But if you can understand some very basic
principles of how to use expressions as a problem solving tool, the possibilities that
they open up are pretty incredible. You can create entire setups inside of After
Effects that allow you to do things that natively After Effects can’t even do. They’re an extremely powerful tool to have
in your toolbox. And hopefully after this lesson, you will
have a very good grasp on how to use them to your advantage. So let me start with my big, fat disclaimer
up front. We are going to be writing a lot of code in
this lesson. And it’s gonna get pretty geeky, but it’s
not gonna get too complex. Really, we’re gonna be more clever with our
expressions. So you should have no problem following along. I’ll go step by step. And at the end, we’ll have a tapered stroke
rig that you can reuse over and over in any project. Alright, let’s get straight to it. I’m gonna make a new composition. And framerate doesn’t really matter. Resolution, I’ll do 1920 by 1080. And I’ll set the background color to white,
just so it’s easy to see. And I’m going to start by drawing a line. Now, natively, shape layers do not allow you
to taper a stroke in After Effects. It’s a single width all the way along your
line. There’s no control for that. The only real solution that I know of that
exists is Trapcode’s 3D Stroke. And the reason I don’t really wanna use that
is ’cause one, it’s not free, and two, it works with mask paths. So I don’t have all of the controls and special
operators that shape layers allow me to have. So when I approached this problem originally,
my goal was to have a line behave exactly the same way that I’m used to on a shape layer
that I could control with Trim Paths, and use all kind of operators on, exactly the
way that I was used to, with the additional control of being able to control the width
of the line from one end to the other. So let me show you what my original concept
for that even being a possibility was. I will go into my Contents and add a Trim
Paths on the shape group. I don’t need that fill. And I’ll make my stroke round caps and round
joins. Then I’ll take my Trim Paths and set the End
value to 10. And I’m gonna make a bunch of duplicates of
this group. So let’s say 10. And then I will bring up all of the start
and End values. And I want to offset each one of these by
10%, so that I have 10 different segments. So I’m just gonna do that really quick. Not a very fun process to have to do this. Alright, there we go, so we got 10 segments,
all offset by 10% on the Trim Paths. So then I will open up the Stroke Width and
offset each one of these by 10 pixels. So 100, then 90. All the way down the line. Alright, there we go. So, if you take a look at this line, it’s
totally crude, but you can kind of see the concept working. Basically, if you segment this line, and offset
the Trim Paths of each one of them, as well as the Stroke Width, you kind of get a taper. Now, obviously, you would need a lot more
segments to make this not noticeable. And doing it by hand is pretty much out of
the question. That takes way too much time. And I have all these Duplicate Groups that
each have a copy of the same path. So if I were to go in and try and modify this
path, that’s only controlling this segment, and I’ve got another path, another path. Really, I would want one path to control all
of the segments. So I wanted to figure out a way to get expressions
to do all this complicated work or me so I didn’t even have to think about it and I’d
be left with a tapered stroke. So now I’m gonna walk you through how I used
expressions to solve that problem. I’ll start by deleting all of the Duplicate
Groups. And I will rename this Master Group. And I’ll duplicate that group and rename it
Taper 01. And I’ll regroup that group and name it Duplicate
Groups. Now, setting up this structure is pretty important
because we’re gonna be referencing a lot of different properties in groups within this
layer structure. So naming is super important. So let’s continue this structure and rename
the contents of the Master Group Master Path, Master Trim Paths, and Master Stroke. Alright, in the Duplicate Groups, I will go
into Taper 01, and that is all fine just the way it is. So I want these expressions to be based off
of the Master Group. I want all the duplicates to be following
the Master Group, and then the expressions that we use will automatically divide this
line up into segments and offset the stroke incrementally. So the first thing I wanna do is link the
duplicate path to the Master Path. So this is what we’re gonna use our first
expression for. If you’ve never use expressions before, you
just go to any property that has a stopwatch for the keyframes, and hold down Option, or
Alt on a PC, and click on that stopwatch. That will open up the expression dialog box
and give us a few extra controls. And it automatically fills in the code that
references the property that you are putting that expression on. Now, I don’t need this line of code. I actually need the code that references the
Master Path. But I don’t actually have to know how to type
that out, or what that code to reference that is. There’s this little expression pick whip that
behaves just like the parenting pick whip. I can click and drag it and then come down
to the Master Path and let go. And then After Effects will automatically
fill in that code for me, so I don’t have to do any coding. It’s as simple as that. I just click off to apply it, and now that
duplicate path follows the Master Path. And if I offset the Trim Paths for this group,
just so we can see the two different groups, grabbing this path and moving it around, you
see that it looks like there’s only one copy of that path because this path will always
follow it now that we have that expression. So, awesome, we’re already using expressions
to make stuff work! Let’s keep going! Next I want to add some expression controls. So I’m gonna come up to Effect, and go to
Expression Controls, and you’ll see this whole list of controls that we can add. Now on their own, expression controls do absolutely
nothing. They’re basically there just to give you values
that you can use to control expressions. So, the first one we’ll start with is Slider
Control. So go to Expression Controls, Slider Control. And by default, a slider, if I twirl this
open, has a range of zero to 100. You can grab this number and go past that
range in either direction, and you can also right-click on the slider and say Edit Value
to adjust that range. We’re not gonna need to do that, but just
so you’re aware, if you ever have to have a different range of numbers. Zero to 100 is gonna work just fine for what
we’re using it for, though. So I’m gonna rename this slider Stroke Width. And then I want to link the Master Stroke
Width to that slider. To do that, I’ll just hit Option and click
on that stopwatch to add the expression, grab this expression pick whip, and I can actually
come up to the Effects Controls panel and let go. And there we go. After Effects fills in that line of code for
me. I click off of it and that number turns red. Now that means that there’s an expression
driving this value. I can click and drag on this number and you
see it’s changing, but as soon as I let go, it switches back to zero. The reason why it’s zero is because our Stroke
Width slider is set to zero. If I adjust this, you see that now the Stroke
Width of my Master Path is being controlled by that. And just like I said before, I can increase
that to a higher number if I need to. But I seriously doubt I’ll ever need a Stroke
Width higher than 100, so I’m gonna leave the range right where it is. Next, I’m gonna duplicate this slider, and
I’ll rename it End. And I wanna tie the Master Trim Path’s End
value to that slider. So, I will add an expression again and pick
whip that slider, and click off. Now if I move this slider around, it controls
the End value. And because the End value is a percentage
of zero to 100, the range of zero to 100 is perfect for that value. So, no need to change that. Next we need to add another type of expression
control. I’ll come down to Angle Control. And this is gonna be a value measured in degrees. So the offset control is measured in degrees
as well. So that’s the type of controller I want to
use to drive that property. So I will add my expression, grab the pick
whip, select the angle control, and click off. Now that angle is controlling the offset of
the Trim Paths. Now if you take a look at the way that After
Effects wrote this expression, it’s referencing the effect Angle Control and the value of
Angle. But the more important part that I wanna point
out is that the name of this effect is Angle Control, which you can see up here. If I change the name of this angle to Offset,
the expression just updated based on what I named it. So After Effects is pretty intelligent in
that sense. Which is a really nice feature. Alright, so we’ve already got three controls
driving our rig. But there’s a lot more you can do with expressions
than just linking properties to expression controllers or to other properties. You can have complex equations, you can base
stuff on time, offset keyframes. There’s all kinds of possibilities. Again, we’re not gonna get too complex. But we are gonna start writing some code of
our own. So this is where I wanna introduce an extension
for After Effects called Expressionist. So, I’m gonna switch over to my Expressionist
layout and make this window bigger over here. Now, Expressionist is an expression editor
that is much easier to work with than the expression editor built into After Effects. As you can see down here, I am confined to
this window. I can’t change the size of the font, and it
can get pretty complex if you have a lot of lines of code with not a lot of room to work
with. Expressionist behaves a lot more like an actual
coding program inside of After Effects, and it has a ton of great features. If you’re serious about learning how to write
expressions, and making your own things with expressions, I highly recommend that you purchase
Expressionist. It is totally worth the money, and we have
a link for it on this page so you can go check it out. If you think you’re gonna get it, I would
even recommend that you pause the video, go buy it, install it, and then come back so
you can follow along with me inside of Expressionist. It’s fine if you don’t use Expressionist. Everything I do in here is completely doable
inside of After Effects. Expressionist just makes it a lot more easy
to look at. Alright, so the first thing I wanna do is
work on the Start value of the Master Trim Paths. So, I’m just gonna clean up my layer a little
bit so I can just focus on what’s important. I want the Start value to be based on the
End value and the total number of groups in my layer. So the number of duplicates we have in this
group here. Right now, there are two groups total, the
Master Group and Taper 01. So, I want the Start value to be the End value
divided by the number of groups, which is two. So it should be 50. So what does the expression look like that
would get that to happen? Well, let’s write that code. I’ll come over to Expressionist. And I will select the End value. And down here, I have this pick whip. I will click it once and Expressionist fills
in the code exactly the same way as if I was writing the expression down here and using
the expression pick whip. Now, the syntax that Expressionist uses is
slightly different than the syntax After Effects uses. And syntax is just the structure and the naming
conventions that coding languages use. So things like putting names in quotes and
putting groups in parentheses. The thing is, After Effects natively uses
one naming convention for its syntax and Expressionist just uses another one that’s a little bit
more consistent. Expressions are based on the JavaScript language,
and it’s pretty flexible in the way that you can write things. If you look down here, After Effects puts
Content, Master Group dot Content Master Trim Paths, and Expressionist uses parentheses
and double-quotes for each one of those groups instead. So you see Contents, instead of being separated
by periods, is just in the exact same format as the other groups. The end result is exactly the same, it’s just
a little bit different way of writing the code. So if you’re not using Expressionist, just
know that any time I click on a pick whip, my code’s probably gonna look different than
yours, but the end result is gonna be exactly the same, so don’t worry about it. Alright, so that code references the End value. And then, again, there are two Total Groups,
Master Group and the Taper 01. So, I want to take this End value and divide
it by two. Then I’ll apply that to the Start value by
having my Start value selected and then inside of Expressionist pressing Command-Enter. That applies the expression and look at that. Our Start value is now 50%. Because it is 100, the End value, divided
by two. So that’s great. If I go into my Effects Control, and I adjust
this slider, you see that the Start value of the Master Group is moving in proportion
to the End value. So if this was set to 50, then the Start value
is 25% because it is half of the End value. Great! The problem is, that hard coded number is
not going to update with the number of groups. So if I were to duplicate these groups, this
value doesn’t change at all. So instead of using a two, we need to tell
After Effects how to count the number of groups and automatically fill that in, instead of
a hard-coded number. So I’ll delete these Duplicate Groups. And now I’m gonna show you really quickly
how to get a group’s index. So I’m just gonna make a new composition really
quick for a demo. You don’t have to follow along with this. I’m gonna make a new solid. And you probably already know that this number
over here in this column is the index value of the layer. That’s what After Effects calls its number. It’s an index value. What you might not know is that inside any
layer, every group, every effect and every property has an index value. There’s just no number next to it. So inside of this layer is a Transform group. Right now, that’s an index value of one. If I add, say, a Fast Blur to that layer,
now there’s an Effects group. So in this hierarchy, the index value of Effects
is one and Transform is two. If I open up the Effects, and I duplicate
this Fast Blur five times, now there’s a hierarchy inside of the Effects group. Fast Blur one, two, three, four, five. So I’ll open up the fifth Fast Blur, and I’ll
add an expression on the blur value. And I’m just gonna type in a simple expression,
ThisProperty. So, the property I’m writing the expression
on, dot PropertyGroup, parentheses, one, close parentheses, dot PropertyIndex. I’ll apply that. And now we have a value of five. So this expression is saying ThisProperty,
the blurriness, PropertyGroup one, which means the property group one level higher than ThisProperty,
give me the property index for that value. So, one level higher is Fast Blur five from
the value that I’m writing the expression on. If I change the order of this Fast Blur to
the third position, that value updates to three. And if I copy this expression to all the Fast
Blurs, and double-tap the E to bring up all the expressions, you see that the index value
is reflected in the Fast Blurs’ blurriness, and it updates based on the order of the effects. So that’s how we can find the property index
of any value. So I’ll go back to this main comp, and things
get a little bit more tricky when it comes to shape layers. To show you what I mean, I’m just gonna go
into the stroke of this Taper 01, and I’ll add an expression onto the Stroke Width. So if I type that same expression, ThisProperty,
dot PropertyGroup one, dot PropertyIndex, and I capitalize ThisProperty. That is not the proper syntax, so that would
have broken the expression. So that is something that is very important
to take note of. It’s very common for commands and expressions
to start with lowercase, but then the second word of the command to be uppercase, and every
word after that uppercase as well. And if you don’t follow that syntax, the expression
will break. So anyway, we’ve got ThisProperty, ProperyGroup1,
PropertyIndex, so the index of Stroke One. So it says it’s got a value of three. If I move it up, it goes to two. So we know it’s working. Here’s where it gets interesting. The next level up is Taper 01. So you would think, if I change this to Group
Two, we should get the index value of Taper 01. But this is returning a value of two. And there’s only one group inside of Duplicate
Groups. If I duplicate this taper, the value doesn’t
change. I can do it as many times as I want. It’s always going to be two. So the reason this is happening is because
there’s actually an invisible layer of the hierarchy that we’re not seeing. To show you what I mean, I will grab the Stroke
Width. And let’s get rid of this; I will clear it
out. And I’m going to pick whip that Stroke Width. So let’s look at this layer structure that
it gave us. Starting at this layer, Contents, Duplicate
Groups, Contents, which we don’t see, Taper 01, Contents again, then Stroke One, the Stroke
Width. So the reason this is happening is because
there is an invisible layer of Contents inside every shape group. It’s a unique thing to shape layers, but it’s
very important to be aware of because when we’re using this Property Group command, we
need to account for those levels of the hierarchy even though we can’t see them. Alright, so let’s get rid of that expression,
and we can actually start doing some coding. So let’s go back to the Start value. I will load that back in. And I’m gonna get rid of this divided by two. Now obviously this line of code is not that
easy to look at. It’s pretty long and it would take you a little
bit to figure out what exactly it’s saying. It’s not very clear. But expressions allow you to create what are
called variables. And a variable is basically a way for you
to create your own shorthand so that your code is easier to look at. So I’m actually gonna clear out this entire
line of code. And I’m gonna start over by writing a new
variable. So, to write a variable, you start by typing
V-A-R for variable, and then you need to give it a name. So I’m going to name this End, and then an
equals sign, and then the line of code that you want End to contain. So, I want to go to the Effects and to the
End slider. And Expressionist can’t pick whip anything
from the Effects Controls, so that’s why it went down to the Effect. But then with that selected, I will click
on the pick whip, and end that variable with a semicolon. It’s every important that you end it with
a semicolon, or else After Effects will not know when that variable is supposed to end. But there you go. Now I can use End anywhere in my expression
after that line, and it will automatically interpret it as this line of code. Cool. So the next variable that I need is the Total
Groups. So I’ll make another variable and name it
Total Groups. And then I need to write the expression that
will give me the Total Groups. So I’m going to pick any property within this
Taper 01. So, we’ll just say the opacity, pick whip
it, and then I can get rid of everything on this line of code that I don’t need. Remember, I want to count the number of groups
within Duplicate Groups. So, I need to go to this layer, Contents,
Duplicate Group, Contents, that invisible layer of contents, and I can get rid of everything
else. Then I’ll type in a new expression. It’s very simple: dot NumProperties. And what that’s saying is take the number
of properties that are within the contents of that group. So now, I can write my equation. So I’ll drop down two lines and I’ll say End
divided by Total Groups. And I’ll end that with a semicolon. Now After Effects is pretty forgiving and
will generally still carry out a command even if you don’t end a line with a semicolon. But it’s just a good practice to get into
to make sure that there are no mistakes in your code and no errors pop up. So, just get into the habit of ending every
line with a semicolon. Alright, now that I’ve got that written, I
will apply it to the Start value. And the value goes to 90.7, which is exactly
the End value. So let me just make this 100% to make it more
clear. Why is the End value, 100, divided by the
Total Groups also 100? They’re two different groups, so it should
be 50, right? Well, the problem is, we defined Total Groups
to be the number of properties within Duplicate Groups, and the Master Group is not contained
within that. So the expression is actually working exactly
the way it’s supposed to, it’s just not what we want. So we need to account for this Master Group
within our variable for the Total Groups. And it’s very simple to do that. All I have to do is add a plus one after NumProperties,
and that will automatically increase the number of properties by one anytime it references
it. So let me reapply that to the start. And there we go, we’re back to 50%. And now, if I duplicate this group, you see
that the End value updates as well. Now, it’s not updating the way that I need
it to, but it is being based on that total number of groups, which is progress. So we’re doing great. Let’s delete those Duplicate Groups, and then
we need to add another factor into this, which is the Segment Length. So I actually need to duplicate my End slider,
and I’ll rename it Segment Length. And I need to define a variable for that slider. So I will drop down here and type in V-A-R,
SegLength, just for short. And then open up the Segment Length, pick
whip it, and finish off that variable. Now, I want to update my equation to be End
minus the Segment Length, divided by the total of groups. And if you remember back to your algebra days,
the order of operations applies here. And by that, I just mean multiplication and
division is going to happen before addition and subtraction. So this equation is going to play out like
this. It’s gonna take the Segment Length, 100, divided
by the Total Groups, two, so that becomes 50. Then it’s gonna take the End value, which
is 100, and subtract 50 from it. And it’ll do it in that order. So, let’s apply that to our Start value. And now when I duplicate this group, you see
this number is getting bigger, closer to 100, making the Segment Length smaller with every
duplicate. That’s working exactly the way it needs to. And that’s actually all we have to do for
the Start value. Now we can move on to the Duplicate Groups. Alright, hopefully you’re following along
with no problems. I know this is a lot to take in, but hang
in there, we’re making really great progress. Let’s get into the Trim Paths of the Taper
01 and start with the End value. Now, really, I want the End value of the first
duplicate to be in the exact same place as the Start value of the Master Trim Paths. Or another way to think about it is I want
the End value to be the same as the master end minus one Segment Length. Now, that might sound a little bit confusing,
so instead of talking about, I’m just gonna show you. Let’s write the expression for the End value. I’m gonna load that up into Expressionist
by Shift-clicking into the editor. And let’s define some variables. So, V-A-R, End, equals, and again, we’ll grab
that End slider. Then we’ll add a variable for the Group Index. And I’ll write the same expression we used
before. ThisProperty dot PropertyGroup3 dot PropertyIndex. And the reason I chose three is because one
level up is the Trim Paths, two levels up is that invisible layer of contents, and then
three levels up is Taper 01, which is the index value that I need. So ThisProperty, PropertyGroup3, PropertyIndex. Then I’m gonna define one more variable, and
I’ll put this on the second line. And I’ll name this Master Start. And this is going to be the Master Trim Path’s
Start value. And then one last variable for the Segment
Length. Now this Segment Length is gonna be different
than the actual Master Path’s Segment Length. I don’t want it to be base exactly on this
slider. Instead, I want it to be based on the trimmed
portion of the Master Path, so whatever the length that segment is. To find that, all I have to do is subtract
the Start value of the Master Path from the End value, which is the same as the End value
of the slider. Which is why I pick whipped the end slider
instead of the master end. So, for the Segment Length, very simply, I
just want to write End minus masterStart. So within this variable, I’m already referencing
variables that I defined up here. That’s an extremely powerful feature of variables. As long as the variable was defined before
this line, I can already use it. Alright, so now that all my variables are
defined, I’ll actually write the equation. I want this End value to be the End value
minus the Segment Length times the Group Index. So, let me walk you through this. The End value, master end, set here, minus
the Segment Length times the Group Index. And again, order of operations, it’s gonna
do that multiplication before the subtraction. The Segment Length is this segment, the Master
Path’s Segment Length, times the Group Index; in this case, it’s one. So, end minus one Segment Length. Let’s apply that to the End value. And it’s set to 50, which is exactly the same
as the Start value of the Master Trim Paths. I’ll set this Taper 01 to Multiply just so
you can see this is perfectly overlapping. So there’s no gap between the two lines. And if I adjust the Segment Length, you see
that that updates with it. And the End value also controls that. So what happens if I duplicate this group? Well, it offsets, and this is segmented evenly. I can duplicate this a bunch and you see that
all of these End values are spread out evenly, and the Segment Length proportionately spaces
everything out. So I hope you’re getting excited. This is actually working. Let’s delete the tapered groups. And now we need to do the same thing for the
Start value. And the variables can actually stay the same. So I’m actually gonna reuse this instance
of Expressionist. The equation just needs to change slightly. Instead of the Start value being based on
the End value of the Master Trim Paths, it needs to be based on the Start value. So instead of End, I’m gonna type in Master
Start. And I’ll apply that to the Start value. Everything else is the same. Now when I adjust the Segment Length, look
at that, the End value of the duplicate and the Start value of the master stays directly
in the center there, and everything else gets spaced out proportionately. I can duplicate this a whole bunch. And just like that, everything is perfectly
spaced out, and I’m able to adjust the length of that line and animate it exactly the way
that you would expect a shape layer to behave. If I move the offset angle, now there’s something
I forgot to do. I did not set up the offset of any of the
duplicates to be based on that, but that is an easy fix. I’ll just delete all of my duplicates, Option-click
on that offset, expression pick whip the offset value. Now that it’s all linked up, I’ll reduplicate
this a bunch of times, and now I can use that offset control exactly as you would expect
it to be used. So, that’s really awesome. We’ve already solved the first part of the
problem, which was automatically dividing up that segment based on the number of groups. Now obviously if I take off this Multiply,
this line looks exactly the same as it did when we started. So we need to solve the other half of the
problem now, which is offsetting the Stroke Width. So, take a deep breath, and let’s keep going! I’m gonna delete all these duplicates again. I’ll set this back to Multiply just so we
can see where the two lines are segmented. And I’ll collapse the Trim Paths for both
groups, and I will open up the Stroke One. This is where we’re gonna be working. And before I forget, I’m actually going to
link some of these properties up. I want the color of all the duplicates to
be driven by the color of the Master Stroke. So I will directly link that. I don’t think I’ll need to mess with the opacity,
so I’m gonna leave that the way it is. But let’s start writing the Stroke Width expressions. So I will select that and then Shift-click
into Expressionist to load that property up. And we’ll start by defining more variables. So let’s start with the Stroke Width. And pick whip the Stroke Width slider. Then we’re gonna need to know the Group Index,
which we can actually pull from the Trim Paths. That variable’s gonna be exactly the same. We find that, Group Index. Copy and paste that in. And we’re also gonna need to know the Total
Groups. So, I’ll define that variable, TotalGroups
equals. And I’ll just pick whip the Stroke Width. And, again, delete everything I don’t need. So, I need to know the Duplicate Groups’ contents,
the number of properties in there. So I’ll delete everything after that and type
dot NumProperties. And there’s my Total Groups. So, let’s write the equation. I want the Stroke Width to be based on the
slider’s Stroke Width. So I’ll type in strokeWidth divided by the
Total Groups times the Group Index. So let’s apply that expression to the Stroke
Width. And it stays at 100. Now, again, that is because we did not account
for the Master Group in our Total Groups. So I need to come back up to that variable,
add plus one at the end, and update that expression. And now it is half the width. Let’s duplicate this group a bunch of times. And it seems to be working, kind of? It’s not doing exactly what I expected. This taper is going in reverse. And the Master Group is on the wrong end. So the reason why this is happening is because
even though this counts Taper 01 all the way up to Taper 10, the index structure starts
at the top and goes down. So every new duplicate is actually the index
value of one. So Taper 10 is now one, nine is two, all the
way down the line. Taper One, which is here at the end, has the
Group Index of 10. So what I need After Effects to do is reverse
that index order. And it’s actually pretty simple. All I have to do is type in Total Groups minus
the Group Index. And I need this to be calculated before it’s
multiplied by the rest of the equation. So to make that happen, I just have to put
this within parentheses. So, what’s happening here is it’s gonna take
the total number of groups, so right now there are 10, actually 11, because of the extra,
and then subtract the Group Index from it. So if Taper 01 has an index value of 10, I’m
gonna take the total number of groups, 11, and subtract 10 from it, and it’s going to
become Group One. And, say, Group Seven… we’ll take the Total
Groups again, 11 minus seven is four. So that’s essentially reversing my index order. So I’ll delete all these duplicates, go to
my Stroke Width, and then reapply this expression. Now if I make some duplicates, look at that,
our stroke is tapering in the correct order. And if I have enough of these, I’ll turn off
the Multiply. That segmentation gets less and less noticeable. Now this is great, except that I have no way
to control how thick or thin this taper is. So we need to add one more piece of the equation
into our expression. And I’ll start by adding a new slider. I’ll just duplicate the end and rename this
Taper Out. Then I’ll delete all these Duplicate Groups. And this last part of the equation is a function
within expressions called linear interpolation. And that sounds complicated, but once you
understand it, it is an incredibly powerful tool. So, again, I’m gonna jump into a new composition. You don’t have to follow along with this. It’s just for a demo. But feel free if you want to. I’m going to make a square again, and I’m
gonna add a slider control to it. And this slider by default goes from zero
to 100. Now let’s say I wanted to change the rotation
of this layer, so I’ll bring that up. And rotation is measured in a value of degrees,
while the slider control is just a hard number. If I wanted this slider to control the rotation
of this square, where zero was zero degrees, but 100 was one entire rotation, that wouldn’t
work if I directly linked them together. And I’ll show you. If I just link this to the slider, the slider’s
set to 100, the angle of the rotation goes to 100. It doesn’t go to one revolution because one
revolution is actually a value of 360 degrees. Now linear interpolation allows me to remap
any range of values to another range of values. And I’ll show you what I mean by that. Let’s load this expression up, and I’ll define
this as a variable. So, V-A-R, Slider, equals, and then this code
for the expression. End it with a semicolon. And I’ll come down and say linear parentheses,
and then I need to tell the linear expression what values to look at. So, I’m going to type Slider. So I target the slider control, and then I
need four numbers. So I’m just gonna put a comma zero, comma
zero, comma zero, comma zero. So we have four numbers. This is completely arbitrary right now, but
I’ll tell you what these mean. The first number is the input minimum value,
and the second number is the input maximum value, so the range of numbers of that slider
that we want to pay attention to. So I want the range to go from zero to 100. So zero is fine, and the second number will
be 100. The second set of numbers is the output range. So, the minimum output and the maximum output. So when the slider is set to zero, which is
the input, I want to interpret that number as this number, the output. So zero is actually fine. When the slider is at zero, it should be at
zero degrees. But when the output slider is at 100, I want
the rotation to be 360 degrees. So I’ll type 360 degrees there. And then I’ll finish this off with a semicolon. And, just one more time, I’m gonna run through
this again, just so it’s crystal clear. We’re targeting the slider values and taking
the range of zero to 100 and remapping that range from zero to 360. Let’s apply that expression to the rotation. And now this is set to 100, and you see that
we have one full revolution. And if I adjust this slider, you see that
it makes an entire rotation from zero to 100. So that’s an example of what linear interpolation
can do. Now you can do a lot more than hard-coded
numbers in the linear interpolation. You can use variables, you can do equations,
and you don’t even have to use a full range of numbers. I could have said from a minimum input of
25 to, say, 75. And then if I reapply that to the rotation,
now, until this value reaches 25, nothing happens. But you see that as soon as it hits 25, it
starts rotating. And then once it gets to 75 is when that rotation
finishes its entire revolution, and then from 75 to 100, nothing happens. So it’s an extremely powerful function, and
it’s a key factor in getting our tapered stroke to work the way that we want it to. So let’s go back out to our tapered stroke,
and you can jump back in to following along. I’ll load up the Stroke Width again. And now that we have this Taper Out slider,
let’s put that into our variable list. So, V-A-R, and we’ll call it TaperOut, equals,
pick whip the Taper Out. Semicolon. And then I’m actually gonna take this equation
and make it a variable. So I’m gonna type V-A-R, and name this StrokeTaper
equals and then this equation. So now, anytime I type out StrokeTaper, it’s
just gonna interpret that as this entire equation. Now, our new equation is going to be a linear
expression. So, we start by typing… Whoops, I had my layer selected. let’s get back to the Stroke Width. Alright, there we go. So, linear, parentheses. And I wanna look at the Taper Out slider. So, TaperOut, comma, zero to 100, comma, StrokeWidth,
comma, StrokeTaper. And then end it with a semicolon. Now, what does this expression say? It’s saying take the range of zero to 100,
and in this case, I’m treating this kind of like a percentage. When the Taper Out is set to 0%, I want no
taper, and when it’s at 100%, I want the maximum taper. So, the range of zero to 100% is remapped
to the Stroke Width, which makes sense because when there’s no taper, the Duplicate Groups
should match the Stroke Width of the master. And when it’s at 100%, I want it to be the
stroke taper, which is our equation that makes the taper work. Anything in between is automatically interpolated
between those two values. So this is making the expression extremely
flexible, allowing us to control things with variables instead of fixed, hard-coded numbers. Let’s apply this to the Stroke Width and duplicate
the group a bunch. So now we have 10 Total Groups. And now, watch what happens when I adjust
this Taper Out slider. I hope I just blew your mind because that
is a working tapered stroke with full control of the taper. And if I duplicate this group a whole bunch,
and then maybe lower the Stroke Width to, say, 50, it’s starting to become really difficult
to see that there are any segments in there. And I can go ahead and modify this path to,
say, be a curve like this. And then maybe change the Segment Length so
it doesn’t take up the entire line. And this is a completely working tapered stroke. If I set some keyframes… Let’s zoom in here. You know, just something really simple. We’ll go from zero to 100 on the End value. And then I will just easy ease these keyframes
really quickly. And let’s RAM Preview. This layer animates exactly the same way that
a single path would on a shape layer, but we have these added controls of being able
to taper the stroke, control the Segment Lengths, and the Stroke Width. All right here with lots of calculations taking
place behind the scenes so that we don’t even have to think about it. All we’re left with are the animation controls
that we’re already used to using. And if I closed this path, and maybe made
this like a figure eight, then instead of animating the End value, I could animate the
offset. And I’ll just put it at one. And then I will RAM Preview that. And we now have a looping tapered stroke going
around this figure eight. So, it’s time to place your head between your
knees, take some deep breaths. We just built a freaking taper stroke rig
inside of After Effects on a single shape layer using expressions. That is pretty incredible. Now the way that I like to animate with this
is usually with a low number of groups, usually around 10. And then once I’m ready to render, I’ll really
crank up the duplicates. Now if I go ahead and do that, say there’s
40 groups, you might notice that After Effects is starting to slow down a little bit as I’m
working with this. And it’s just because with every group duplicate,
After Effects has to recalculate all of these expressions that we wrote for every frame. So typically, like I said, I’ll work with,
say, 10 groups, and that’s generally quick enough. And then once I’m ready to render, I’ll just
increase the duplicate count until that taper is no longer noticeable, and then you’re ready
to roll. Holy crap, that was a lot to take in! We just covered linking properties directly
with expressions, defining variables, writing equations, determining index values of groups,
and counting the number of groups within a group, and linear interpolation. I know that that was a lot to take in, and
if you’re anything like me, you’re probably pretty overwhelmed right now. But if you were able to follow along, and
you can grasp all the concepts that I covered, you are well onto your way to harnessing the
power of expressions to allow you to build things to make animation the priority, and
make really complex, intricate processes happen in the background so you don’t have to think
about it. Now, we can actually build a lot more functionality
into this rig, but we’re gonna save that for the next lesson. For now, give yourself a hand. Pat yourself on the back. That was an incredible amount of coding, especially
if you’re new to expressions. Now, if you got lost at any point, and you
really don’t feel like going back and figuring out what went wrong, you can always sign up
to be a VIP member of School of Motion and download my project file for free. Then you could just use my project and take
that tapered stroke rig that I just built and reuse it in any of your own projects. And again, I can’t say enough good things
about Expressionist. We didn’t even cover all of the amazing features
that it allows, but I’m sure you noticed that seeing this color-coded syntax makes looking
at these expressions much easier than working in these tiny little boxes with no highlighting
at all. It’d be much more difficult to catch mistakes
inside of this box. So, again, check out the link to Expressionist
on this page, if you’re serious about getting into writing your own expressions. Alight, that’s enough. Thank you so much for sticking with me through
that very long process. Now get out there and start making some tapered
stroke animations, and post your work online. Let us know what you make with this rig. Thanks again and stay tuned for the next lesson
where we’re gonna add more features to this rig using some more types of expression controllers.


36 Responses

  1. racheli munsa

    July 3, 2017 11:36 pm

    I saw this tutorial on your website

    And I could not register to download the Free Preset

    I'd love to get help because your training is amazing

  2. Mindaugas Dudenas

    October 5, 2017 2:20 am

    that's what I waited for some time. Someone to go more into scripting. That's awesome and please do not stop. If someone would go even further for making a script file with script UI that would be highly appreciated by all the community.

  3. Kallissa Hollins

    December 12, 2017 11:07 pm

    This expression isn't working for the End Trim Paths for the Duplicate Groups layer. I am following you step by step and it's not working. Please advise before I throw my keyboard. Thanks.

    P.S. I believe it's the third line since there's nothing to pick whip it to after var groupIndex =.

    Current Expression Used:
    var end = effect("End")("Slider");
    var masterStart = content("Master Group").content("Master Trim Paths").start;
    var groupIndex = thisProperty.propertyGroups(3).propertyIndex;
    var segLength = end-masterStart;


  4. Bob Smithson

    January 16, 2018 1:58 pm

    This is so helpful. I spent an hour trying to figure out how to do this and ran into a bunch of stupid paywalls. I cannot even :O

  5. Kevin

    January 16, 2018 4:55 pm

    This tutorial is absolutely fantastic, it goes quite full on if your new to scripting but Jake's teaching is spot on and easily guides you through, thanks guys, the rig is mega useful too.

  6. Fabian Torres

    March 4, 2018 7:43 pm

    It is kind of confusing, I will need to analyze it a couple of hundred times. But, this is a great tutorial, for mind agility, expressions comprehension, and logic, and magic and awesomeness, OMG!! this tutorial is wonderful, thank you so much for sharing.

  7. Daniel Hansen

    March 22, 2018 6:57 am

    This took a lot of effort but it was WELL worth it because now I have a tapered stroke rig ready to go for any project. THANK YOU SO MUCH

  8. Video Game Animation Study

    July 24, 2018 7:31 pm

    Unfortunately I couldn't get passed 19:59, I was using Expressionist and I couldn't see what the code was in the top left, nothing I was typing seemed to work, and I don't know enough about code to guess. Some commands on screen would have helped. Shame, I was looking forward to completing this.
    Great otherwise though.

  9. lesupercam

    August 30, 2018 9:14 pm

    How do I get my text in Expressionist to show the same colors as yours? Mine don't highlight the variables as anything other than grey, and propertyGroup and propertyIndex are also grey, can't find any options to change the theme or anything.

  10. ShadowRipper 25

    December 9, 2018 8:49 pm

    so, how do i write the code with out expressionist?? It would be great if you also showed how to do it with out expressionist.

  11. Boris Desgeyl

    January 21, 2019 3:42 am

    Very impressive and helpful, thank you!
    Could you make the project file available also for CS6? That would be fantastic! Thanks a lot.

  12. Alex Cleary

    February 5, 2019 2:29 am

    Seems like you could use the techniques from the Text Animators tutorial to achieve something similar (Jan 2019 video)?

  13. M.A. Nutile

    March 27, 2019 7:57 pm

    Great tutorial! Just confused by one thing: what is it that you do at 4:38, when you say "regroup that group?" It seems so simple but I've never seen it before.

  14. Matthijs K.

    April 2, 2019 3:02 am

    almost 00:00 over here and i just got done with this video.
    This is the best video about after effects i have ever watched. Thank you so so much.
    Now im gonna sleep and i will continue this journey tomorrow with the second part!!

  15. sunmonks

    June 7, 2019 2:59 am

    It's pretty amazing that after effects doesn't have a tapered stroke built in. It's really stupid. Thanks for the tut.

  16. Alex Ross-Edwards

    July 16, 2019 10:17 am

    Hey Jake, I know this is a year old, but the project doesn't seem to download anymore.

  17. Emilio Lopez

    November 24, 2019 9:09 pm

    Im literally stuck on how he makes the shape… I dont know how he makes a perfect rectangle with the Pen tool, or how he sets up those guidelines.
    Can anyone help?

  18. Panos Koutelas

    December 8, 2019 2:40 am

    Thank you for such an amazing tutorial. You just not only share your knowledge, you are sharing light!

  19. Maxim for all

    January 14, 2020 5:30 pm

    Here is the Project file for German AfterEffects, since the original file only works for English AE:


Leave a Reply