Tapering A Stroke with Expressions in After Effects Part 2

  • Share
 

Tapering A Stroke with Expressions in After Effects Part 2

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.

Download Project File
    00:00:00,879(light instrumental music)
    00:00:15,464(upbeat instrumental music)
    00:00:23,446- [Instructor] Hey, it's Jake Bartlett again
    00:00:24,637for School of Motion, and this is Lesson Two
    00:00:27,200of our tapered stroke rig, using expressions.
    00:00:30,797If you made it through Chapter One of this lesson,
    00:00:32,580you should already have a pretty good grasp on how all
    00:00:35,296of the expressions we need for this rig are working.
    00:00:38,475We'll add more complexity to the rig, but it will also
    00:00:41,104unlock a lot of extra features.
    00:00:43,788The good news is there's a lot of repetition
    00:00:45,625to this process.
    00:00:46,989So even if it's a little bit confusing at first,
    00:00:49,573just keep following along, and it should start to click.
    00:00:53,609Alright, so to start, just open up the project file
    00:00:55,932that we had from the previous lesson.
    00:00:58,385This one is exactly the same.
    00:01:00,133All I've done is modified the path so that we have
    00:01:02,685this nice curve here.
    00:01:04,788So I thought of some extra features that would make this
    00:01:06,865tapered stroke rig a lot more useful.
    00:01:09,901The first thing I thought of was just the ability
    00:01:11,783to reverse the taper.
    00:01:13,376So, the thick end is on this side, and tapers out
    00:01:16,272in the opposite direction.
    00:01:18,460Another great thing to have would be the ability to taper
    00:01:21,133from the center, and taper either end independently.
    00:01:25,104So let's jump right in, and take a look at how we could
    00:01:27,184make those two features a reality.
    00:01:30,264I'll start by adding a new expression control.
    00:01:32,814So come up to effects, expression controls,
    00:01:35,708and then checkbox control.
    00:01:39,613Now a checkbox control is just that.
    00:01:41,736It's a checkbox that you can turn on or off.
    00:01:44,519So the values that they return are zero for off,
    00:01:48,489and one for on.
    00:01:50,548And we can use that in combination with some new
    00:01:52,604expressions, to enable or disable that reverse taper.
    00:01:56,475So let's start by renaming this checkbox control
    00:01:58,939reverse taper.
    00:02:02,523And the way that the reverse taper will actually work
    00:02:04,781is by reversing the order of the stroke width offset.
    00:02:08,642And if you remember, when we first built this taper,
    00:02:11,352the original equation we wrote for the duplicate groups'
    00:02:14,541stroke widths was tapering in the opposite direction.
    00:02:18,941So we already kind of know how to make this work.
    00:02:22,295I'm gonna delete all these duplicate groups,
    00:02:24,332and open up taper01's stroke.
    00:02:27,776I'll load the stroke width equation.
    00:02:30,448And if we take a look at the variable for the stroke taper,
    00:02:33,129remember that we put this in parentheses.
    00:02:35,872Total groups minus the group index,
    00:02:38,125to get the taper to go in the right direction.
    00:02:40,932But if I duplicate this variable ...
    00:02:45,176And give it a new name, say, reverse stroke taper ...
    00:02:51,844And then take off this total group's minus
    00:02:55,692and the parentheses around it.
    00:02:57,387That equation should give us the taper in
    00:02:59,674the opposite direction.
    00:03:01,171But how do we get that variable to come into effect
    00:03:04,417when this reverse taper is checked?
    00:03:07,442Well, we need to use what's called a conditional statement.
    00:03:10,642And a conditional statement is just another type
    00:03:12,490of expression that you can set conditions for,
    00:03:15,682and if those conditions are met, one line of code
    00:03:17,970will happen, and if those conditions are not met,
    00:03:20,466it moves on to the next line of code.
    00:03:22,916That might have been really hard to take in.
    00:03:24,841So let's just start writing it, so you can see
    00:03:27,140exactly how it works.
    00:03:29,155I'll drop down one line, and start writing my statement.
    00:03:32,928So a conditional statement always starts with an if.
    00:03:36,602And then an open parentheses.
    00:03:39,471Now my condition is going to be based off of the
    00:03:41,299reverse taper checkbox.
    00:03:42,762But I don't have any way to reference that yet.
    00:03:45,314So I need to define it as a variable.
    00:03:47,922So I'll come back up here, and type VAR
    00:03:50,826reverse taper, equals ...
    00:03:54,521I'll find that reverse taper checkbox control,
    00:03:57,361and pick whip it.
    00:03:59,913Then close that out with a semicolon.
    00:04:02,365And now I can reference that.
    00:04:03,553So, if the reverse taper
    00:04:08,282equals one ...
    00:04:11,438And in a conditional statement, the syntax for equals
    00:04:14,309is actually two equal signs together.
    00:04:17,390And one is the value when the checkbox is checked.
    00:04:21,297So, if the reverse taper is checked, then I'll go outside
    00:04:25,433the parentheses, and add an open curly bracket.
    00:04:30,667Expressionist automatically generates the closing curly
    00:04:33,353bracket, because it knows that I'm going to need that
    00:04:35,340at the end of whatever is contained within it.
    00:04:38,941Then I'm going to press enter, to drop down a line,
    00:04:41,964and again Expressionist has done something for me.
    00:04:44,485It's indented my line, which is the same as pressing tab,
    00:04:48,565and it's dropped that curly bracket down one more line.
    00:04:52,411So these are all time saving functions of Expressionist.
    00:04:55,153And, when you're writing a lot of code,
    00:04:57,045every little bit helps.
    00:04:58,841None of these features are available in After Effects'
    00:05:01,117native expression editor.
    00:05:02,954But why do I need this indentation and this curly bracket
    00:05:05,984on the next line?
    00:05:07,375Well, when you're writing code, things can get very messy,
    00:05:11,367and very hard to look at.
    00:05:13,183And, using this type of indentation, and the placement
    00:05:16,195of these containers, makes everything much more organized
    00:05:20,243and easy to look at.
    00:05:21,936So for example, conditional statements have a hierarchy,
    00:05:25,083which looks like this.
    00:05:26,370You start with an if statement, and the condition.
    00:05:30,306Then you have a line of code for whatever you want
    00:05:33,096that value to be.
    00:05:35,045If that condition is met, and you close that off
    00:05:37,827with a curly bracket, then we would type ...
    00:05:40,953Else, and then another curly bracket,
    00:05:45,221drop down another line, indent.
    00:05:47,849And then the second line of code that you would want
    00:05:49,676to happen, if that condition isn't met.
    00:05:52,900So else is basically saying otherwise, if that condition
    00:05:55,802is not met, do this.
    00:05:58,840So one more time, the basics of the conditional statement
    00:06:01,292is, if something is true, do this.
    00:06:05,065Otherwise, do this.
    00:06:07,661So what do we want to happen if the reverse
    00:06:09,013taper is checked?
    00:06:10,817Well I want a similar equation to what we already had,
    00:06:14,381so I'll copy and paste that inside that curly bracket.
    00:06:18,405Another feature of Expressionist I want to point out
    00:06:20,265really quick, is you see that when I have my cursor right
    00:06:23,137after a curly bracket, or any type of container,
    00:06:26,713the corresponding closing or opening container
    00:06:30,189is highlighted blue.
    00:06:32,057So I know that everything between these two highlighted
    00:06:34,983brackets is what's included in this conditional statement.
    00:06:38,613Same thing is true for these parentheses.
    00:06:40,429If I click on that, both of the parentheses light up blue.
    00:06:43,697So, that's super handy.
    00:06:45,783Alright, back to our equation.
    00:06:47,412If reverse taper is checked, we want to do the same
    00:06:49,537linear equation, but instead of tapering to the stroke
    00:06:53,309taper variable, we want to go to the reverse
    00:06:56,861stroke taper variable.
    00:06:58,645So I will write that in, reverse stroke taper.
    00:07:04,099Otherwise, if reverse taper is not checked,
    00:07:07,005then I want to do my regular equation.
    00:07:09,039So I'll cut and paste that in between
    00:07:11,581these two curly brackets.
    00:07:13,681And that finishes off the conditional statement.
    00:07:16,477So let's apply this to the stroke width
    00:07:18,157of the duplicate group.
    00:07:20,249And then I'll make a bunch of duplicates ...
    00:07:23,184And we'll see what happens when I turn the
    00:07:25,913reverse taper checkbox on.
    00:07:28,760Well for the most part, it's working.
    00:07:30,513It looks like that taper has been reversed.
    00:07:32,733The problem is that master group at the end there
    00:07:36,497hasn't changed at all.
    00:07:37,969And that's because the master stroke width doesn't have
    00:07:40,477any of that conditional expression applied to it.
    00:07:43,513So we need to go add that conditional statement.
    00:07:45,857So, I'll just load that up.
    00:07:48,321And this value's just being driven directly
    00:07:50,289by the stroke width slider.
    00:07:52,313So let's define this slider as a variable.
    00:07:54,933So VAR stroke width equals ...
    00:07:58,923Then that effects slider.
    00:08:00,772Next we're going to need some variables that
    00:08:02,929we've already defined other places.
    00:08:04,789So I'm just gonna open up the stroke width for the duplicate
    00:08:07,967group, and we're going to need the taper out.
    00:08:12,543So I'll copy that and paste it.
    00:08:15,303We're going to need the total groups.
    00:08:18,253So I'll copy that,
    00:08:20,299and paste it.
    00:08:21,928And then we're gonna need the reverse taper checkbox.
    00:08:24,093So let's copy that.
    00:08:28,001And now we should be able to write
    00:08:28,834our conditional statement.
    00:08:30,377So let's drop down, and start again by typing if,
    00:08:34,740open parentheses, reverse taper, equals ...
    00:08:40,629And again, you have to put two equals signs
    00:08:42,521to represent equals.
    00:08:44,551One, which again, just means that the checkbox is checked.
    00:08:49,171Zero is unchecked, one is checked.
    00:08:52,076And I'll go outside the parentheses,
    00:08:53,903and type my open curly brackets.
    00:08:57,215Enter down and indent.
    00:08:59,349So if reverse taper is checked, then this happens.
    00:09:03,377So what happens?
    00:09:04,773Well, we need to use linear interpolation.
    00:09:07,193So, linear, parentheses ...
    00:09:11,152And we need to look at the taper out slider,
    00:09:15,013comma, with a range of zero to 100,
    00:09:20,600interpolated to a range of stroke width
    00:09:25,528to stroke width divided by total groups.
    00:09:31,641And end that all with a semicolon.
    00:09:34,577So when the taper out is set to zero, we want the stroke
    00:09:37,869width, and when it's set to 100, we want it to be
    00:09:40,245the stroke width divided by the total groups.
    00:09:42,860Nothing really new in that equation.
    00:09:45,281Then we'll drop down after this curly bracket,
    00:09:47,424and say else, open curly bracket.
    00:09:51,165Drop down and indent.
    00:09:52,917Stroke width ...
    00:09:55,621Which is the same as what we had before we just wrote
    00:09:57,713this a conditional statement.
    00:09:59,737So let's look at this one more time.
    00:10:01,673If the reverse taper is checked, do this.
    00:10:06,473Otherwise, do this.
    00:10:09,421Simple as that.
    00:10:10,717Let's go down to our stroke width for the master group,
    00:10:13,457and apply it.
    00:10:15,239And just like that, our stroke width now fits
    00:10:17,238at the tail end.
    00:10:18,945Now, something strange is happening.
    00:10:20,916If I turn on multiply for all of the duplicate groups,
    00:10:23,938you'll see that the last duplicate group is 28 pixels wide,
    00:10:29,065but so is the master group.
    00:10:32,355And that's because we accounted for this extra master group,
    00:10:36,481in the variable for the total groups within
    00:10:38,857the duplicate stroke widths.
    00:10:40,672So let me load that up, and show you.
    00:10:43,081Right there, at the end of total groups,
    00:10:45,063we added one to compensate for the fact that
    00:10:48,659the taper should be starting with the master group.
    00:10:52,479So to fix that, all we have to do is add a one to
    00:10:56,691the group index on this reverse stroke taper equation.
    00:11:02,018So if I just put group index within parentheses ...
    00:11:07,462And then add plus one after group index,
    00:11:11,390that will automatically increase the group index of every
    00:11:14,654group, when the reverse stroke taper comes into play.
    00:11:18,934So, that should solve the problem.
    00:11:20,324Let's apply that to the duplicate.
    00:11:23,360Delete all of the other duplicates,
    00:11:25,396and then reduplicate that group.
    00:11:28,464(laughs) And this is a process we'll be doing a lot
    00:11:30,345through this lesson, so just bear with me.
    00:11:32,756It's a lot of back and forth, of deleting groups,
    00:11:34,874and then reduplicating.
    00:11:36,308Alright, so, now that looks like it's working.
    00:11:39,508I'll get rid of all the multiplies.
    00:11:42,830And now you can clearly see that the master group
    00:11:45,888is as different stroke width than the group before it.
    00:11:49,144And if I uncheck the reverse taper,
    00:11:51,672the taper goes back to normal.
    00:11:53,365So that is functioning exactly the way that we need it to.
    00:11:56,553Awesome!
    00:11:57,521On feature down.
    00:11:58,566And we just learned the basics of conditional statements,
    00:12:01,074which is really what we'll been using for all of the other
    00:12:03,582features that we're going to to implement into this rig.
    00:12:06,423So if that went a little bit over your head, don't worry.
    00:12:08,799We're gonna be using a lot of different conditional
    00:12:10,702statements, so if you don't already have the hang of it,
    00:12:13,252you probably will by the end of this lesson.
    00:12:16,167Alright, so next we want to taper the stroke on
    00:12:18,775either end independently from the center.
    00:12:22,292So I'm gonna need another checkbox.
    00:12:24,879I'll duplicate this one and name it taper in/out.
    00:12:31,215And then I'll need another slider, so I'll duplicate
    00:12:33,615this taper out and rename it taper in.
    00:12:39,323Now there are a lot more things you can do with
    00:12:40,886conditional statements than just checking to see
    00:12:43,239if a checkbox is enabled.
    00:12:45,228And we're gonna have to get a little bit more complex
    00:12:47,363to make this taper in and out function.
    00:12:50,742But again, it's going to be based on the stroke width,
    00:12:53,403so we can keep working on this same expression.
    00:12:55,855We need to add in variables for the new controllers
    00:12:58,023that we just made.
    00:12:59,190So, I'll type in VAR taper both, for the taper in and out.
    00:13:05,262So I'll find that checkbox,
    00:13:08,002pick whip, semicolon.
    00:13:10,530And then we need a variable for the taper in.
    00:13:12,859So I will just copy and paste this expression,
    00:13:15,526and then just by hand, update it to be taper in.
    00:13:19,530And then the name of that slider is taper in.
    00:13:23,212So that's all I have to do to define that variable.
    00:13:25,954And we're going to add another condition to our expression.
    00:13:29,944So right now we just have a single if statement.
    00:13:33,126And then a final else statement.
    00:13:36,326But, if I drop this else statement down one line,
    00:13:40,197I can write another curly bracket to close off
    00:13:42,782the expression above it, and type else if,
    00:13:47,778and start writing another condition.
    00:13:50,174So that's exactly what I'll do.
    00:13:51,647I'll type parentheses, and this condition is going
    00:13:54,850to be based on the taper in and out checkbox.
    00:13:57,918So, taper, both, equals, one.
    00:14:03,606So if the taper both is checked, then,
    00:14:07,684drop down an indent ...
    00:14:09,808And I actually don't need this second curly bracket,
    00:14:12,492because I've already got one on the next else statement.
    00:14:16,385And if I left that extra curly bracket in there,
    00:14:18,520it would mess up the conditional statement.
    00:14:20,212So I'm gonna get rid of that one,
    00:14:22,523bring that back up, and go to my indented line.
    00:14:25,963So, if taper both is checked, then what needs to happen?
    00:14:30,180Well, here's where we're gonna get clever,
    00:14:31,961and even a little bit more complex.
    00:14:34,281You don't have to just write a single equation
    00:14:37,138as a result of a condition.
    00:14:39,100You can actually put a condition within a condition.
    00:14:42,696Some might say it's an "expressionception".
    00:14:45,765Alright, that was terrible.
    00:14:46,865But let's go ahead and write another condition,
    00:14:49,264within this condition.
    00:14:50,684So, I will start by saying if, just like normal.
    00:14:54,269Open parentheses, and then the condition I want to know
    00:14:57,689is if the group index, for the group this expression
    00:15:00,832is contained in, is greater than the total groups
    00:15:06,617divided by two ...
    00:15:09,180Or in other words, half of the total groups.
    00:15:12,392Then, I want something to happen ...
    00:15:15,086Else, or otherwise, I want something else to happen.
    00:15:19,629So let's take a look at this condition.
    00:15:21,445The reason why this is a clever expression is because
    00:15:23,689it's going to be based on what the group index is that
    00:15:27,233the expression is written on.
    00:15:29,136So depending on where the group is in this stack,
    00:15:31,929one thing will happen.
    00:15:33,435And if it's in another location, another thing will happen.
    00:15:36,209So one half of this line is going to be affected by
    00:15:39,928the first line, and the other half will be affected
    00:15:42,017by the other line.
    00:15:44,152So what do we want to happen on the groups that are
    00:15:45,868an index value greater than half of the groups?
    00:15:49,551Well let's make sure we know which groups those are.
    00:15:52,321Taper 01 should be an index value of 11,
    00:15:56,104because there are ten duplicate groups, plus one.
    00:16:00,107Right here, we've got plus one,
    00:16:01,881to account for that master group.
    00:16:04,345So, taper one should be a value of 11.
    00:16:07,128So yes, that is greater than half of the total groups.
    00:16:10,921So group one is on this tail end.
    00:16:13,825So if taper both is checked, we want the taper to go
    00:16:16,827in the same direction for that half of a line.
    00:16:20,625So really, I can just copy the expression for
    00:16:22,472the regular taper, and paste that into that section.
    00:16:26,893If the group index is not greater than half the total
    00:16:29,612groups, then I want it to taper in the other direction.
    00:16:33,540Or, reverse the taper, which I have the line of code
    00:16:36,652for right up here.
    00:16:38,181So I'll just copy and paste that.
    00:16:40,885And we can apply that to the stroke width.
    00:16:44,162Then I'll delete all of the duplicates, reduplicate them,
    00:16:47,397and then enable the taper in and out.
    00:16:52,788Now, it's kind of working.
    00:16:54,415Again, the master group is outside of these expressions,
    00:16:57,925so it's not being affected by it.
    00:17:00,137So I'm just going to shut it off for now.
    00:17:02,645And, it actually does look like it's tapering
    00:17:05,041from the center on to both ends.
    00:17:08,297There are a few issues.
    00:17:10,037Number one is that if I adjust the taper in slider,
    00:17:13,645nothing is happening.
    00:17:15,404And if I adjust the taper out, it's affecting
    00:17:18,153both ends at the same time.
    00:17:20,652Now, that is because when I copied and pasted these
    00:17:23,634expressions from the reverse taper and the regular taper,
    00:17:26,945I did not update the linear expression to target
    00:17:30,782the taper in, instead of the taper out.
    00:17:34,388So I'll take this linear equation and change
    00:17:36,853taper out to taper in.
    00:17:40,014Now if I reapply that, that should fix the problem.
    00:17:43,806I'll delete these groups, and reduplicate.
    00:17:49,682And there we go, now that slider is affecting the first
    00:17:53,002half, and the taper out slider is affecting the second half.
    00:17:57,118That's great, it's working the way that it should.
    00:17:59,726But, there is another issue.
    00:18:02,190When these two numbers aren't the same, you see that
    00:18:05,063they don't flow together very nicely in the middle.
    00:18:08,565Now the reason this is happening is because the way that
    00:18:11,707this expression is dividing the groups in half,
    00:18:15,042we're basically cutting the number of groups
    00:18:16,547for each taper in half.
    00:18:19,530So if I disable this, you see that the taper
    00:18:21,739keeps getting larger.
    00:18:23,292And when I check it, it leaves this part of the taper
    00:18:26,407the way it was, and shrinks down the front half
    00:18:28,695of the taper to mirror it.
    00:18:30,710Instead, I want this middle section to be the stroke width.
    00:18:34,206And that's actually another really easy fix.
    00:18:36,318All I have to do is come in here and account for the fact
    00:18:39,739that there are half the number of groups.
    00:18:42,291So at the end of each linear interpolation,
    00:18:45,085I will just add a times two.
    00:18:48,736And I'll do that up here on this one as well.
    00:18:52,114And that will double the taper amount for each half
    00:18:54,039of the line, when the taper both is checked.
    00:18:57,305So, we'll reapply this to the stroke width,
    00:18:59,896delete the duplicates, and reduplicate.
    00:19:05,240Now the line is thicker at the middle.
    00:19:07,450If I uncheck, you see that now the stroke width
    00:19:09,620is just shifted to the center, rather than
    00:19:12,512shrinking down the front half of the line.
    00:19:15,580And again, the taper out slider is affecting that half,
    00:19:18,924the taper in is affecting this half.
    00:19:21,136And they fit together nicely.
    00:19:23,994Now we need to turn on our master group,
    00:19:26,050and account for that.
    00:19:27,636So, let's go ahead and load up that stroke width.
    00:19:31,149And, I can copy over some of the variables that
    00:19:33,139we just defined for the duplicate groups.
    00:19:35,326So, I'm going to need to know this taper both.
    00:19:38,791So I'll copy that.
    00:19:40,651And paste it here.
    00:19:43,172And, I just noticed that that was missing a semicolon.
    00:19:45,953So I'm just going to finish that off.
    00:19:49,001Like I aid, After Effects is generally pretty smart,
    00:19:51,488and knows when things should end and begin.
    00:19:54,612But, be consistent and just end lines with those semicolons.
    00:19:59,989Alright, what other variables do we need?
    00:20:02,111We'll need that taper in.
    00:20:04,477So I'll copy that,
    00:20:07,469paste, and I think that's it.
    00:20:09,605So after the reverse taper condition, I will drop down
    00:20:12,409this else, and type closing bracket,
    00:20:17,100else, if, parentheses,
    00:20:20,344taper both, equals one,
    00:20:23,674curly bracket, drop down an indent.
    00:20:26,346I can delete this curly bracket, because I have one
    00:20:28,186right here to close that statement.
    00:20:30,272And I don't need to add that second level to find out
    00:20:32,319which half of the line it's on.
    00:20:34,234I already know which equation it should be using.
    00:20:36,710It's the same as the reverse taper.
    00:20:39,590So I'll copy and paste that expression.
    00:20:43,386And then multiply this by two at the end.
    00:20:46,883That should be all I have to do.
    00:20:47,842So, I'll go to the master stroke.
    00:20:50,032Now that master stroke fits in with the rest of the taper.
    00:20:53,644So if I adjust these sliders, everything is working
    00:20:56,229just the way it should.
    00:20:58,054Now here's an interesting problem with conditions.
    00:21:01,059If I check the reverse taper checkbox, taper in and out
    00:21:05,327no longer functions, even though it's still checked.
    00:21:08,595And the reason why that happens, is because a conditional
    00:21:10,933statement, as soon as it's met ...
    00:21:13,951The equation underneath it will be applied,
    00:21:16,204and then After Effects will stop.
    00:21:18,395It will completely ignore everything after
    00:21:20,362that condition is met.
    00:21:22,323So because reverse taper is first in this list,
    00:21:24,875if that statement is true, it's going to apply
    00:21:27,911this equation, and it's going to stop right there.
    00:21:31,187Now I want this to function so that even if
    00:21:33,112the reverse taper is checked, the taper in and out
    00:21:36,204checkbox takes priority.
    00:21:38,459And we can actually do that pretty easily.
    00:21:41,155All I have to do is come up to this reverse taper condition,
    00:21:44,587and add another condition to it.
    00:21:48,568So you can actually have multiple conditions within
    00:21:50,701any conditional statement.
    00:21:52,559So I want to add after this reverse taper equals one,
    00:21:56,224two ampersands, which translates to and.
    00:22:00,853And then I'll type taper both equals zero.
    00:22:05,352Or, taper both is unchecked, then reverse the taper.
    00:22:10,436But, if either of these statements is not true ...
    00:22:14,044So the reverse taper is off, or taper both is on,
    00:22:17,684ignore this line of code, and go to the next statement.
    00:22:20,961So this should work exactly how I want it to.
    00:22:24,120So apply this to this master stroke,
    00:22:26,987and then I will come in to my duplicate strokes,
    00:22:29,729and I'll do the same thing.
    00:22:31,984If reverse taper equals one, and taper both
    00:22:36,065equals zero, reapply that.
    00:22:42,280Delete the duplicates ...
    00:22:45,085And reduplicate.
    00:22:49,716Alright, now both checkboxes are checked, but,
    00:22:52,092taper in and out is what's getting the priority.
    00:22:55,237If I uncheck taper in and out, my stroke still
    00:22:57,921tapers in reverse.
    00:22:59,502And I can uncheck reverse taper, and it goes back to normal.
    00:23:03,236If I check just taper in and out, that still works.
    00:23:06,997Alright, we're in business.
    00:23:08,120We've got two of these features
    00:23:09,206already completely functioning.
    00:23:11,286Now, let's say that you were using this taper on something
    00:23:14,412like a write on, where you had letters that you were
    00:23:17,731revealing through the tapered path.
    00:23:20,317You would probably want a trail to be left out
    00:23:23,596the same width as the smallest stroke.
    00:23:26,432Well, believe it or not, that is actually
    00:23:27,973really simple to do.
    00:23:30,120All I have to do is load up the trim paths'
    00:23:32,503start value of the duplicate groups.
    00:23:35,532And we're gonna need an extra checkbox,
    00:23:37,389so I'll duplicate this, and rename it trail.
    00:23:41,832And then we'll define that as a variable in this list.
    00:23:45,020VAR trail equals ...
    00:23:48,772I'll get that checkbox in the list.
    00:23:50,650And pick whip it.
    00:23:54,795And then we'll write a conditional statement.
    00:23:57,031So this one's pretty simple.
    00:23:58,781We'll start by typing if, trail, equals one ...
    00:24:04,710And, group, index,
    00:24:09,445equals, total groups.
    00:24:13,859Then, zero.
    00:24:18,819Else, the equation we already had.
    00:24:24,570So what this is saying is, if the trail is checked,
    00:24:27,843and the group index that this expression is applied on,
    00:24:30,702equals the total number of groups ...
    00:24:33,223Or in other words, if the group index is the last
    00:24:36,708group in the line,
    00:24:38,908make the start value equal to zero.
    00:24:41,791Not a variable, not another property.
    00:24:44,343Simply just a value of zero.
    00:24:47,356Otherwise, do exactly what you've already been doing.
    00:24:50,436And before I go any further, I need to make sure that
    00:24:51,999I actually define total groups as a variable up here.
    00:24:55,903Otherwise, there's nothing for it to reference.
    00:24:57,951So, I think the stroke width of the master stroke has that.
    00:25:02,480Yep, right there, total groups.
    00:25:04,998We'll copy and paste that in here.
    00:25:07,235And, this line of code is accounting for the master group.
    00:25:11,315I actually don't need that to happen in this instance.
    00:25:15,395I'm only concerned with the total number of groups
    00:25:18,035within this duplicate group's stack.
    00:25:21,699So I'm going to delete that plus one.
    00:25:24,943And that should be everything we need
    00:25:26,351for this expression to work.
    00:25:28,091So I will apply it to the start value.
    00:25:31,687Delete the duplicates, and reduplicate.
    00:25:36,891Now when I click the trail checkbox,
    00:25:39,672the last duplicate in this list has a start value of zero
    00:25:44,547on its trim paths.
    00:25:46,019Because we hard coded that value of zero,
    00:25:48,303for when that checkbox is checked.
    00:25:50,518And it still reacts to the taper out, because
    00:25:52,498this expression is written on the trim paths,
    00:25:55,118so it's not affected by the other conditions
    00:25:57,174we have on the stroke width.
    00:25:59,562So that means that I can reverse the taper,
    00:26:01,354and it still works, and I can do the taper in and out,
    00:26:04,522and it still works.
    00:26:06,050So that was pretty painless.
    00:26:07,745Now I just want to talk about how you might animate
    00:26:10,242this line a little bit.
    00:26:12,121So, if you set a key frame on the end value, and
    00:26:16,854start it at zero, and then go forward a little bit in time,
    00:26:20,218and set it to 100 ...
    00:26:22,494Maybe I'll just easy ease these key frames,
    00:26:25,883and ran preview.
    00:26:29,369Alright, so very simple animation.
    00:26:31,535But right here at the front end,
    00:26:33,486you see that as soon as this value goes past zero,
    00:26:37,649the front end of the taper just pops on, it just appears.
    00:26:41,190And I'm not really happy with the way that that looks.
    00:26:43,710So I guess I would need to animate the stroke width along
    00:26:47,074with that, and possibly the segment length at the same time.
    00:26:51,322So let me go to right about here, where it's the first frame
    00:26:54,654that you can see the entire line, and I'll set a key frame
    00:26:57,702for the stroke width, and the segment length.
    00:27:00,705And then I'll go back to the first frame,
    00:27:03,354and change those values down to zero.
    00:27:07,877Then I'll probably want to easy ease these key frames
    00:27:10,473as well, and then we'll ran preview.
    00:27:13,938Alright, so that definitely looks better.
    00:27:15,718It doesn't just appear out of nowhere, it kind of grows.
    00:27:19,414But because these key frames are eased, and these key frames
    00:27:24,005aren't in the exact same place, and they're also eased,
    00:27:26,855it's not as fluid as I would like it to be.
    00:27:29,923And if I went into the graph editor, and modified these
    00:27:32,883at all, then where these two key frames are positioned
    00:27:37,283has to be completely changed.
    00:27:39,031So this is not a very easy way of dealing with this
    00:27:41,639very simple animation.
    00:27:43,827It'd be great if I didn't even have to think about
    00:27:45,710the stroke width or the segment length, and that scaling
    00:27:48,734automatically happened, based on how much of this path
    00:27:52,122was actually visible.
    00:27:54,267Well, that's exactly what we're going to do next.
    00:27:56,983So let me get rid of these key frames.
    00:27:59,772And we'll start with the segment length.
    00:28:02,541And the nice thing about the segment length is that
    00:28:04,530it's all being determined by the master trim paths.
    00:28:07,985Remember, all of these segments are the exact same length
    00:28:10,922as the master groups length.
    00:28:13,681So if I modify this one expression, it will reflect
    00:28:17,345in all of the other duplicates.
    00:28:19,698So I need another checkbox, and I'm going to name it
    00:28:22,370auto shrink in, and then I need to make a variable
    00:28:26,210for that checkbox.
    00:28:27,911So VAR, auto, shrink, in ...
    00:28:31,511Equals, then pick whip.
    00:28:38,686And I need to write a condition.
    00:28:40,666So, if, auto, shrink, in,
    00:28:45,416equals, one, then ...
    00:28:50,453And we'll write something there.
    00:28:52,215But first, I'll finish off this conditional statement.
    00:28:54,679Else, this line of code we've already got.
    00:29:01,750Okay, so now let's go back up and write the actual equation.
    00:29:04,867So, if auto shrink in is checked, then we want to do
    00:29:07,527a linear interpolation.
    00:29:09,220So, linear ...
    00:29:11,256And we're going to look at the end value.
    00:29:13,708So, end, comma.
    00:29:16,566I want the range to be zero, to segment length, comma,
    00:29:23,024end, comma, this equation right here.
    00:29:28,744But I need to move that semicolon on the outside
    00:29:30,891of that parentheses.
    00:29:33,256Alright, so what is this expression saying?
    00:29:35,289Take the end slider's range from zero to segment length,
    00:29:39,700and I'm going to move that segment length up.
    00:29:41,812So whatever this segment length is set to,
    00:29:45,015and remap the values from the end value to the equation
    00:29:48,753we're already using.
    00:29:50,448So, let's apply this to the start value,
    00:29:52,319and see what happens.
    00:29:54,659If I turn auto shrink in on,
    00:29:57,400and then back this end slider up,
    00:30:00,723you see that as soon as this slider hits the segment
    00:30:04,748length of 50, the segment length starts to collapse.
    00:30:09,743And none of the path actually disappears,
    00:30:11,943it's all just collapsing down on each other.
    00:30:14,670If I change the blend mode of the duplicates to multiply,
    00:30:17,188this will be easier to see.
    00:30:19,851And maybe I'll knock down the number of duplicates to five.
    00:30:23,260So as the end slider closes in from the segment length
    00:30:25,935down to zero, you see that the segment length
    00:30:28,538is actually collapsing.
    00:30:30,972That's exactly what I wanted.
    00:30:32,894So that's the first part of the problem.
    00:30:34,639I'll change these back to normal.
    00:30:36,499The next part of the problem is that the stroke width
    00:30:38,588also needs to collapse down.
    00:30:40,735But the duplicate stroke widths are not based on the master
    00:30:43,439stroke width, so there's gonna be a few more steps.
    00:30:46,981Let's start with the master stroke though.
    00:30:50,624I'll extend this out so I can see the whole line.
    00:30:53,361And then I'll go into the master stroke.
    00:30:56,182I'll load that up, and this is where I'm going to point out
    00:30:59,076that these conditional expressions can get very complex,
    00:31:03,135the more features you add.
    00:31:05,039Because remember, if one set of conditions is met,
    00:31:08,360then all of the other conditions are ignored.
    00:31:11,649So I'm going to write this condition as if none
    00:31:14,508of the other checkboxes are checked.
    00:31:16,982A little later, we'll come back to figuring out
    00:31:18,953how to get it to work with the other checkboxes.
    00:31:21,822But for now, let's just say these checkboxes are unchecked.
    00:31:25,001So, I'm going to add another conditional expression
    00:31:27,445right before else.
    00:31:29,839So I'll add the closing bracket,
    00:31:32,347else, if, parentheses.
    00:31:36,397And I need to get that variable that I defined
    00:31:38,178for the auto shrink in,
    00:31:40,079from the master start.
    00:31:41,777So, let's find that variable.
    00:31:44,248There we go, auto shrink in.
    00:31:46,341And we'll ...
    00:31:48,277Copy that, and paste it here.
    00:31:52,060And then I will type auto, shrink, in, equals one.
    00:31:58,485Then I'll get rid of this extra curly bracket.
    00:32:02,236So if auto shrink in is one, I want
    00:32:04,657another linear interpolation.
    00:32:06,569So linear, end, comma.
    00:32:09,958And again I don't have the end value defined
    00:32:12,716in my variables list.
    00:32:14,382So let me grab that.
    00:32:17,008Copy and paste it.
    00:32:19,879So, linear, and, zero,
    00:32:22,908to segment length,
    00:32:24,800comma, zero, comma, stroke, width.
    00:32:29,916But I'll end that with a semicolon.
    00:32:32,322So for the master stroke, it's not that complicated at all.
    00:32:35,427I'll apply that ...
    00:32:37,627Oh, and it looks like I forgot to add
    00:32:39,387the segment length variable.
    00:32:41,244So let me just copy and paste that real quick.
    00:32:46,427You see that Expressionist gives me the same
    00:32:48,296error message that After Effects does.
    00:32:50,540But, it conveniently places it directly below the line
    00:32:54,512that the error is coming from.
    00:32:56,943So that's another really great time saver.
    00:32:59,202Alright, so I put my segment length variable in there.
    00:33:01,487I should be able to re-update that expression.
    00:33:04,286And there we go, the error goes away.
    00:33:07,377Now, if this end value goes below 50, you can see that
    00:33:10,941that master stroke width is getting smaller,
    00:33:13,888and shrinking down to zero.
    00:33:15,473Great.
    00:33:16,529So let's make that same functionality happen
    00:33:18,465to the rest of the stroke widths.
    00:33:20,674I'll load up the stroke width for the first duplicate.
    00:33:26,229And again, assuming all of these checkboxes are unchecked,
    00:33:29,498I'll drop down and type another condition.
    00:33:33,194Else, if ...
    00:33:35,658Auto shrink out,
    00:33:38,430equals one.
    00:33:40,586Then, and get rid of that curly bracket.
    00:33:45,632And again, we need those extra variables,
    00:33:47,448so we need the end ...
    00:33:52,155I'll put that at the top.
    00:33:53,793We need the auto shrink in.
    00:34:00,780And we need the segment length.
    00:34:06,356So we've got a decent list of variables,
    00:34:08,656but that's totally fine.
    00:34:09,896It's making everything a lot easier to code.
    00:34:14,156Alright, so let's go back to our condition.
    00:34:16,452If auto shrink out is one, then we want to linear
    00:34:20,172the end value from zero
    00:34:24,019to seg length to zero
    00:34:28,416to this linear interpolation down here.
    00:34:32,477So, we are actually putting a linear interpolation
    00:34:35,868within a linear interpolation.
    00:34:38,317Now that might seem a little bit crazy.
    00:34:40,288And, if you do stuff that's super super complex,
    00:34:43,541with lots of math happening within those linear
    00:34:46,545interpolations, it can really slow down your render.
    00:34:50,009But in this case, it's really not that complex,
    00:34:53,001and it doesn't add much render time at all.
    00:34:55,753So, I want to make sure that I end this line
    00:34:58,116with a semicolon.
    00:35:00,448And I will apply that to the stroke width.
    00:35:06,176Oh, and I got another error.
    00:35:08,080I accidentally typed auto shrink out,
    00:35:10,412that will come in a little bit.
    00:35:13,164I need to change that back to auto shrink in,
    00:35:15,276reapply it, now we're good.
    00:35:17,352Alright, let's delete the duplicates, and reduplicate,
    00:35:22,700and see if it worked.
    00:35:25,173As I bring this down, not only does the segment length
    00:35:28,044get smaller, but the stroke width also gets smaller.
    00:35:31,482So that is working exactly the way it needs to.
    00:35:34,259And if I adjust the segment length,
    00:35:37,044it doesn't kick in until the end value reaches
    00:35:41,268the segment length's value.
    00:35:43,028Which also just happens to be the exact amount
    00:35:46,536of how much of the line is visible.
    00:35:50,077So, as soon as that tail end of the line hits the front
    00:35:53,280of the path, it starts to scale down.
    00:35:55,938So that's working perfectly.
    00:35:58,787But, what if we want it to happen
    00:36:00,924on the opposite end as well?
    00:36:03,673Well, we can be a little bit clever, and get that
    00:36:05,808to work fairly simply.
    00:36:08,052Let's add another checkbox, called auto shrink out,
    00:36:13,056and go back to our master trim paths.
    00:36:15,500We'll start there again.
    00:36:17,619Load that up.
    00:36:19,812And we need to define that new variable,
    00:36:21,516so I'll just duplicate this auto shrink in,
    00:36:24,168and rename it auto shrink out.
    00:36:26,993And, auto shrink out, to reference the right checkbox.
    00:36:32,358And first I'll start by assuming that auto shrink in
    00:36:34,660is not checked.
    00:36:36,376And I will drop down, add another condition,
    00:36:39,313else, if, auto, shrink, out,
    00:36:44,340equals, one ...
    00:36:48,048Then, linear, end, comma.
    00:36:54,152And this is where it's gonna get a little bit different.
    00:36:56,218I need a different range if this is going to work properly.
    00:37:00,240The way that I want it to behave is ...
    00:37:02,031Say this segment length is 25.
    00:37:04,915So I want the auto shrink out to kick in as soon as
    00:37:07,840it's 25% away from 100.
    00:37:12,692So, 75.
    00:37:14,704So the way that we'll do this, is by saying 100 minus
    00:37:18,676the segment length, rather than just the segment length.
    00:37:24,120Comma, 100, because I want it to go from that point,
    00:37:28,960to the end, which is 100, not zero.
    00:37:34,516And I want to remap those numbers from this equation
    00:37:37,538right here, which is determining the segment length,
    00:37:40,347and make sure that I delete this duplicate curly bracket,
    00:37:43,603or else the expression will break.
    00:37:46,824Comma, end, and end it with a semicolon.
    00:37:53,107So once the slider reaches 100, the start value should
    00:37:57,199be equal to the end value.
    00:38:00,289Alright, let's apply that to the master trim paths' start,
    00:38:03,583and see if it worked.
    00:38:05,405Again, this is assuming that auto shrink in is off,
    00:38:08,168so I will uncheck that.
    00:38:10,049And let's test it out.
    00:38:12,225Yep, it's working, awesome.
    00:38:14,203So how do we get it to work with auto shrink in?
    00:38:17,634Well, we need to put another condition within
    00:38:19,606this condition, and it's gonna get
    00:38:21,313a little bit more complex.
    00:38:23,225But it's still pretty easy to understand.
    00:38:25,064So inside of this auto shrink in statement,
    00:38:28,452we need to first check for another condition.
    00:38:31,839So I will indent, and type if, auto,
    00:38:35,414shrink, out, is, on, and,
    00:38:41,560the end slider is greater than
    00:38:44,531the segment length slider, then ...
    00:38:52,132Give give me this auto shrink out equation.
    00:38:57,511Else, give me the auto shrink in equation.
    00:39:07,520So adding the two ampersands next to each other
    00:39:10,125within this condition is allowing me to have two conditions
    00:39:13,912that need to be met in order for this to be carried out.
    00:39:17,513And the way that this is used is pretty clever,
    00:39:19,086because what it's saying is what if auto shrink is checked,
    00:39:21,717and the end slider is greater than the segment length,
    00:39:26,105then apply the auto shrink out equation.
    00:39:30,317If the end slider is less than the segment length,
    00:39:33,353then give me just my auto shrink in expression.
    00:39:37,445So that's how we can apply both the auto shrink out
    00:39:40,229and auto shrink in expressions at the same time.
    00:39:44,189So let's apply this to the master start.
    00:39:48,533And see if it worked.
    00:39:50,171I'll check both boxes, and move the end slider back,
    00:39:54,573and it shrinks down, perfect.
    00:39:57,137And I'll go with this other direction,
    00:39:58,596and it also shrinks down.
    00:40:00,489So yes, that is functioning perfectly.
    00:40:03,384And let's just double check the controls to make sure
    00:40:05,981that the auto shrink in still works.
    00:40:07,597Yep, and the auto shrink out still works on the trim paths
    00:40:10,918on its own.
    00:40:12,150Awesome, so we can move on from the master trim paths.
    00:40:15,681Let's go to the master stroke width.
    00:40:18,949Load that up.
    00:40:21,049We need to start by defining the variable
    00:40:22,865for the auto shrink out.
    00:40:24,481So I'll just duplicate this variable, and adjust the naming.
    00:40:29,222So auto shrink out.
    00:40:31,246And the name of the checkbox is auto shrink out.
    00:40:35,097Then let's start with just the single auto shrink out
    00:40:38,550checkbox checked, drop this down a line,
    00:40:41,433and add a else, if,
    00:40:46,225auto, shrink, out,
    00:40:49,083equals one, then ...
    00:40:53,605Get rid of that extra curly bracket.
    00:40:56,001Linear, end, comma, 100 minus seg length,
    00:41:03,569comma, 100, comma,
    00:41:07,969stroke, width, comma, zero.
    00:41:12,711And then semicolon.
    00:41:14,801Let's apply that to the stroke width,
    00:41:16,737and then see if it works.
    00:41:18,880The auto shrink out scales down, yes.
    00:41:22,258The front master group, you can see, is scaling down.
    00:41:26,098Now let's account for the auto shrink in also being checked,
    00:41:29,289because right now that cancels it out.
    00:41:32,829So, we'll go up to auto shrink in,
    00:41:37,528and drop down indent, and make a new condition.
    00:41:41,885If, auto shrink out equals one,
    00:41:46,737and, end is greater than segment length,
    00:41:52,325then ...
    00:41:56,745We want this equation right here that we just wrote.
    00:42:02,741Else, this equation right here.
    00:42:11,599Alright let's apply that to the master stroke.
    00:42:15,315And double check that it's working.
    00:42:18,085Shrink's out that way,
    00:42:20,133and it shrinks out that way.
    00:42:22,698Great, that is working.
    00:42:24,854Let's move on to the duplicate groups' stroke width.
    00:42:31,340And again, I need that auto shrink out variable,
    00:42:33,291so I will just copy it from the one we were just using.
    00:42:37,468And paste it right here.
    00:42:40,141Then I'll start down here again,
    00:42:42,233and make the condition else,
    00:42:44,358if, auto shrink out
    00:42:47,506equals one, then ...
    00:42:50,913Get rid of that extra curly bracket.
    00:42:53,466Linear, end, comma,
    00:42:55,727100 minus segment length,
    00:42:59,348comma, 100, comma,
    00:43:05,672this equation right here,
    00:43:09,480comma, zero, semicolon.
    00:43:14,944Then I'll copy that entire line of code,
    00:43:17,576and we'll come up into the auto shrink in condition.
    00:43:21,491Drop down an indent, and say if, auto shrink out
    00:43:28,156equals one, and the end value
    00:43:31,676is greater than the segment length, then ...
    00:43:36,296And I will paste the expression I just copied
    00:43:39,136from auto shrink out.
    00:43:41,104Else ...
    00:43:45,781This equation right here.
    00:43:51,909We should be able to apply that to the stroke width,
    00:43:54,734and delete and reduplicate that group.
    00:43:58,266And check to see if it worked.
    00:44:00,301So, let's move the end value.
    00:44:02,589And sure enough, it is scaling out,
    00:44:04,458and the segment lengths are decreasing
    00:44:06,957on the out and the in, perfect.
    00:44:12,369So let's just double check to make sure these work
    00:44:13,916on their own as well.
    00:44:16,042Auto shrink out off, so just the auto shrink in.
    00:44:19,163Yep, that works.
    00:44:20,706And the auto shrink out only, auto shrink in is disabled,
    00:44:25,062auto shrink out is working.
    00:44:26,657Perfect, these features are working great.
    00:44:29,749Now, one little problem that I need to bring up
    00:44:32,829is that if I increase the segment length,
    00:44:35,733past 50%, so say 60 ...
    00:44:39,944And both auto shrink in and auto shrink out
    00:44:42,541are enabled, then when I get to that threshold
    00:44:46,777of 60 on the end value, you see that, boom,
    00:44:51,064it pops right there.
    00:44:53,069Now, the reason this is happening is because both
    00:44:55,576the auto shrink in and auto shrink out values
    00:44:58,985are based on where that segment length is.
    00:45:02,582And because the segment length is greater than half
    00:45:05,607of the entire range, the taper out equation
    00:45:09,531takes place before we reach that threshold.
    00:45:13,462And so it snaps as soon as that condition is met,
    00:45:16,894and that equation kicks in.
    00:45:19,962So what I'd like to do is to give priority to the auto
    00:45:22,980shrink in, so that if both are checked, and the segment
    00:45:25,695length is great than 50, it ignores the auto shrink out.
    00:45:30,273That's actually really simple to do.
    00:45:32,772So let's just jump back to the master trim path start value.
    00:45:36,885And we're going to go to the auto shrink out within
    00:45:39,480the auto shrink in condition.
    00:45:41,869And we're going to add one last condition,
    00:45:44,606which is, and, seg length,
    00:45:48,866is less than or equal to, 50.
    00:45:52,683So this is how you can say less than or equal,
    00:45:54,544you just use the less than sign,
    00:45:56,491followed up with an equal sign.
    00:45:59,329So I'm gonna copy that line of code,
    00:46:00,705'cause we're going to reuse that.
    00:46:02,474But I'll apply that to the master trim path start.
    00:46:05,973And already, we see that things are happening.
    00:46:08,196Then I'll go to the master stroke,
    00:46:10,748load that up.
    00:46:12,353And again, find the auto shrink out within the
    00:46:14,807auto shrink in, and paste this code right here.
    00:46:19,194Looks like I forgot to copy my ampersands, so let me
    00:46:21,351add those back in.
    00:46:23,761And then copy that line of code again.
    00:46:26,750So, auto shrink out is one, and end is greater than segment
    00:46:29,980length, and the segment length is less than or equal to 50.
    00:46:33,558Great, I'll apply that to the stroke width.
    00:46:36,988That updated.
    00:46:40,346Now let's go to the stroke for the duplicate groups.
    00:46:44,326Find that same condition, so auto shrink out ...
    00:46:48,078After the segment length I will paste and apply that.
    00:46:53,854Then I'll delete the duplicates, and reduplicate.
    00:46:57,946And now, the segment length is greater than 50.
    00:47:01,046So, the auto shrink in works,
    00:47:03,622but the auto shrink out is disabled.
    00:47:06,118Great, if I drop this down below 50,
    00:47:08,702then again, that kicks back in, and it works.
    00:47:12,686So, let's take a look at how this could be animated now.
    00:47:16,961I'll set the key frame on the end value,
    00:47:19,638start it at zero.
    00:47:21,463Go forward maybe a second or so.
    00:47:25,226And, we'll set that to 100.
    00:47:28,577Then I'll ran preview this.
    00:47:33,818And with just two key frames, I'm able to animate this taper
    00:47:37,101in and out, and it will automatically scale up, and scale
    00:47:40,530down, based on how much of that line is visible.
    00:47:43,915So I could go in here now, and adjust my value curves,
    00:47:47,822and everything else happens for me automatically.
    00:47:51,057So that is a huge time saver when it comes to
    00:47:53,498animating lines like this.
    00:47:56,150Now, I mentioned earlier that adding all these extra
    00:47:59,041checkboxes is making things a lot more complex,
    00:48:02,815and I coded the last couple of features assuming that
    00:48:05,828other checkboxes weren't on.
    00:48:08,544The reason why is because if I enable, say, the reverse
    00:48:12,594taper, that is now going to break the expression
    00:48:18,831that controls the stroke width auto shrink in and out.
    00:48:23,063Because, remember, if a condition is met,
    00:48:26,835After Effects applies the expression,
    00:48:29,487and then ignores everything after it.
    00:48:32,159Since reverse taper is in the top of this list,
    00:48:35,063that condition is met with that checkbox being checked,
    00:48:38,419and everything else is disregarded.
    00:48:40,762So every time you add another checkbox control,
    00:48:43,743it adds another layer of conditions that you have to
    00:48:46,559take into account.
    00:48:48,394And it can get really complex, really quickly.
    00:48:51,683On top of that, some of these combinations of checkboxes
    00:48:54,771require completely different equations.
    00:48:57,518For example, if you had the trail enabled, and reverse taper
    00:49:02,327was off, and you animated this out, and had auto shrink out
    00:49:06,131enabled, it's going to shrink that trail out to zero.
    00:49:10,488And that's probably not what you would want.
    00:49:16,639Instead of automatically shrinking everything down to zero,
    00:49:17,472it would be way more functional if the taper shrunk down
    00:49:19,815to be the stroke width of the trail, rather than zero.
    00:49:25,128And the same way if it was reversed.
    00:49:27,540Then you would want the taper to scale up into that
    00:49:30,564thickest stroke width.
    00:49:32,752So it's definitely a lot more complicated,
    00:49:34,964and you have to take a lot more things into account.
    00:49:37,800I'm going to spare walking you through every single line
    00:49:40,772of code, and instead jump to the final rig, and just
    00:49:44,259show you how it's working.
    00:49:46,756Alright, so here is my final tapered stroke rig,
    00:49:49,660with all the controls working exactly the way
    00:49:51,790that they're supposed to.
    00:49:53,312And all the different combinations of these checkboxes
    00:49:55,780are also going to behave properly.
    00:49:57,704So let's take a look at that combination of the trail
    00:49:59,872being checked, and the auto shrink out being checked.
    00:50:03,093Now, you already see that this is single width line,
    00:50:06,416instead of it scaling down to zero.
    00:50:08,044So if I back this up from the end, you see that
    00:50:10,634that taper now scales down to the smallest stroke width,
    00:50:14,782or the trail width, instead of down to zero.
    00:50:17,530That makes things likes write ons with text so much easier,
    00:50:21,182because you end up with a single width line by the time
    00:50:24,241the animation is finished.
    00:50:25,880And this works with every combination of checkbox.
    00:50:28,510If I reverse the taper, instead of scaling down,
    00:50:32,754the taper scales up, to be the width of the trail.
    00:50:34,997Same thing with the taper in and out.
    00:50:36,208I'll back that up, and you see that both halves
    00:50:38,596are scaling down to be the trail width.
    00:50:41,478So let's uncheck all these boxes, and take a look
    00:50:43,965at what happened to the code.
    00:50:46,007I'll go into the contents, and the duplicate groups,
    00:50:48,154and I'll just load up the stroke width
    00:50:49,384of the first duplicate.
    00:50:51,880Now, there are so many more lines of code here.
    00:50:55,339So much so that I can't even fit it all on one screen,
    00:50:57,532I have to scroll down.
    00:50:58,706I think we went from around 35 lines of code down to 108.
    00:51:03,610And the reason why there are so many more lines of code
    00:51:06,319is because all of these different combinations of checkboxes
    00:51:09,641forced me to account for so many more conditions
    00:51:12,580within my conditional statements.
    00:51:14,956So for example, that trail combined with auto shrink out.
    00:51:18,730Well, I'll scroll down to the bottom where we have auto
    00:51:20,930shrink out, which is right here, there's our condition.
    00:51:23,658And you'll see that the first thing I do is check to see
    00:51:26,749if the trail is also enabled.
    00:51:29,378If the trail is enabled, then we get a linear expression.
    00:51:33,328The result of all of the conditions, and you can see
    00:51:35,659this all the way through my entire expression,
    00:51:38,456is a linear interpolation.
    00:51:40,037That hasn't changed.
    00:51:41,360The only thing that has changed is how that range
    00:51:43,923of values is being interpolated.
    00:51:46,387So, if the auto shrink out is on, and trail is on,
    00:51:50,334then we want to interpolate to the trail width,
    00:51:53,786rather than zero.
    00:51:56,408If trail is not checked, then we do want to interpolate
    00:51:59,057down to zero.
    00:52:00,176Now the trail width, if we go up to the variable list,
    00:52:03,339you see that I defined this as a variable.
    00:52:05,264This is just the stroke width of the first
    00:52:07,772duplicate taper group.
    00:52:09,620And the reason why I can define it as that stroke width
    00:52:13,019is because that group is never going to be deleted.
    00:52:16,351This is the group that you duplicate to increase
    00:52:17,739the resolution, basically, of your taper.
    00:52:20,174So that's always going to be there, which made it okay
    00:52:22,305to turn that into a variable.
    00:52:24,537But once I had that as a variable, I can use it as part
    00:52:27,531of my interpolation, so that whatever size it is,
    00:52:32,029no matter which one of these checkboxes is turned on,
    00:52:34,515it will always interpolate down to that size, or up
    00:52:38,046to that size, instead of to zero.
    00:52:40,764And like I said, you can see this same format repeated
    00:52:43,184through every single one of my conditions.
    00:52:45,868The expression itself if pretty simple, it's just checking
    00:52:48,059to see if a checkbox is checked, and then in this instance,
    00:52:51,720it's seeing if auto shrink in is checked, and then
    00:52:54,563the third level is to see if auto shrink out is checked.
    00:52:56,907And then check to see if trail is checked.
    00:52:59,182And if all of those things are checked, and all
    00:53:00,975of the conditions are met, then apply this
    00:53:03,243linear interpolation expression.
    00:53:05,707Otherwise, if this condition right here
    00:53:07,247isn't met, apply this.
    00:53:09,810If this condition isn't met, then skip everything between
    00:53:12,295this curly bracket and this curly bracket, and go on
    00:53:15,190to the next thing, which would be right here.
    00:53:17,575If this condition isn't met, ignore everything between
    00:53:20,490this curly bracket, and this curly bracket, and check
    00:53:23,130for the next condition.
    00:53:24,991So this is a great example of why having this structure
    00:53:28,521of putting line breaks after curly brackets and indenting
    00:53:31,898for every level of condition is so important.
    00:53:35,460Because it allows you to follow this hierarchy
    00:53:37,900visually through your code, to make it a lot easier
    00:53:41,159to follow and understand.
    00:53:43,150It makes absolutely no difference to After Effects
    00:53:44,954if you drop down a line and indent.
    00:53:47,053I could have written this entire 108 lines of code
    00:53:50,170on a single line, and After Effects still would have
    00:53:52,620interpreted it exactly the same way.
    00:53:54,162But that would make it impossible for me to wrap my head
    00:53:57,362around what exactly is going on in this code.
    00:53:59,893Now, all of that code is just for the stroke width
    00:54:02,357of the duplicate groups, but we had to take a lot
    00:54:04,469of these conditions into account for the master
    00:54:06,393group as well.
    00:54:07,556So if I open that up, and take a look at the master stroke
    00:54:10,372width, you see that I had to build a bunch of conditions
    00:54:12,679into this as well, in order to get it to behave properly
    00:54:15,670for all of these combinations of checkboxes.
    00:54:18,452It wasn't as complicated for the trim paths,
    00:54:21,048on the master group or on the duplicate groups.
    00:54:23,995But there were some things I needed to take into account.
    00:54:26,712So feel free to download this project, and dig through
    00:54:28,362the code to see how everything is functioning,
    00:54:30,212if you're curious.
    00:54:31,486But the basic format is always the same.
    00:54:33,524You always start with a condition, and sometimes there's
    00:54:36,548multiple levels of conditions, and if all those conditions
    00:54:39,470are met, apply this expression.
    00:54:41,651Otherwise, apply this expression.
    00:54:43,720And that structure is the foundation for every single one
    00:54:46,008of the features in this tapered stroke rig.
    00:54:49,099One last thing I want to point out is that you'll see
    00:54:50,978some gray text up here, next to some of the variables
    00:54:53,988in other lines of code, within the rig.
    00:54:56,244And these two slashes means that it's a comment,
    00:54:58,562and After Effects will not read this as code.
    00:55:01,712So I just gave a few explanations of some
    00:55:03,824of the choices I made.
    00:55:05,252For example, this num properties plus one.
    00:55:07,715I added the comment that explains that we had to account
    00:55:10,223for that extra group, the master group, outside of
    00:55:12,776the duplicate groups folder.
    00:55:14,612This style of commenting will make everything after
    00:55:16,738these two slashes on that line a comment.
    00:55:19,913So, if I were to put this before the variable,
    00:55:23,062that will comment out the variable, and it will
    00:55:26,714no longer work.
    00:55:29,750So if you use one line comments, make sure they go after
    00:55:33,292a line of code, or in between lines of code.
    00:55:36,109Now you can make a comment not extend an entire line,
    00:55:38,575if I had changed this from a slash slash to slash star,
    00:55:42,511and then ended it with a star slash.
    00:55:46,161Then everything between that becomes a comment.
    00:55:48,625And I can even drop this down a line, and add more text,
    00:55:52,183on as many lines as I need to.
    00:55:53,831So that's how you can add notes to your expressions,
    00:55:56,205for your own benefit, or for other people's benefit,
    00:55:58,615if you pass it on to somebody else.
    00:56:01,995Oh my gosh.
    00:56:03,499Congratulations on making it through all of that lesson.
    00:56:07,634I'll give you a virtual high five.
    00:56:09,175You should probably go outside, take a walk around
    00:56:11,829the block, because that was probably way too much code
    00:56:14,328to be taking in at one time.
    00:56:16,310Not only have you created a completely customizable,
    00:56:19,538reusable, and streamlined tapered stroke rig, you learned
    00:56:23,418so much about using really powerful expressions to come up
    00:56:26,773with solutions to pretty complex problems.
    00:56:29,985You can now use expressions as a problem solving tool,
    00:56:34,126instead of just applying the wiggle to any property,
    00:56:36,576to get some randomness out of it.
    00:56:38,635I can't say enough great things about Expressionist,
    00:56:40,923so again, if you think you're going to be getting into
    00:56:42,756this world of expressions, I highly recommend
    00:56:44,948you go check it out.
    00:56:46,376Thanks so much for watching, and I'll see you next time.
    00:56:55,382(upbeat instrumental music)