January 23rd 2012 08:00:01am
(CODE UPDATED 3/25 See article for updates)
Learn how to fade a layer up and down without using keyframes. The cool part is that you can change the in/out points of your layer and it’ll adjust accordingly.
The expression code on this one is a bit more involved, but I give a full breakdown below the video tutorial. Enjoy.
SOURCE CODE: (gets applied to the Opacity property of a layer)
fadeTime = 10;
opacityMin = 0;
opacityMax = 100;
layerDuration = outPoint – inPoint;
singleFrame = thisComp.frameDuration;
animateIn = linear(time, inPoint, (inPoint + framesToTime(fadeTime)), opacityMin, opacityMax);
animateOut = linear(time, (outPoint – framesToTime(fadeTime+1)), (outPoint-singleFrame), opacityMax, opacityMin);
if(time < (layerDuration/2+inPoint)){ //<--CODE UPDATED 03/25
animateIn;
}else{
animateOut;
}
The Auto Fade expression we have here is definitely confusing to look at, but I hope to help you understand it better. We are dealing with some new terms in this code, we have inPoint, outPoint, frameDuration, framesToTime(), linear() and an if/else statement. We are gonna be learning some very hefty expression code today my friends, but it is all worth it. 🙂
inPoint – The inPoint is pretty self explanatory. It retrieves the in point of a layer.
outPoint – The outPoint is pretty self explanatory. It retrieves the out point of a layer.
frameDuration – frameDuration is used to retrieve the duration of time for a single frame. Basically a single frame written as seconds, this is the native method of how After Effects reads time behind the scenes. So one frame in a 23.976 fps comp is equal to 1 frame or 0.04170837504171 seconds. Crazy I know, but that’s how it works. We will need the value of one frame later on.
framesToTime() – A very handy conversion method that does exactly what it says, it converts a frame value to a time value. So if we were to write framesToTime(1), we would get that same seconds value mentioned above, 0.04170837504171. For our purpose we will be converting our numbers from different variables so all the math works out properly in the end.
linear() – linear() is a handy bit of code when you are wanting to map a value to another value over time. There are two versions of this code, the one we are using requires five input values, like so…
linear(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.
if(){}else{} – if/else statement runs a comparison of values and then runs different code depending on weather or not that comparison is true or false. Simply put "if" a value is true, run this code, "else" run this other code. Another annalogy would be, if I have my keys, I can drive my car, otherwise if I don’t have my keys, I can’t drive my car. The formating of an if/else statement can vary, but they all do the same thing. Here are three examples.
Version 1:
if(I have my keys){
I can drive my car;
}else{
I can’t drive my car;
}
Version 2:
if(I have my keys)
{
I can drive my car;
}
else
{
I can’t drive my car;
}
Version 3:
if(I have my keys)
I can drive my car;
else
I can’t drive my car;
Version 4:
(I have my keys) ? I can drive my car : I can’t drive my car;
Versions 1 and 4 are my favorite to use. 1 is easy to read, plus properly contained with the curly braces and 4 is just plain faster to write.
CODE BREAKDOWN:
fadeTime = 10;
opacityMin = 0;
opacityMax = 100;
layerDuration = outPoint – inPoint;
singleFrame = thisComp.frameDuration;
animateIn = linear(time, inPoint, (inPoint + framesToTime(fadeTime)), opacityMin, opacityMax);
animateOut = linear(time, (outPoint – framesToTime(fadeTime+1)), (outPoint-singleFrame), opacityMax, opacityMin);
if(time < (layerDuration/2+inPoint)){ <--CODE UPDATED 01/28
animateIn;
}else{
animateOut;
}
Line 1: We set a variable called fadeTime and assign it the amount of frames we want the fade to last.
fadeTime = 10;
Line 2: We make a variable called opacityMin and assign it the minimum opacity we want, which is 0.
opacityMin = 0;
Line 3: We make a variable called opacityMax and assign it the maximum opacity we want, which is 100.
opacityMax = 100;
Line 4: We create another variable called layerDuration to hold the total length in time of our layer. We do this by subtracting the inPoint value from the outPoint value.
layerDuration = outPoint – inPoint;
Line 5: We make a variable called singleFrame to hold the value of the current comp’s frameDuration.
singleFrame = thisComp.frameDuration;
Line 6: This variable called animateIn uses the linear() method to calculate our overall fade value and when it happens. Hopefully with the linear() explanation on the previous page and the video just below, this should start to make a little more sense.
– Our first argument for linear() is time, this is what we are sourcing as our master input, the timeline’s current time.
– The second argument is our layer’s in point.
– The third argument is our layer’s in point plus our ten frame variable, fadeTime. You’ll notice here, that we place that variable in our framesToTime() method to convert our value into seconds. Without this conversion After Effects would think that we wanted to add 10 seconds, not 10 frames. We also surround the entire equation with parenthesis, (equation), to help both organize the code and tell the computer that this is a self contained equation.
– The fourth argument is our starting opacity value variable, opacityMin. For our fade in, we start at 0.
– The fifth argument is our ending opacity value variable, opacityMax. For our fade in, we finish at 100.
animateIn = linear(time, inPoint, (inPoint + framesToTime(fadeTime)), opacityMin, opacityMax);
Line 7: This variable called animateOut uses the linear() method to calculate our fade value and when it happens. This may look repetitive, but pay close attention to what’s happening for our fade out because values are flipped.
– Our first argument for linear() is time, identical to our animateIn setup.
– The second argument is our layer’s out point. We also do the framesToTime() conversion, but we are also adding one frame to our fade out. The reason for this one frame offset is that After Effects gives us the literal out point of a layer, the very edge that you see in the timeline when in fact the actual visual out of a layer is on the last frame, so we add this one frame to compensate for that.
– The third argument is our layer’s out point and we have to subtract a single frame here to offset for the same reason as above.
– The fourth argument is our starting opacity value variable, opacityMax. For our fade out, we start at 100, to match the value we faded up to with animateIn.
– The fifth argument is our ending opacity value variable, opacityMin. For our fade out, we finish at 0.
animateOut = linear(time, (outPoint – framesToTime(fadeTime+1)), (outPoint-singleFrame), opacityMax, opacityMin);
Line 8,9,10,11,12: CODE UPDATED 01/28 For the if/else statement we are checking to see which half of the layer we are reading in our timeline. If you were to cut the layer in half vertically, you would have a left(or first half) and a right(or second half) to your layer. We setup an equation taking the total length of time our layer exists, variable layerDuration, and divide that by 2 using the backslash. (layerDuration/2+inPoint) This gives us the middle of the layer time wise. We then check to see if time is less than that value. If it is less than, then we know we are on the left side of the layer and we should run animateIn. If the value of time is greater than, we know we are now on the right side of the layer and we should run animateOut. Hopefully that makes sense.
if(time < (layerDuration/2+inPoint)){
animateIn;
}else{
animateOut;
}
I hope this explains this code clearly enough. Not knowing Javascript can make this stuff frustrating, believe me I know, but I hope this code breakdown made that process a little less painful for you. If you have questions or feedback, please leave comments and I will try to reply as best I can.