All Articles After Effects
After Effects: Shape Layer Index Hierarchy
Toby Pitman on Mon, January 2nd 5 comments
Toby Pitman demonstrates how to dynamically add multiple strokes, generate increasing stroke widths and even randomize width and brightness in After Effects.

I recently wrote an article on some things you can do with converting Text to Shape Layers. One of the examples added multiple strokes to the shape outlines using the Shape Layers' built in stroke effect which was just duplicated.

While this is very easy to set up it can be a very lengthly process to manipulate all your stroke widths and colors manually. If you have 20 strokes that are based on a blue color and you want them all to be based on green and double the width it can be a real pain to change!

So is it possible to do this dynamically? Well, yes! By linking stroke width and color to some expression sliders on the first stroke any subsequent duplicated stroke will also be linked to the sliders allowing you to control them all at once.

Wouldn't it be great if you could also offset each stroke so every duplicate stroke got a bit wider, darker or lighter, or even to be able to randomize the width and brightness of each stroke! Well you can do that too!

The problem is how do you target the contents of a Shape Layer and find the index of each Stroke effect? Here's what I mean.

Comp Layer Index

Each Layer in an After Effects composition has an Index number. The top Layer has an Index of 1. It could be any type of Layer, a Solid, an Adjustment Layer or Null object.

The Layer below it has an Index of 2 and so on and so on. You can see this in the image below. The Index number is on the right hand side by the Layer color.

The Layer below it has an Index of 2

A common trick with index numbers is to offset a duplicate of the original Layer by adding, multiplying or dividing its position, opacity, etc by its Index number. 

By adding an expression to Position and Opacity that says if the Index is equal to one do nothing but if it's not then multiply the X position by the Layer Index and divide the Opacity by the Layer Index.

duplicate of the original Layer by adding, multiplying or dividing its position, opacity, etc by its Index number

I get this when I duplicate the Layers.

the result

This type of thing is used to create faux 3D text by offsetting the Z position of a duplicate 3D text layer by its Index number. Standard stuff!

Finding The Index Within A Shape Layer

Now Shape Layers are kind of like mini compositions in the fact that they can hold many different elements. They can contain single or multiple Paths, Fills, Strokes and Vector Effects like Pucker and Bloat, Offset Path, Twist, Zig Zag, Rounded Corners and Wiggle Path (an animated version of Illustrators Roughen Edges).

These elements can be grouped together using the Add > Group and a Shape Layer can contain multiple groups each with its own independent hierarchy and effects, even nested groups. This can lead to very complex structures. So how do we find the Index numbers of these elements within these structures for duplication offset effects?

Let's start from the top. Here's an empty Shape Layer. It contains two items Contents and Transform. 

an empty Shape Layer

When you create a Layer > New > Shape Layer the Contents folder is empty. This is where all new items (or Properties) go, so let's put something into the Contents folder. 

I'm going to add three shapes clicking the Add button. I'll add an Ellipse, a Circle and a Poly Star. 

Adding three shapes

Now I need a Fill and Stroke so I'll add these too using the Add button.

Fill and stroke

Now I have have a basic structure.

the basic structure

Here's the problem. I want to duplicate my Stroke effect and have the new Stroke automatically increase in size based on an Index number like my Comp Layer example. 

But does my Stroke effect even have an Index number? Well, yes it does but it's a bit harder to find than Layer Index. 

To find an Index number that I can increase my Stroke Width with I'm going to use this clever expression on Stroke 1's width.  

value = thisProperty.propertyGroup(1).propertyIndex

How does this work then? Here's a breakdown...

value =  The value of Stroke Width.

thisProperty - the actual '˜Stroke 1' effect.

propertyGroup(1) - The '˜container' that holds thisProperty (Stroke 1) which is Contents. 

propertyIndex - Give me the Index of thisProperty (Stroke 1) inside Contents.

You can see propertyGroup() lets me drill backwards up the hierarchy from my start point to find the container for the Stroke effect. The (1) is the first level up from the Stroke effect. propertyGroup(2) would be the container that holds Contents, two levels up from thisProperty, i.e the actual Shape Layer! Lets add this to Stoke Width and see what happens.

