Hostingheaderbarlogoj
Join InMotion Hosting for $3.49/mo & get a year on Tuts+ FREE (worth $180). Start today.
Advertisement

Introduction To The Basics Of After Effects Scripting

by
Gift

Want a free year on Tuts+ (worth $180)? Start an InMotion Hosting plan for $3.49/mo.

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.


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

newProject()

method of the

app

object and wrapping it between curly brackets.

{
  // Creating project
  app.newProject();
}

The

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

app

object’s sub-objects

project

which contains the project created in the first line and the

items

sub-object which gives you access to the folders and compositions you see in your project window in After Effects.

{
  // Creating project
    app.newProject();

  // Creating comp
    app.project.items.addComp("Demo", 1280, 720, 1, 10, 24);
}

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.

{
  // Creating project
  var currentProject  = (app.project) ? app.project: app.newProject();

  // Creating comp
  var compSettings    = cs = [1280, 720, 1, 10, 24];
  var defaultCompName = "Demo";
  var currentComp     = (currentProject.activeItem) ? currentProject.activeItem: currentProject.items.addComp(defaultCompName, cs[0], cs[1], cs[2], cs[3], cs[4]);
  currentComp.openInViewer();
}

The

var

keyword indicates that the following variable is a new variable. That’s why, on line 9, we don’t use the

var

keyword anymore because we want to use

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

    currentProject

    which will equal to

    app.project

    if

    app.project

    is not undefined and will otherwise equal to

    app.newProject()

    .

  • Line 6: Create new variables

    compSettings

    and

    cs

    which both equals to a new array of values.

  • Line 7: Create new variable

    defaultCompName

    which contains the name we will give to our comp.

  • Line 8: Create new variable
    currentComp

    which will equal to the

    activeItem

    property of our

    currentProject

    object. If it’s not undefined and will otherwise equal to the result of the

    addComp

    method of the

    items

    sub-object of

    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

    currentComp

    method

    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.
    • var myVar = "String value";
    • var myVar = 2;
  • Array: Contains multiple values. Arrays can be declared in two ways.
    • var myVar = array("value1", "value2", 3);
    • var myVar = ["value1", "value2", 3];
  • Function: Part of code designed to perform a specific task.
    • function myFunction(argument) {
      // Do something
        }
  • Object: The object is a little more complex but, for now, you must know it has properties and methods.
    • Property: Similar to a variable
      myObject.myProperty = "Value"
    • Method: Similar to a function call
      myObject.myMethod(argument)

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

⌘ + Z

/

CTRL + Z

Doing so it pretty easy, we just have wrap our code between the

beginUndoGroup()

and

endUndoGroup()

methods of the

app

object. This method takes one argument which is the name that will be displayed in After Effects

Edit > History

menu.

{
  app.beginUndoGroup("Demo Script");

  // Creating project
  var currentProject  = (app.project) ? app.project : app.newProject();

  // Creating comp
  var compSettings    = cs = [1280, 720, 1, 10, 24];
  var defaultCompName = "Demo"
  var currentComp     = (currentProject.activeItem) ? currentProject.activeItem : currentProject.items.addComp(defaultCompName, cs[0], cs[1], cs[2], cs[3], cs[4]);
  currentComp.openInViewer();

  app.endUndoGroup();
}

Creating the Background Layer

To create our background layer, we will use the

layers

sub-object of our

currentComp

. Call the

addSolid()

method and send it these arguments :

{
  app.beginUndoGroup("Demo Script");

  // Creating project
  var currentProject  = (app.project) ? app.project : app.newProject();

  // Creating comp
  var compSettings    = cs = [1280, 720, 1, 10, 24];
  var defaultCompName = "Demo"
  var currentComp     = (currentProject.activeItem) ? currentProject.activeItem : currentProject.items.addComp(defaultCompName, cs[0], cs[1], cs[2], cs[3], cs[4]);
  currentComp.openInViewer();

  // Creating background layer
  var backgroundLayer = currentComp.layers.addSolid([93, 5, 2], "Background", cs[0], cs[1], cs[2]);

  app.endUndoGroup();
}

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

