Introduction to the Basics of After Effects Scripting
To go along with our recent tutorial about script development workflow, we will go over the basic concepts and good practices necessary to start writing After Effects scripts. We will go over usual After Effects actions such as: creating a project, creating a composition, creating a layer, creating shapes, adding effects, changing values and expressions, using text and fonts, adding keyframes, using functions, etc.
After Effects Scripts on VideoHive
If you're looking for a quick solution with an After Effects script, there's a great collection over on VideoHive. Or, you could consider applying to submit your own scripts as an author!



Writing Your First Script
As stated in the After Effects Sublime Text build package installation and usage tutorial, scripts are files which use the Adobe ExtendScript language. ExtendScript is an extended form of JavaScript used by several Adobe applications such as Photoshop, Illustrator, and InDesign. ExtendScript is a good and efficient way to achieve anything you want in After Effects.
Scripts use the Adobe ExtendScript language, which is an extended form of JavaScript used by several Adobe applications such as Photoshop, Illustrator, and InDesign
This tutorial will go over the basic concepts and good practices necessary to start writing After Effects scripts.
Creating Our First Composition
We’ll start off by using the
1 |
newProject() |
method of the
1 |
app |
object and wrapping it between curly brackets.
1 |
{ |
2 |
// Creating project |
3 |
app.newProject(); |
4 |
} |
The
1 |
app |
object is the root of almost everything as seen on this schema:
This schema can be found in the Adobe After Effects CS6 Scripting Guide like most of what I will explain in this tutorial.
We now create our composition by using the
1 |
app |
object’s sub-objects
1 |
project |
which contains the project created in the first line and the
1 |
items |
sub-object which gives you access to the folders and compositions you see in your project window in After Effects.
1 |
{ |
2 |
// Creating project |
3 |
app.newProject(); |
4 |
|
5 |
// Creating comp |
6 |
app.project.items.addComp("Demo", 1280, 720, 1, 10, 24); |
7 |
} |
Cleaning Our Code
Writing clean and maintainable code is really important. We are not writing quick and dirty expressions anymore. Since we want our scripts to be easily scalable, we need to embrace the Javascript community’s conventions.
So, we will isolate key data into variables and name them accordingly to their content. Also, we will put conditions in case there would already be a project or a composition in our After Effects file.
1 |
{ |
2 |
// Creating project |
3 |
var currentProject = (app.project) ? app.project: app.newProject(); |
4 |
|
5 |
// Creating comp |
6 |
var compSettings = cs = [1280, 720, 1, 10, 24]; |
7 |
var defaultCompName = "Demo"; |
8 |
var currentComp = (currentProject.activeItem) ? currentProject.activeItem: currentProject.items.addComp(defaultCompName, cs[0], cs[1], cs[2], cs[3], cs[4]); |
9 |
currentComp.openInViewer(); |
10 |
} |
The
1 |
var |
keyword indicates that the following variable is a new variable. That’s why, on line 9, we don’t use the
1 |
var |
keyword anymore because we want to use
1 |
currentComp |
’s value (which is the comp we’ve just created).
Here’s, line by line, what we did in plain english:
-
Line 3: Create new variable
1
currentProject
which will equal to
1
app.project
if
1
app.project
is not undefined and will otherwise equal to
1
app.newProject()
.
-
Line 6: Create new variables
1
compSettings
and
1
cs
which both equals to a new array of values.
-
Line 7: Create new variable
1
defaultCompName
which contains the name we will give to our comp.
- Line 8: Create new variable
1
currentComp
which will equal to the
1
activeItem
property of our
1
currentProject
object. If it’s not undefined and will otherwise equal to the result of the
1
addComp
method of the
1
items
sub-object of
1
currentProject
to whom we’ll send an array of arguments containing:
- Name of the composition
- Width of the composition
- Height of the composition
- Pixel ratio of the composition
- Time (in seconds) of the composition
- Frame rate of the composition
-
Line 9: Use the
1
currentComp
method
1
openInViewer
which will open the timeline for this composition.
Yes, that’s a lot of methods and properties. Again, you will have to take a look at one time or another to Adobe After Effects CS6 Scripting Guide to learn more about the objects and their available methods and properties. The guide is really well written and a quick search for Project object will immediately take you to the right information.
Quick Javascript Concepts
- Variable: Can store a value, an array of values or an object.
-
1
var myVar = "String value";
-
1
var myVar = 2;
-
- Array: Contains multiple values. Arrays can be declared in two ways.
-
1
var myVar = array("value1", "value2", 3);
-
1
var myVar = ["value1", "value2", 3];
-
- Function: Part of code designed to perform a specific task.
-
1
function myFunction(argument) {
2
// Do something
3
}
-
- Object: The object is a little more complex but, for now, you must know it has properties and methods.
- Property: Similar to a variable
1
myObject.myProperty = "Value"
- Method: Similar to a function call
1
myObject.myMethod(argument)
- Property: Similar to a variable
Adding Undo Groups
Since a lot of operations will happen during your script execution, you’ll want to decide what will happen when you hit
1 |
â + Z |
/
1 |
CTRL + Z |
Doing so it pretty easy, we just have wrap our code between the
1 |
beginUndoGroup() |
and
1 |
endUndoGroup() |
methods of the
1 |
app |
object. This method takes one argument which is the name that will be displayed in After Effects
1 |
Edit > History |
menu.
1 |
{ |
2 |
app.beginUndoGroup("Demo Script"); |
3 |
|
4 |
// Creating project |
5 |
var currentProject = (app.project) ? app.project : app.newProject(); |
6 |
|
7 |
// Creating comp |
8 |
var compSettings = cs = [1280, 720, 1, 10, 24]; |
9 |
var defaultCompName = "Demo" |
10 |
var currentComp = (currentProject.activeItem) ? currentProject.activeItem : currentProject.items.addComp(defaultCompName, cs[0], cs[1], cs[2], cs[3], cs[4]); |
11 |
currentComp.openInViewer(); |
12 |
|
13 |
app.endUndoGroup(); |
14 |
} |
Creating the Background Layer
To create our background layer, we will use the
1 |
layers |
sub-object of our
1 |
currentComp |
. Call the
1 |
addSolid() |
method and send it these arguments :
- Layer color
- Array of floating numbers (between 0 and 1). To get that value you have to divide each of your RGB values by 255 or use this jsFiddle I made: http://jsfiddle.net/seblavoie/mezGe/43/embedded/result/
- Layer name
- Layer width
- Layer height
- Layer pixel ratio
1 |
{ |
2 |
app.beginUndoGroup("Demo Script"); |
3 |
|
4 |
// Creating project |
5 |
var currentProject = (app.project) ? app.project : app.newProject(); |
6 |
|
7 |
// Creating comp |
8 |
var compSettings = cs = [1280, 720, 1, 10, 24]; |
9 |
var defaultCompName = "Demo" |
10 |
var currentComp = (currentProject.activeItem) ? currentProject.activeItem : currentProject.items.addComp(defaultCompName, cs[0], cs[1], cs[2], cs[3], cs[4]); |
11 |
currentComp.openInViewer(); |
12 |
|
13 |
// Creating background layer |
14 |
var backgroundLayer = currentComp.layers.addSolid([93, 5, 2], "Background", cs[0], cs[1], cs[2]); |
15 |
|
16 |
app.endUndoGroup(); |
17 |
} |
Adding the Grid Effect
The best way to create our centered cross is by using the Grid effect on our background layer. To do that, we will use our
1 |
backgroundLayer |
variable which refers to
1 |
currentComp.layers.byName("backgroundLayer") |
and we will use its
1 |
Effects |
property.
1 |
// Adding the grid effect |
2 |
backgroundLayer.Effects.addProperty("Grid"); |
3 |
backgroundLayer.property("Effects").property("Grid").property("Anchor").setValue([0,0]); |
4 |
backgroundLayer.property("Effects").property("Grid").property("Corner").expression = "[width/2, height/2]"; |
5 |
backgroundLayer.property("Effects").property("Grid").property("Color").setValue([0,0,0]); |
6 |
backgroundLayer.property("Effects").property("Grid").property("Blending Mode").setValue(2); |
There are some things your should notice here. First, the
1 |
property() |
method is chainable which means that you can call it multiple times to reach the sub-property you want to get.
-
1
backgroundLayer.property("Opacity")
: Layer’s opacity.
-
1
backgroundLayer.property("Effects").property("Grid").property("Opacity")
: Grid effect’s opacity.
Second, we use the method
1 |
setValue() |
when we want to set a value but not when we want to set an expression.
Creating the Wipe Layer
To add the wipe effect, we’ll create a new layer and use the Radial Wipe effect.
1 |
// Creating the wipe layer |
2 |
var wipeLayer = currentComp.layers.addSolid([0.1, 0.1, 0.1], "Wipe", cs[0], cs[1], cs[2]); |
3 |
wipeLayer.Effects.addProperty("Radial Wipe"); |
4 |
wipeLayer.property("Effects").property("Radial Wipe").property("Wipe").setValue(2); // Counterclockwise |
5 |
wipeLayer.property("Opacity").setValue(50); |
6 |
|
7 |
// Setting wipe transition animation |
8 |
wipeLayer.property("Effects").property("Radial Wipe").property("Transition Completion").setValueAtTime(0, 100); |
9 |
wipeLayer.property("Effects").property("Radial Wipe").property("Transition Completion").setValueAtTime(1, 0); |
10 |
wipeLayer.property("Effects").property("Radial Wipe").property("Transition Completion").expression = "loopOut('Cycle')"; |
We used the method
1 |
setValueAtTime() |
to set keyframes and a
1 |
loopOut("Cycle") |
to make the animation loop (makes sense right?).
Adding the Text Layer
Playing with text is a little different since you have to change the source text value properties directly.
1 |
// Adding text layer |
2 |
var textLayer = currentComp.layers.addText("Countdown"); |
3 |
var textProperty = textLayer.property("Source Text"); |
4 |
var textPropertyValue = textProperty.value; |
5 |
|
6 |
// Changing source text settings |
7 |
textPropertyValue.resetCharStyle(); |
8 |
textPropertyValue.fontSize = 200; |
9 |
textPropertyValue.fillColor = [0, 0, 0]; |
10 |
textPropertyValue.justification = ParagraphJustification.CENTER_JUSTIFY; |
11 |
textProperty.setValue(textPropertyValue); |
12 |
|
13 |
// Adding expression to source text |
14 |
textProperty.expression = "Math.floor(10-time)"; |
15 |
|
16 |
// Adjusting text layer anchor point |
17 |
var textLayerHeight = textLayer.sourceRectAtTime(0, false); |
18 |
textLayer.property("Anchor Point").setValue([0, textLayerHeight.height / 2 * -1]); |
We changed our text value properties and used
1 |
setValue() |
to resend it to our text layer. Also, we used a simple expression to make our countdown.
1 |
Math.floor() |
is a Javascript function that will remove the decimal part of a number. After that we center the anchor point by using the
1 |
sourceRectAtTime() |
method.
Adding the Ellipses
To add the ellipses we will use the
1 |
addShape() |
method and give it a vector group and a vector shape. We’ll also make a little function to avoid code repetition.
1 |
// Adding shape layer for the circles |
2 |
var shapeLayer = currentComp.layers.addShape(); |
3 |
|
4 |
// Adding circle shapes group |
5 |
var shapeGroup = shapeLayer.property("Contents").addProperty("ADBE Vector Group"); |
6 |
|
7 |
// Adding circle shapes |
8 |
createEllipse(shapeGroup, 200); |
9 |
createEllipse(shapeGroup, 400); |
10 |
|
11 |
// Adding black stroke to the shapes |
12 |
var stroke = shapeGroup.property("Contents") |
13 |
.addProperty("ADBE Vector Graphic - Stroke") |
14 |
.property("Color").setValue([0, 0, 0]); |
15 |
|
16 |
function createEllipse(shapeGroup, size) { |
17 |
var ellipse = shapeGroup.property("Contents").addProperty("ADBE Vector Shape - Ellipse"); |
18 |
var ellipseSize = ellipse.property("Size").setValue([size,size]); |
19 |
} |
Line 5 is really important since you won’t be able to find the
1 |
Contents |
property in neither the documentation nor in your After Effects interface for the moment, thanks to Dan Ebbert for his help (http://forums.creativecow.net/thread/227/22280).
We used a custom little function instead of duplicating the ellipse creation. You can use functions as you wish.
Basic rule of thumb: If you’re copy-pasting lines of code, consider using a function.
For the rest we just modified the shape’s properties. You may want to refer to Adobe After Effects CS6 Scripting Guide to see them listed.
You may have noticed the
1 |
var stroke |
line is looking a little different than what we’ve written yet. Javascript supports chaining across multiple lines. The result will be the same and there isn’t a good or bad way, it’s a personnal coding style choice you may or may not want to adopt.
Conclusion
The possibilities of scripting are endless and can make a really powerful tool once mastered. Here’s some more documentation about scripting and Javascript:
- Adobe After Effects CS6 Scripting Guide
- MotionScript
- Javascript on Codeacademy
- Introduction To Writing Scripts
Or check out Envato Elements, which offers millions of stock items, including motion graphics projects for After Effects, with creative templates for slideshows, titles, logos, lower thirds, intros, and text effects.