Well you can see my Stroke Width is now 5px! 

stroke width at 5px

This is because '˜Stroke 1' is the 5th item inside Contents! 

Stroke 1 as fifth item in content

OK, so that's cool, I have an index number! But what if I choose to get rid of a shape later it will throw out my index numbers!

Well I can get round this by placing all my shapes in a Group. Go to Add and choose Group and move the shapes into it. I'll even move my Fill into it incase I decide to add a different fill for each Shape later. I've named it '˜My Shapes'.

place all shapes in a group

Now my Stroke is 2px as it's the 2nd item in Contents. 

stroke value changes to 2px

Now I have a more consistent structure I can simply subtract one from my expression to make my first stroke 1 pixel!

value = thisProperty.propertyGroup(1).propertyIndex - 1 

Now I can do some stuff!! First I'll add a Master Width control to the Shape Layer using an Expression Slider. 1 - 100 pixels.

Master width control

Then I'll wrap my expression in some brackets and add a multiply sign and Pick Whip to the slider value. This way I can control the relative value of my stroke width.

control the relative value of my stroke width

Before I duplicate I'll divide the Stroke Opacity by the propertyIndex as well.

divide the Stroke Opacity by the propertyIndex as well

Each duplicate will become more transparent as it's divided by a higher index number! So if I raise the Master Width slider my Stroke expands.

raise the Master width slider to expand the stroke

And if I duplicate each Stroke increases and the Opacity fades! Horray!

duplicate each Stroke increases and the Opacity fades

If I enlarge the Stroke it works for each duplicate!

If I enlarge the Stroke it works for each duplicate!

Here you can see all the expressions working.

All the expressions working

And if I delete some Shapes it still works because of that Group we put them in!

result so far

Now you can take this as far as you want to go. I made myself a really handy animation preset using this technique that lets me create multi stroke design elements with a click of a button, I just add a Shape or Path.

Add a shape or path

It has random or linear options for Lightness and Stroke Width with random seed control. Controls for Start and End Lightness which you can Invert etc etc. 

random seed control

Once you know this technique Shape Layers take on a whole new meaning! Try it for yourself!!

Related Videos
Comments (5)

You must be logged in to comment.

  • Dennis
    Great tutorial. I have a question; how can I change the color of the stroke depending on the index number. If indexnumber is even color one or if indexnumber is odd than color two. Greets, Dennis
    • 8 years ago
    • By: Dennis
  • Dennis
    Got it, with 2 color effect controlers (color1 and color2) i=(thisProperty.propertyGroup(1).propertyIndex - 1)%2; if (i==0) {effect("color1")("Color")} else {effect("color2")("Color")};
    • 8 years ago
    • By: Dennis
  • Great tutorial, i had some questions which i cant seem to find the answer for, i want to do the following. I have a shape with a stroke, now i want to zoom in and out of the shape but without changing the stroke width, is that possible without a expression.
    • 9 years ago
    • By:
  • tobypitman
    Well you could always just Keyframe the Stoke width manually. Ideally you'd want to do this finding the distance of the object to the camera using an expression. You may find that actually 'zooming' the camera will be trickier to work out so moving the camera in would be best. Good Luck!
    • 9 years ago
    • By: tobypitman
  • Bynudyy
    Great info regarding how to access various shape properties via expressions, really useful thanks
    • 9 years ago
    • By: Bynudyy
Motion Tracking and Stabilization
After Effects CS5 201
Dream It. Do It.
Do you want to learn Motion Tracking and Stabilization?
Yes, I want to learn!
No Thanks, I just want to read the article.
Course Advisor
Don't Know Where To Start?
Ask A Course Advisor
Ask Us!
Copy the link below and paste it into an email, forum, or Facebook to share this with your friends.
Make money when you share our links
Become an Ask.Video Affiliate!
The current affiliate rate is: 50%
Classes Start Next Week!
Live 8-week Online Certification Classes for: