Expression Shorts Swinging Motion Part 2

February 26th 2012 08:30:58am

For part 2 of Swinging Motion, I’m gonna step it up a notch and show you how to add a little more character to the Pendulum setup by loosening it up to mimic a string or lamp pull chain swinging.

So in Swinging Motion Part 1 I explained how to use Math.sin() to make circular motion and pendulum like swinging motion. If you have not seen part 1, I would highly recommend that you view it so you will better understand what I am doing in part 2. For this tutorial the setup will involve a little more than just the expression alone, but I thought it was worth sharing the technique.

MASTER POINT SOURCE CODE:

swingMaxDistance = 20;
swingSpeed = 8;
easeTimeSpan = 6;
easeOutSpeed = 1;
easeOutVal = easeOut(time*easeOutSpeed, 0, easeTimeSpan, swingMaxDistance, 0);

Math.sin(time * swingSpeed) * easeOutVal + transform.rotation;

The expression is nearly identical to the one used in part 1, but it is how all the layers are combined that makes the animation possible. The key is in how the Child layers are aligned and parented. The new expression in this is an interpolation expression called easeOut(). There are two layers minimum required for this setup, both of which are explained in the breakdowns below. This may be one of the few setups that is best to learn by viewing the tutorial above, but I will do my best to explain it in the text below.

easeOut() – This expression is identical to the ease() expression with the exception that it will ease the out values only. easeOut() contains the same five input values as ease()…

easeOut(time, tMin, tMax, value1, value2);

time: Is the master source of information. You can use time, a layer’s position, rotation, opacity, etc…
tMin: The minimum value you want to use from the master source, time.
tMax: The maximum value you want to use from the master source, time.
value1: The start value that maps to the tMin value.
value2: The finish value that maps to the tMax value.

There are also more ease expressions available too if you only want to ease the in values or both in and out values…

easeIn(time, tMin, tMax, value1, value2);
ease(time, tMin, tMax, value1, value2);

MASTER POINT CODE BREAKDOWN:

swingMaxDistance = 20;
swingSpeed = 8;
easeTimeSpan = 6;
easeOutSpeed = 1;
easeOutVal = easeOut(time*easeOutSpeed, 0, easeTimeSpan, swingMaxDistance, 0);
Math.sin(time * swingSpeed) * easeOutVal + transform.rotation;

NOTE: The above expression is meant to be placed on the Rotation property of your master layer. This will be your controller layer that starts the chain of layers that connect to each other.

Line 1: We create a variable called swingMaxDistance and assign it a value of 20. We will use this to define how far the swing will be in either direction.

swingMaxDistance = 20;

Line 2: Next we make a variable named swingSpeed and assign it a value of 8. This will be the speed at which our layer will swing.

swingSpeed = 8;

Line 3: We then create a variable called easeTimeSpan and assign it a value of 6. This will be the max number of seconds for our ease to play in our timeline.

easeTimeSpan = 6;

Line 4: Next we create a variable called easeOutSpeed and assign it a value of 1. This is how fast our ease motion will be. 1 equals realtime and anything higher would be a multiple of time. For example, 2, would be twice as fast and would also force the ease motion to play out in 3 seconds instead of the 6 seconds defined in line 3.

easeOutSpeed = 1;

Line 5: We then create our easeOutVal variable and we assign it an easeOut() interpolation expression. This will create a decreasing value that will start at full speed, then ease out. The speed at which this happens is determined by the first value, time*easeOutSpeed. The second and third values determine the time range in which to run the ease out. We have ours set to start at time 0 and continue until the 6 second mark. During which our swing distance will start at our swingMaxDistance (20) then decrease to 0.

easeOutVal = easeOut(time*easeOutSpeed, 0, easeTimeSpan, swingMaxDistance, 0);

Line 6: For our final line we output the total rotational value using Math.sin(). We assign time and our multiplier to it like so, Math.sin(time * swingSpeed). Then we multiply that total by our easeOutVal to create the slowing effect. After that we then add our original source rotation value back into it. By doing this we can then effectively offset the starting rotational angle by simply adjusting the Rotation property slider of this layer.

Math.sin(time * swingSpeed) * easeOutVal + transform.rotation;

CHILD POINT CODE BREAKDOWN:

thisComp.layer(index+1).transform.rotation;

Line 1: For our child layer we add a single expression to the Rotation property to tie it’s Rotation value to the rotational value of the layer below it. When duplicating layers in After Effects, they naturally stack on top of each other, so having the child layer connect to the one below itself is more logical and saves a step.

We connect the Rotation value by defining thisComp.layer().transform.rotation, then inside the () we place index+1. Now the expression, index, refers to the index number of the current layer. By saying index+1, we are adding 1 to that value, so if the current layer is 5, then it will look for layer 6, which is one layer below. If you did want to reverse the stacking order and have the layers connect to the layer above, then you would subtract 1, index-1.

thisComp.layer(index+1).transform.rotation;

The video tutorial above may be a better resource for this next section of the process. Having a visual usually helps, but I will try to explain it. So now that you have a child layer created and the Rotation expression connecting to the layer below, you will need to duplicate the child layer as many times as you want.

Once you have as many layers as you want, you need to parent them one at a time to the layer below, so the first child layer parents to the Master layer, then child 2 parents to child 1, then child 3 parents to child 2 and so on. There is actually a script made by Lloyd Alvarez that makes this task super simple that you can grab here: Layer Chain

Once you have parented the layers you will need to offset the position value. You can do this by selecting all of your child layers, then tapping P to reveal the Position property. Click in one of the Position property boxes and change the value. All selected layers will update with the new value. You want to allow some overlap depending on your design. For the example I created, the layers were 100 pixels high so I made the Y Position value 90, so I would have a 10 pixel overlap. Once you do that you should be ready to go.

Checkout more:
Free Function Friday Ep.30 – addCompMarker
X-Particles Blood
Free Function Friday Ep.11 – collectFontsUsed
After Effects ExtendScript Training: Ep. 5
After Effects ExtendScript Training: Ep. 18 Part 1