backgroundLayer

variable which refers to

currentComp.layers.byName("backgroundLayer")

and we will use its

Effects

property.

  // Adding the grid effect
  backgroundLayer.Effects.addProperty("Grid");
  backgroundLayer.property("Effects").property("Grid").property("Anchor").setValue([0,0]);
  backgroundLayer.property("Effects").property("Grid").property("Corner").expression = "[width/2, height/2]";
  backgroundLayer.property("Effects").property("Grid").property("Color").setValue([0,0,0]);
  backgroundLayer.property("Effects").property("Grid").property("Blending Mode").setValue(2);

There are some things your should notice here. First, the

property()

method is chainable which means that you can call it multiple times to reach the sub-property you want to get.

  • backgroundLayer.property("Opacity")

    : Layer’s opacity.

  • backgroundLayer.property("Effects").property("Grid").property("Opacity")

    : Grid effect’s opacity.

Second, we use the method

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.

  // Creating the wipe layer
  var wipeLayer = currentComp.layers.addSolid([0.1, 0.1, 0.1], "Wipe", cs[0], cs[1], cs[2]);
  wipeLayer.Effects.addProperty("Radial Wipe");
  wipeLayer.property("Effects").property("Radial Wipe").property("Wipe").setValue(2); // Counterclockwise
  wipeLayer.property("Opacity").setValue(50);

  // Setting wipe transition animation
  wipeLayer.property("Effects").property("Radial Wipe").property("Transition Completion").setValueAtTime(0, 100);
  wipeLayer.property("Effects").property("Radial Wipe").property("Transition Completion").setValueAtTime(1, 0);
  wipeLayer.property("Effects").property("Radial Wipe").property("Transition Completion").expression = "loopOut('Cycle')";

We used the method

setValueAtTime()

to set keyframes and a

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.

// Adding text layer
var textLayer                   = currentComp.layers.addText("Countdown");
var textProperty                = textLayer.property("Source Text");
var textPropertyValue           = textProperty.value;

// Changing source text settings
textPropertyValue.resetCharStyle();
textPropertyValue.fontSize      = 200;
textPropertyValue.fillColor     = [0, 0, 0];
textPropertyValue.justification = ParagraphJustification.CENTER_JUSTIFY;
textProperty.setValue(textPropertyValue);

// Adding expression to source text
textProperty.expression         = "Math.floor(10-time)";

// Adjusting text layer anchor point
var textLayerHeight             = textLayer.sourceRectAtTime(0, false);
textLayer.property("Anchor Point").setValue([0, textLayerHeight.height / 2 * -1]);

We changed our text value properties and used

setValue()

to resend it to our text layer. Also, we used a simple expression to make our countdown.

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

sourceRectAtTime()

method.


Adding the Ellipses

To add the ellipses we will use the

addShape()

method and give it a vector group and a vector shape. We’ll also make a little function to avoid code repetition.

// Adding shape layer for the circles
var shapeLayer = currentComp.layers.addShape();  

// Adding circle shapes group
var shapeGroup = shapeLayer.property("Contents").addProperty("ADBE Vector Group");

// Adding circle shapes
createEllipse(shapeGroup, 200);
createEllipse(shapeGroup, 400);

// Adding black stroke to the shapes
var stroke = shapeGroup.property("Contents")
             .addProperty("ADBE Vector Graphic - Stroke")
             .property("Color").setValue([0, 0, 0]);

function createEllipse(shapeGroup, size) {
  var ellipse     = shapeGroup.property("Contents").addProperty("ADBE Vector Shape - Ellipse");
  var ellipseSize = ellipse.property("Size").setValue([size,size]);
}

Line 5 is really important since you won’t be able to find the

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

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:

Advertisement