redefinery

Properties and Keyframes

This section describes how to work with layer properties, including keyframed properties. The following topics are covered:


Accessing a property

To access a property, you need to traverse its path from the layer level, similar to twirling open property groups in the Timeline panel until you see the property.

The following code accesses the Position transform property for a layer.

// given:
// layer = Layer object

// Access the Transform property group, then the Position property
var positionProp = layer.property("Transform").property("Position");

The following code accesses the master Exposure property for the applied Exposure effect on the layer.

// given:
// layer = Layer object
// Exposure effect is the first effect

var effectsGroup = layer("Effects");
var exposureProp = effectsGroup.property(1).property("Exposure");

The above code refers to property groups and properties via their displayed names in the English version of After Effects. Names will most likely be different in non-English versions. You can refer to property groups and properties by their internal match names, so that a script can work regardless of language. You can use a script like rd: Gimme Prop Path to retrieve these match names. The following code accesses the Position property via its match name.

// given:
// layer = Layer object

var positionProp = layer.property("ADBE Transform Group").property("ADBE Position");

Accessing all properties for a layer

To access all properties for a layer, you need to iterate over the layer's child properties, then recursively doing the same if a property is a property group. This is easily done via a function that is initially called with the layer as its parameter, then called itself for any property group.The following code "walks" the property hierarchy for a layer.

// given:
// layer = Layer object

function scanPropGroupProperties(propGroup)
{
    var i, prop;

    // Iterate over the specified property group's properties
    for (i=1; i<=propGroup.numProperties; i++)
    {
        prop = propGroup.property(i);
        if (prop.propertyType === PropertyType.PROPERTY)    // Found a property
        {
            // Found a property
            // FYI: layer markers have a prop.matchName = "ADBE Marker"
        }
        else if ((prop.propertyType === PropertyType.INDEXED_GROUP) || (prop.propertyType === PropertyType.NAMED_GROUP))
        {
            // Found an indexed or named group, so check its nested properties
            scanPropGroupProperties(prop);
        }
    }
}

scanPropGroupProperties(layer);

Retrieving the selected properties

You can retrieve the selected properties to perform a batch operation on them, or to ensure that a single property or property group is selected.

The following code shows how to use the selectedProperties attribute to determine if the selection is a single property, and not multiple properties or a single property group.

// given:
// layer = Layer object

var selectedProps = layer.selectedProperties;
if ((selectedProps.length === 1) && (selectedProps[0].propertyType === PropertyType.PROPERTY))
{
    // requirements are met
    var prop = selectedProps[0];
}

Retrieving the current value of a property

A property can either be constant (non-keyframed) keyframed, with a possible expression applied. The value, however, depends on the type of value associated with the property.

The following code shows how to access the Scale value, and specifically the vertical (y) scale value, at the current composition time. Also, if there is an expression applied, it'll access the post-expression value.

// given:
// comp = CompItem object representing the composition
// layer = Layer object

var scaleProp = layer.property("ADBE Transform Group").property("ADBE Scale");
// comp.time is the current time; second parameter set to false = use post-expression value
var scaleValue = scaleProp.valueAtTime(comp.time, false);

// Value is an array; Y value is the second item in it
var scaleY = scaleValue[1];

Setting the value for a property

To set the value of a property, you need to first know if it has keyframes or not, otherwise an error will occur. Also, you need to know the type of value (e.g., an array, number, etc.) for the property.

The following code sets a layer's Opacity to 50%. If Opacity is keyframed, it'll set a new keyframe at the current time.

// given:
// comp = CompItem object representing the composition
// layer = Layer object

var opacityProp = layer.property("ADBE Transform Group").property("ADBE Opacity");
if (opacityProp.numKeys > 0)
{
    // Opacity is keyframed, so set the value at the current time
    opacityProp.setValueAtTime(comp.time, 50);
}
else
{
    opacityProp.setValue(50);
}

Selecting or deselecting a property

The following code toggles the selection of the Position property for a layer.

// given:
// layer = Layer object

var positionProp = layer.property("ADBE Transform Group").property("ADBE Position");
// Use the logical NOT operator (!) to toggle the value
positionProp.selected = !positionProp.selected;