Essential After Effects expressions list

Essential After Effects Expressions List

Unlock the true power of Adobe After Effects with our essential expressions list and cheat sheet. Whether you're a beginner looking to understand AE expressions or a pro aiming to streamline your workflow for After Effects, this guide is for you!

What Are After Effects Expressions?

After Effects expressions are small pieces of code, based on JavaScript, that allow you to automate animations, link properties, and create complex relationships between layers and effects without manually creating hundreds of keyframes. Think of them as mini-programs that tell After Effects what to do with a property over time or based on other properties. Learning After Effects expressions can drastically speed up your workflow and open up a new world of creative possibilities, from simple wiggles to complex text animation expressions.

If you've ever found yourself painstakingly keyframing a repetitive motion or wishing one layer could intelligently react to another, then expressions in AE are your answer. From simple wiggles to complex procedural animations, they are a cornerstone of professional motion graphics and visual effects in After Effects.

The Basics of Using Expressions

Using expressions is straightforward:

1. Add an Expression: Alt-click (Option-click on Mac) the stopwatch icon next to any layer property in the timeline (like Position, Scale, Opacity). This opens the expression editor field.

2. Use the Pick Whip: This spiral icon (@) lets you visually link properties. Drag it to another property, and After Effects writes the basic linking code for you – a great way to start!

3. Enable/Disable: Click the equals sign (=) next to an expression field to toggle it on or off.

Quick Navigation: Expression List

Essential After Effects Expressions

Let's break down some of the most useful expressions, from fundamental building blocks to specialized advanced expressions. This After Effects expressions list is designed to be a go-to resource. Some of these expressions or their concepts were inspired by the excellent library at PlainlyVideos.com – check them out for even more ideas!

Wiggle Expression 963.2, 541.8

The legendary wiggle() creates random, organic-looking movement. It's controlled by frequency (how many wiggles per second) and amplitude (how much the property deviates). Optional parameters include octaves (adds detail), amp_mult (octave amplitude multiplier), and t (base time).

To wiggle a single axis (e.g., Y-axis of Position): [value[0], wiggle(2,50)[1]];

// --- Wiggle Controls ---
var frequency = 2;   // Wiggles per second (e.g., 1 for slow, 5 for fast)
var amplitude = 50;  // Max amount of change (e.g., 50 pixels for position)
var octaves = 1;     // Optional: Layers of detail in the wiggle (usually 1-3)
var amp_mult = 0.5;  // Optional: How much an octave affects amplitude (0 to 1)
var timeToWiggleAt = time; // Optional: Base time for wiggle (default is current time)

wiggle(frequency, amplitude, octaves, amp_mult, timeToWiggleAt);
Commonly Applied to: Position, Scale, Rotation, Opacity, Effect Properties
Visual representation of Wiggle effect in After Effects
An object subtly wiggling using the wiggle expression.
loopOut() / loopIn() 75.0%

Essential for repeating keyframed animations. loopOut() affects animation *after* the last keyframe; loopIn() affects it *before* the first. The type parameter (e.g., "cycle", "pingpong", "offset", "continue") defines loop behavior. numKeyframes (default 0 for all) specifies how many keyframes from the end/start define the loop segment.

// --- LoopOut Example (applied after last keyframe) ---
var loopType = "cycle"; // "cycle", "pingpong", "offset", or "continue"
var numKeyframesToLoop = 0; // 0 means all keyframes, 1 means segment between last two, etc.
loopOut(loopType, numKeyframesToLoop);

// --- LoopIn Example (applied before first keyframe) ---
// loopIn(loopType, numKeyframesToLoop);
Commonly Applied to: Any keyframable property (Position, Scale, Rotation, Opacity, Time Remap)
Visual representation of Loop effect in After Effects
An animation sequence seamlessly looping.
Time 3.75s

Simply returns the current composition time in seconds. Fundamental for creating animations that progress consistently or at a constant rate.

// Basic time usage (returns current time in seconds)
time;
// Example: Continuous Rotation (apply to Rotation property)
var rotationSpeed = 90; // Degrees per second
time * rotationSpeed;
// Example: Constant Horizontal Movement (apply to Position property)
var initialX = value[0]; // Or a specific starting X value like 100
var speedX = 200; // Pixels per second
[initialX + time * speedX, value[1]]; // Keeps original Y
Commonly Applied to: Rotation, Position, Opacity (for timed fades), driving other expressions
Visual representation of Time expression for continuous rotation
An object continuously rotating based on the time expression.
Value 960.0, 540.0

Represents the property's original, pre-expression value (from keyframes or the value set in the UI). Crucial for adding to or modifying existing animations non-destructively.

// Example: Add a small wiggle to existing keyframed position
value + wiggle(0.5, 15);
Commonly Applied to: Any property to modify its existing keyframed animation.
valueAtTime(t) 850.0, 480.0

Returns the value of the property it's applied to, but at a specific time `t` (in seconds) you provide, rather than the current composition time. Excellent for creating delays or echo effects.

// --- Delayed Follow Example (apply to Position property of follower layer) ---
var leaderLayer = thisComp.layer("LeaderLayerName"); // Change "LeaderLayerName" to the name of your leader layer
var delayInSeconds = 0.5; // How much time delay

leaderLayer.transform.position.valueAtTime(time - delayInSeconds);
Commonly Applied to: Position, Scale, Rotation, Opacity (to follow another layer with a delay)
Index 3

Returns the layer's own number in the layer stack (the topmost layer is 1, second is 2, etc.). Very useful for creating automatic offsets or variations across multiple duplicated layers.

// Example: Staggered Opacity for duplicated layers
var baseOpacity = 100;
var opacityDecrementPerLayer = 10; // Each layer below will be 10% less opaque
baseOpacity - (index - 1) * opacityDecrementPerLayer; // (index-1) so first layer is full opacity
Commonly Applied to: Any property to create variations across duplicated layers (e.g., Position offset, Rotation offset, Color variations, Opacity)
Linking to Expression Controls Slider: 72.5

Link parts of your expression to Effect Controls (like "Slider Control", "Checkbox Control", "Color Control" found under Effect > Expression Controls) for easy adjustments without editing the code. Add the control to a layer (often a Null named "Controller") and pick-whip to it.

// Example: Control Wiggle Frequency with a slider named "FreqControl" on this layer
var freq = effect("FreqControl")("Slider");
var amp = 50; // Amplitude can still be fixed or linked to another slider
wiggle(freq, amp);
Commonly Applied to: Any expression where you want user-friendly controls for variables (e.g., wiggle frequency/amplitude, color values, checkbox toggles).
Math.sin() / Math.cos() 572.3

Standard trigonometric functions for creating smooth, wave-like or oscillating motions. Angles must be in radians (use degreesToRadians(degrees) to convert).

// Example: Y Position sine wave movement
var initialY = value[1];       // Initial Y position of the layer
var amplitude = 50;          // How high/low the wave goes (pixels)
var frequency = 2;           // How many full cycles per second

var yPositionOffset = Math.sin(time * frequency * 2 * Math.PI) * amplitude;
[value[0], initialY + yPositionOffset]; // Keep original X, animate Y
Commonly Applied to: Position (for wave motion), Rotation (for oscillation), Scale (for pulsing), Opacity (for flickering).
An object moving up and down in a smooth sine wave.
random() / seedRandom() 68.4%

random(min, max) generates a pseudo-random number between min and max (or 0 and min if only one argument). To get a consistent random value per layer that doesn't change over time, use seedRandom(seedValue, timeless = true) before random(), often using index as the seedValue.

// Example: Random opacity per layer that stays consistent
var minOpacity = 20;
var maxOpacity = 80;
seedRandom(index, true); // Seed with layer index, timeless makes it fixed per layer
random(minOpacity, maxOpacity);
// Example: Random opacity that changes every frame (no seedRandom or timeless=false)
random(20, 80);
Commonly Applied to: Opacity, Position, Scale, Rotation, Color (for random variations), Text Animator Selector Amount.
linear() / ease() 82.5, 82.5

Powerful interpolation functions. As an input t (often time) goes from tMin to tMax, linear() transitions the output from value1 to value2. ease() applies an S-curve (ease-in and -out), while easeIn() and easeOut() provide one-sided easing.

// Example: Scale from 50% to 100% between time 0 and 2 seconds, with S-curve easing
var startScale = 50;
var endScale = 100;
var startTime = 0;
var endTime = 2;
var s = ease(time, startTime, endTime, startScale, endScale);
[s,s];
// Example: Opacity fades from 0 to 100 between seconds 1 and 3 using linear
linear(time, 1, 3, 0, 100);
Commonly Applied to: Any numerical property for smooth transitions over time or based on a controller (e.g., Opacity, Scale, Position, Rotation, Effect parameters).
Visual representation of linear and ease interpolation
An object smoothly scaling up with an ease curve.
if / else 100.0%

Standard conditional logic. If the condition evaluates to true, the expression returns statement A; otherwise, it returns statement B.

// Example: Layer Opacity is 100% after 2 seconds, otherwise 0%
var timeThreshold = 2; // Seconds
if (time > timeThreshold) {
  100; // Opacity if condition is true
} else {
  0;   // Opacity if condition is false
}
Commonly Applied to: Any property to switch between values or behaviors based on conditions (e.g., Opacity, Text Source, Effect enable/disable via checkbox).
Inertial Bounce 960.0, 685.2

A community-favorite script to create natural bounce or spring effects as keyframed animation settles. Adjust amplitude (bounce amount), frequency (bounces per second), and decay (how quickly it fades).

// --- Inertial Bounce Controls ---
var amp = .055;     // Amplitude: How much bounce (e.g., 0.01 for subtle, 0.2 for more)
var freq = 1.8;     // Frequency: Bounces per second (e.g., 1 to 5)
var decayRate = 5.2;// Decay: How quickly bounce fades (e.g., 3 for slower, 10 for faster)

// --- Inertial Bounce Script (do not edit below unless you know what you're doing) ---
var n = 0;
if (numKeys > 0){
    n = nearestKey(time).index;
    if (key(n).time > time) n--;
}
var t = (n > 0) ? time - key(n).time : 0;
if (n > 0 && t >= 0){
    var v = velocityAtTime(key(n).time - thisComp.frameDuration/10);
    value + v * amp * Math.sin(freq * t * 2 * Math.PI) / Math.exp(decayRate * t);
} else {
    value;
}
Commonly Applied to: Position, Scale, Rotation (after keyframed movement).
Visual representation of Inertial Bounce effect
An object settling with a natural bouncing motion.
Position: Circular Orbit 1150.3, 488.1

Makes this layer orbit in a circle around a specified "CenterLayerName". Customize radius and speed.

// --- Orbit Controls ---
var centerLayerName = "CenterLayer"; // Name of the layer to orbit around
var orbitRadius = 500;             // Radius of the orbit in pixels
var orbitSpeed = 2;                // Speed of orbit (higher is faster, negative reverses)

// --- Orbit Script ---
var centerPt = thisComp.layer(centerLayerName).transform.position;
var currentAngle = time * orbitSpeed;
var x = centerPt[0] + Math.cos(currentAngle) * orbitRadius;
var y = centerPt[1] + Math.sin(currentAngle) * orbitRadius;

if (centerPt.length > 2 && transform.position.length > 2) { // If both are 3D
    var z = value[2]; // Maintain this layer's Z, or use centerPt[2] to orbit in center's Z plane
    [x, y, z];
} else { // For 2D layers
    [x, y];
}
Commonly Applied to: Position.
Visual representation of Circular Orbit
A layer smoothly orbiting a central point or another layer.
Position: DVD Bounce 420.7, 280.9

Simulates the classic DVD logo screensaver, making the layer move diagonally and bounce off the composition edges. Speeds are adjustable.

// --- Bounce Controls ---
var horizontalSpeed = 300; // Speed in X direction (pixels per second)
var verticalSpeed = 200;   // Speed in Y direction (pixels per second)

// --- Bounce Script ---
var layerRect = sourceRectAtTime(time, false);
var effectiveLayerWidth = layerRect.width * transform.scale[0]/100;
var effectiveLayerHeight = layerRect.height * transform.scale[1]/100;
var compW = thisComp.width;
var compH = thisComp.height;
var minX = effectiveLayerWidth / 2;
var maxX = compW - (effectiveLayerWidth / 2);
var minY = effectiveLayerHeight / 2;
var maxY = compH - (effectiveLayerHeight / 2);
var t = time - inPoint;
var rawX = minX + (t * horizontalSpeed);
var rawY = minY + (t * verticalSpeed);
var bounceCountX = Math.floor(rawX / (maxX - minX));
var bounceCountY = Math.floor(rawY / (maxY - minY));
var finalX, finalY;

if (bounceCountX % 2 == 1){ finalX = maxX - (rawX % (maxX - minX)); }
else { finalX = minX + (rawX % (maxX - minX)); }
if (bounceCountY % 2 == 1){ finalY = maxY - (rawY % (maxY - minY)); }
else { finalY = minY + (rawY % (maxY - minY)); }
[finalX, finalY];
Commonly Applied to: Position.
Visual representation of DVD Screensaver Bounce
A layer bouncing off the edges of the screen like a DVD logo.
Position: Elastic Connection 910.6, 590.3

Creates a spring-like connection where this layer follows a "leaderLayerName" with bouncy, overshooting motion. Adjust rest length, stiffness, and damping. Can be computationally intensive due to its frame-by-frame iterative calculation.

// --- Spring Controls ---
var leaderLayerName = "leader"; // Name of the layer to follow
var restLength = 20;          // Desired resting distance between leader and follower anchor points
var springStiffness = 0.1;    // Stiffness of the spring (e.g., 0.05 for softer, 0.2 for stiffer)
var dampingFactor = 0.95;     // Damping (0 to 1). Lower is more springy, higher is less oscillation.

// --- Spring Script ---
var leader = thisComp.layer(leaderLayerName);
var fDur = thisComp.frameDuration;
var currTime = time;
var pFollower = position.valueAtTime(0); // Follower's initial position (at its inPoint)
var vFollower = [0,0,0]; // Follower's initial velocity
if (position.length === 2) vFollower = [0,0]; // Match 2D/3D for velocity array

for (var t = 0; t <= currTime - thisLayer.inPoint; t += fDur){ // Iterate for duration layer has been active
    var leaderTime = thisLayer.inPoint + t; // Time to sample leader
    if (leaderTime > leader.outPoint) leaderTime = leader.outPoint; // Clamp if leader ends
    if (leaderTime < leader.inPoint) leaderTime = leader.inPoint;   // Clamp if leader starts later

    var pLeader = leader.transform.position.valueAtTime(leaderTime);
    var delta = pFollower - pLeader;
    var currentDist = length(delta);
    var springForceMagnitude = (currentDist - restLength) * springStiffness; // Hooke's Law
    
    var springForceVector = [0,0,0];
    if (currentDist > 0.001) { // Avoid division by zero if coincident
      springForceVector = normalize(delta) * springForceMagnitude;
    }
    if (position.length === 2 && springForceVector.length === 3) { // Ensure vector matches dimension
        springForceVector = [springForceVector[0], springForceVector[1]];
    }
    
    vFollower = (vFollower - springForceVector) * dampingFactor; // Apply force to velocity, then damp
    pFollower += vFollower * fDur; // Update follower's position (integrate velocity)
}
pFollower;
Commonly Applied to: Position.
Visual representation of Elastic Connection
A layer following another with a springy, elastic motion.
Position: Loopable Wiggle 972.1, 528.4

Creates a position wiggle that loops seamlessly over a defined loopDurationSeconds. Useful for continuous, random-looking background movements.

// --- Loopable Wiggle Controls ---
var wiggleFrequency = 1;    // Wiggles per second
var wiggleAmplitude = 110;  // Wiggle amount in pixels
var loopDurationSeconds = 3;// Duration of the loop in seconds

// --- Loopable Wiggle Script ---
var t = time % loopDurationSeconds;
var wiggle1 = wiggle(wiggleFrequency, wiggleAmplitude, 1, 0.5, t);
var wiggle2 = wiggle(wiggleFrequency, wiggleAmplitude, 1, 0.5, t - loopDurationSeconds);
linear(t, 0, loopDurationSeconds, wiggle1, wiggle2);
Commonly Applied to: Position.
Position: Place Between Two Layers 960.0, 540.0

Dynamically positions the current layer exactly halfway between two other specified layers, referenced by their stack index (e.g., layer 1 and 2) or by name.

// --- Referencing Layers ---
// Option 1: By Layer Index (1 is top layer, 2 is second, etc.)
var layerA = thisComp.layer(1); 
var layerB = thisComp.layer(2);

// Option 2: By Layer Name (uncomment and use instead if preferred)
// var layerA = thisComp.layer("NameOfFirstLayer");
// var layerB = thisComp.layer("NameOfSecondLayer");

// --- Calculation ---
(layerA.transform.position + layerB.transform.position) / 2;
Commonly Applied to: Position.
Visual representation of Placing Layer Between Two Others
A layer maintaining its position exactly halfway between two other moving layers.
Position: 2D Physics (Gravity & Wall Bounce) 960.0, 850.5

A simplified 2D physics simulation. Layers respond to gravity and bounce off composition edges (walls), which can be set independently using sliders. It uses an iterative calculation from the layer's in-point, which can become slow for many objects or long durations.

Setup: Create a Null Layer named "PhysicsSettings2D". Add Slider Controls to it named "Gravity Y", "Wall Bounce Factor", "Global Damping", "Min X Wall", "Max X Wall", "Min Y Wall", "Max Y Wall". On each physics object layer, add sliders for "Initial Velocity X", "Initial Velocity Y", and "Radius".

// --- Global Physics Settings (Reads from Null Layer "PhysicsSettings2D") ---
var settingsNullName = "PhysicsSettings2D";
var gravY = 980, wallBounce = 0.7, damping = 0.995; // Defaults
var minXWall = 0, maxXWall = thisComp.width, minYWall = 0, maxYWall = thisComp.height; // Defaults

try {
    var settingsLayer = thisComp.layer(settingsNullName);
    gravY = settingsLayer.effect("Gravity Y")("Slider");
    wallBounce = settingsLayer.effect("Wall Bounce Factor")("Slider");
    damping = settingsLayer.effect("Global Damping")("Slider");
    minXWall = settingsLayer.effect("Min X Wall")("Slider");
    maxXWall = settingsLayer.effect("Max X Wall")("Slider");
    minYWall = settingsLayer.effect("Min Y Wall")("Slider");
    maxYWall = settingsLayer.effect("Max Y Wall")("Slider");
} catch(err) { /* Use defaults if settings layer or sliders are missing */ }

// --- Individual Object Properties (Reads from sliders on THIS layer) ---
var iVelX = 0, iVelY = 0, radiusThis = 25; // Default radius
try { iVelX = effect("Initial Velocity X")("Slider"); } catch(e){ iVelX = (index % 7 - 3) * 20; } // Default variation
try { iVelY = effect("Initial Velocity Y")("Slider"); } catch(e){ iVelY = -(index % 5) * 50 -50; } // Default variation
try { radiusThis = Math.max(1, effect("Radius")("Slider")); } catch(e){} // Ensure radius is at least 1

// --- Simulation ---
var dt = thisComp.frameDuration;
var p = transform.position.valueAtTime(inPoint); // Start at initial keyframed position or value
var v = [iVelX, iVelY]; // Initial velocity

// Effective boundaries considering object radius
var effectiveMinX = minXWall + radiusThis;
var effectiveMaxX = maxXWall - radiusThis;
var effectiveMinY = minYWall + radiusThis;
var effectiveMaxY = maxYWall - radiusThis;

// Iterate from layer's inPoint up to the current time to simulate physics progression
for (var t = inPoint; t < time; t += dt){
    // Apply Gravity (only to Y velocity)
    v[1] = v[1] + gravY * dt;

    // Apply Global Damping (Air Resistance)
    v = v * damping;       

    // Update Position based on velocity
    p = p + v * dt;

    // Boundary Collisions & Bounce
    // X-axis
    if (p[0] < effectiveMinX) { 
        p[0] = effectiveMinX; 
        v[0] *= -wallBounce; 
    } else if (p[0] > effectiveMaxX) { 
        p[0] = effectiveMaxX; 
        v[0] *= -wallBounce; 
    }
    // Y-axis
    if (p[1] < effectiveMinY) { 
        p[1] = effectiveMinY; 
        v[1] *= -wallBounce; 
    } else if (p[1] > effectiveMaxY) { 
        p[1] = effectiveMaxY; 
        v[1] *= -wallBounce; 
    }
}
p; // Resulting position for the current frame
Commonly Applied to: Position (of 2D layers).
2D objects bouncing within custom composition boundaries under gravity
2D objects falling with gravity and bouncing off defined composition walls.
Rotation: 2D LookAt 0.0x +57.3

Rotates a 2D layer to always point towards another specified "targetLayerName". An artworkPointingOffsetDegrees might be needed if the layer's art doesn't point right (0 degrees) by default.

// --- LookAt Controls ---
var targetLayerName = "targetLayer"; // Name of the layer to point towards
var artworkPointingOffsetDegrees = 0; // Adjust if your artwork points up (e.g., 90 or -90), left (e.g., 180) by default

// --- LookAt Script ---
function calculateLookAtAngle(fromPoint, toPoint) {
    var deltaX = toPoint[0] - fromPoint[0];
    var deltaY = toPoint[1] - fromPoint[1];
    var angleRad = Math.atan2(deltaY, deltaX);
    return radiansToDegrees(angleRad);
}
var thisLayerPosition = transform.position;
var targetPosition = thisComp.layer(targetLayerName).transform.position;
calculateLookAtAngle(thisLayerPosition, targetPosition) + artworkPointingOffsetDegrees;
Commonly Applied to: Rotation (of a 2D Layer).
Visual representation of 2D LookAt Rotation
An arrow layer always pointing towards a moving target layer.
Rotation: 3D LookAt 12, 25, 3

Orients a 3D layer (or camera) so its Z-axis points from a "viewPointLayerName" (or its own position) towards a "targetLayerName" in 3D space, using After Effects' built-in lookAt().

// --- 3D LookAt Controls ---
var targetLayerName = "Target";         // Name of the layer to look AT
var viewPointLayerName = "Point";       // Name of layer defining the viewpoint. 
                                        // If this layer IS the viewpoint, use thisLayer.name or an empty string.

// --- 3D LookAt Script ---
var targetObj = thisComp.layer(targetLayerName);
var fromPosition;

if (viewPointLayerName == "" || thisComp.layer(viewPointLayerName) == thisLayer) {
    fromPosition = toWorld(transform.anchorPoint); // This layer is the viewpoint
} else {
    var viewPointObj = thisComp.layer(viewPointLayerName);
    fromPosition = viewPointObj.toWorld(viewPointObj.transform.anchorPoint);
}
var targetPosition = targetObj.toWorld(targetObj.transform.anchorPoint);
lookAt(fromPosition, targetPosition);
Commonly Applied to: Orientation (of a 3D Layer or Camera).
Visual representation of 3D LookAt Rotation
A 3D layer always oriented towards a 3D target.
Rotation: Ignore Parent Rotation 0.0x +10.0

Applied to a child layer's Rotation, it maintains its own world-space rotation, effectively counteracting rotation inherited from its parent.

// --- Ignore Parent Rotation Script ---
if (hasParent) {
  value - parent.transform.rotation;
} else {
  value; // No parent, so just use its own rotation
}
Commonly Applied to: Rotation.
Visual representation of Ignoring Parent Rotation
A child layer staying upright while its parent rotates.
Rotation: Swinging Pendulum 0.0x -22.5

Creates a realistic decaying pendulum swing on Rotation. Customize frequency (swings per second), initial amplitude (degrees), and decay rate.

// --- Pendulum Controls ---
var swingFrequency = 1.0;   // Swings per second (e.g., 1 full back-and-forth per second)
var initialAmplitude = 45;  // Initial swing angle in degrees (e.g., 45 degrees to each side)
var decayRate = 0.5;        // How quickly swing dampens (0 = no decay, higher = faster stop)

// --- Pendulum Script ---
initialAmplitude * Math.sin(time * swingFrequency * Math.PI * 2) * Math.exp(-decayRate * time);
Commonly Applied to: Rotation.
Visual representation of Swinging Pendulum
A layer swinging back and forth like a pendulum, gradually slowing down.
Scale: Maintain When Parented 100.0, 100.0

Counteracts a parent layer's scale transformations to keep this child layer's visual size consistent as if it were not parented or its parent was at 100% scale.

// --- Maintain Scale Script ---
var newScale = [];
if (hasParent) {
  var parentScale = parent.transform.scale.value;
  for (var i = 0; i < parentScale.length; i++){ // Works for 2D or 3D scale
    if (parentScale[i] === 0) { // Avoid division by zero
        newScale[i] = value[i]; // Or some large number if you want it to "disappear"
    } else {
        newScale[i] = value[i] * 100 / parentScale[i];
    }
  }
} else {
  newScale = value; // No parent, so use its own scale value
}
newScale;
Commonly Applied to: Scale.
Scale: Rhythmic Pulse 115.0, 115.0

Creates a rhythmic scaling pulse. Controls include speed, amount, base scale, phase, and mode (symmetric grow/shrink, grow only, or shrink only).

// --- Pulse Controls ---
var pulseSpeed  = 1.0;      // Cycles per second (e.g., 1.0 for one full pulse per second)
var pulseAmount = 20;       // Percentage of scale change (e.g., 20 means ±20% if mode is 0)
var baseScaleValue = [100, 100]; // Resting scale [X,Y] or [X,Y,Z] for 3D layers
var phaseOffsetCycles = 0.0;// Shifts start point of pulse (0 to 1, e.g., 0.25 starts at peak)
var pulseMode = 1;          // 0 = grow & shrink; 1 = only grow from base; 2 = only shrink from base

// --- Pulse Script ---
var angle = (time * pulseSpeed + phaseOffsetCycles) * 2 * Math.PI;
var rawOffset;
if (pulseMode == 0) { rawOffset = Math.sin(angle) * pulseAmount; }
else if (pulseMode == 1) { rawOffset = ((1 - Math.cos(angle)) / 2) * pulseAmount; }
else if (pulseMode == 2) { rawOffset = -((1 - Math.cos(angle)) / 2) * pulseAmount; }
else { rawOffset = Math.sin(angle) * pulseAmount; } // Fallback
var finalScale = [];
for (var i = 0; i < baseScaleValue.length; i++) {
    finalScale[i] = baseScaleValue[i] + rawOffset;
}
finalScale;
Commonly Applied to: Scale.
Visual representation of Rhythmic Scale Pulse
A layer rhythmically pulsing in size.
Opacity: Fade by Camera Distance 60.0%

Dynamically fades a 3D layer's opacity based on its distance from the active camera, between a defined startFadeDistance and endFadeDistance.

// --- Fade Controls ---
var startFadeDistance = 500; // Distance (pixels) from camera where fade begins (100% opacity closer than this)
var endFadeDistance = 1500;  // Distance (pixels) from camera where layer is fully faded (0% opacity further than this)
 
// --- Fade Script ---
var camPosition;
try { 
    camPosition = thisComp.activeCamera.toWorld([0,0,0]);  
} catch (err) {  
    var compWidthForDefaultCam = thisComp.width * thisComp.pixelAspect;  
    var defaultCamZ = (compWidthForDefaultCam/2) / Math.tan(degreesToRadians(19.799)); // Approx 50mm lens
    camPosition = [thisComp.width/2, thisComp.height/2, -defaultCamZ];  
}  
var layerPosition = toWorld(anchorPoint);  
var distanceToCam = length(camPosition, layerPosition);  
linear(distanceToCam, startFadeDistance, endFadeDistance, 100, 0);
Commonly Applied to: Opacity (of a 3D Layer).
Visual representation of Opacity Fade by Camera Distance
A 3D layer fading out as it moves away from the camera.
Stroke Width: Maintain with 2D Scale 2.5px

Adjusts a stroke's width to counteract the layer's 2D scale transformations, making the stroke appear visually consistent even if the layer is scaled.

// --- Maintain Apparent Stroke Width Script ---
// No user-editable variables needed for this typical implementation.
// It divides the original stroke 'value' by a measure of the layer's current scale.
var scaleFactor = length(toComp([0,0]), toComp([0.7071,0.7071]));
if (scaleFactor === 0) scaleFactor = 0.001; // Avoid division by zero
value / scaleFactor;
Commonly Applied to: Shape Layer Stroke Width, Text Layer Stroke Width (if using layer styles).
Visual representation of Maintaining 2D Stroke Width on Scale
A stroke appearing to maintain its thickness even when the layer is scaled up or down.
Text Styling Styled Text!

Dynamically control text properties like font, size, color, and tracking using text.sourceText.style methods (AE 17.0+). Chain methods for complex styling. Per-character styling (AE 25.0+) uses optional startIndex and numOfCharacters arguments in many styling methods.

// Example: Changing Font, Size, and Fill Color
text.sourceText.style
   .setFont("Impact")
   .setFontSize(120)
   .setFillColor([1, 0.5, 0]); // Orange: [Red, Green, Blue] values 0-1
// Example: Adding a Stroke and Changing Text Content
var styleObj = text.sourceText.style;
styleObj = styleObj.setStrokeColor([0.2, 0.8, 0.2]); // Green stroke
styleObj = styleObj.setStrokeWidth(5);
styleObj = styleObj.setApplyStroke(true); // Important to make stroke visible
styleObj = styleObj.setTracking(20);
styleObj.setText("Styled with Expressions!"); // This must be the last style modification if changing text content
Commonly Applied to: Source Text (to control its styling attributes).
Text dynamically changing font, color, and stroke via expressions.
Expression Selectors (Targeting Characters) 100.0% (for some)

Use conditional logic within an Expression Selector to apply an animator's effect to only specific characters based on their textIndex (0 for first char, 1 for second, etc.).

// --- Targeting Controls ---
// Example: Affect only the first 3 characters (indices 0, 1, 2)
var charactersToTarget = 3;
if (textIndex < charactersToTarget) { 
    100; // Full effect
} else { 
    0;   // No effect
}
// Example: Affect characters from index 2 up to (but not including) index 5
var startIndex = 2; // Third character
var endIndex = 5;   // Affects up to character before this index (i.e., characters at index 2, 3, 4)

if (textIndex >= startIndex && textIndex < endIndex) { 
    100; // Apply full animator effect
} else { 
    0;   // No effect for other characters
}
Commonly Applied to: Text Animator > Expression Selector > Amount.
Text animator targeting specific characters
Only a specific range of characters is affected by the text animator.
Expression Selectors (Every Nth Character) Pattern

Targets every Nth character using an Expression Selector. You can control the interval (N) and an offset to change the starting point (e.g., to select even or odd characters).

// --- Nth Character Selector Controls ---
// Apply this to a Text Animator's Expression Selector > Amount property.
var nthValue = 2; // Select every 2nd character (for every other character)
                  // Change to 3 for every 3rd character, etc.
var startOffset = 0; // 0 to start with the Nth character (e.g. if Nth=2, characters 1,3,5... using 0-based textIndex)
                     // 1 to start with the (Nth + offset) character (e.g. if Nth=2 & offset=1, characters 0,2,4...)

// --- Nth Character Script ---
if (nthValue <= 0) nthValue = 1; // Prevent division by zero or negative values

if ((textIndex + startOffset) % nthValue == 0) {
    100; // Apply full animator effect to this character
} else {
    0;   // No effect for other characters
}
Commonly Applied to: Text Animator > Expression Selector > Amount.
Dynamic Text Scale 78.2, 78.2

Automatically scales a text layer proportionally to ensure it fits within predefined width and height boundaries. Useful for MOGRTs where text length can vary.

// --- Dynamic Text Scaling Controls ---
var maxWidthBoundary = 500; // Desired maximum width for the text
var maxHeightBoundary = 100; // Desired maximum height for the text
var overallScalePercentage = 100; // Additional overall scale (100 = no change from fit)
var measureAtCurrentTime = true; // true: measure text at current time; false: measure at time 0

// --- Scaling Script ---
var timeToMeasureAt = measureAtCurrentTime ? time : 0;
var textRect = sourceRectAtTime(timeToMeasureAt);
var currentTextWidth = textRect.width;
var currentTextHeight = textRect.height;
var widthScaleFactor = 1; 
var heightScaleFactor = 1;

if (currentTextWidth > 0) widthScaleFactor = maxWidthBoundary / currentTextWidth;
if (currentTextHeight > 0) heightScaleFactor = maxHeightBoundary / currentTextHeight;

var finalFitScaleFactor = Math.min(widthScaleFactor, heightScaleFactor);
var s = finalFitScaleFactor * overallScalePercentage;

if (currentTextWidth === 0 || currentTextHeight === 0) { s = overallScalePercentage; }
else if (finalFitScaleFactor >= 1 && overallScalePercentage < 100) { s = overallScalePercentage; }
else if (finalFitScaleFactor < 1) { s = finalFitScaleFactor * 100 * (overallScalePercentage / 100); }
else { s = overallScalePercentage; }
[s, s];
Commonly Applied to: Scale (of a Text Layer).
Visual representation of Dynamic Text Scaling
Text automatically resizing to fit a defined box.
Dynamic Layer Anchor Point 60.5, 30.2

Adjusts a layer's anchor point to one of nine logical positions (e.g., center, top-left) based on its content's bounding box (sourceRectAtTime). While extremely useful for text layers, it can also apply to shape layers or other layers where sourceRectAtTime provides meaningful dimensions. Ensures consistent transformations like scale or rotation, regardless of content changes.

// --- Anchor Point Control ---
// Choose a number from 1 to 9 for anchorPosition:
// 1=Top Left,    2=Top Center,    3=Top Right
// 4=Middle Left, 5=Middle Center, 6=Middle Right
// 7=Bottom Left, 8=Bottom Center, 9=Bottom Right
var anchorPosition = 5; 
var measureAtCurrentTime = true; 

// --- Anchor Point Script ---
var timeToMeasureAt = measureAtCurrentTime ? time : 0;
var layerRect = thisLayer.sourceRectAtTime(timeToMeasureAt); 
var L = layerRect.left;
var T = layerRect.top;
var W = layerRect.width;
var H = layerRect.height;
var xAnchor, yAnchor;

switch(anchorPosition){
    case 1: xAnchor=L; yAnchor=T; break;
    case 2: xAnchor=L+W/2; yAnchor=T; break;
    case 3: xAnchor=L+W; yAnchor=T; break;
    case 4: xAnchor=L; yAnchor=T+H/2; break;
    case 5: xAnchor=L+W/2; yAnchor=T+H/2; break;
    case 6: xAnchor=L+W; yAnchor=T+H/2; break;
    case 7: xAnchor=L; yAnchor=T+H; break;
    case 8: xAnchor=L+W/2; yAnchor=T+H; break;
    case 9: xAnchor=L+W; yAnchor=T+H; break;
    default: xAnchor=L+W/2; yAnchor=T+H/2;
}
[xAnchor, yAnchor];
Commonly Applied to: Anchor Point (primarily for Text or Shape Layers).
Source Text: Digital Timer 00:05:23

Converts a numerical value from a "Slider Control" (representing total seconds) on the same layer into an HH:MM:SS timecode format on a text layer.

// --- Timer Control ---
// Add a "Slider Control" effect to this text layer.
// The slider's value will be interpreted as total seconds.
var totalSecondsInput = Math.round(effect("Slider Control")("Slider").value);

// --- Timer Script ---
var hrs = Math.floor(totalSecondsInput / 3600);
var mins = Math.floor((totalSecondsInput % 3600) / 60);
var secs = totalSecondsInput % 60;

function addLeadingZero(n) {
  return n < 10 ? "0" + n : "" + n;
}
addLeadingZero(hrs) + ":" + addLeadingZero(mins) + ":" + addLeadingZero(secs);
Commonly Applied to: Source Text (of a Text Layer, requires a Slider Control).
Visual representation of Digital Timer
A text layer displaying a formatted timecode driven by a slider.
Source Text: Copy Text & Style Mirrored

Makes this text layer completely mirror both the text content and all styling (font, size, color, etc.) from another specified source text layer.

// --- Source Layer ---
// Change "SourceTextLayerName" to the actual name of your source text layer.
var sourceLayer = thisComp.layer("SourceTextLayerName"); 

// --- Copy Script ---
var sourceStyle = sourceLayer.text.sourceText.getStyleAt(0, time); // Gets style from 1st char of source at current time
sourceStyle.setText(sourceLayer.text.sourceText.value); // Applies source style and text content
Commonly Applied to: Source Text (of a Text Layer).
Visual representation of Copying Text and Style
One text layer perfectly mirroring another's content and style.

Learning Resources

Diving into After Effects expressions can seem daunting, but there's a wealth of knowledge available to help you learn and troubleshoot:

Official Adobe After Effects Expressions Language Reference
This is the definitive guide from Adobe. It provides comprehensive details on all available functions, objects, and syntax. It's an excellent resource for understanding the core mechanics and discovering new possibilities.

Dan Ebberts' MotionScript.com
A legendary and foundational resource in the After Effects community. Dan provides incredibly detailed explanations, practical examples, and solutions to common (and uncommon) animation problems using expressions. Many widely-used expressions originated or were popularized here.

Plainly's After Effects Expressions Library
A great collection of useful expressions for various tasks, often with clear explanations and use cases. A good place to find ready-to-use snippets and learn new techniques.

Adobe After Effects Community Forum
A great place to ask questions, share your work, and get help from fellow users and Adobe staff. If you're stuck on an expression, chances are someone in the community can offer guidance or point you to a solution.

YouTube Tutorials
Many motion designers and After Effects educators share tutorials on YouTube. Channels like School of Motion, Ukramedia, Workbench, Ben Marriott, and Jake Bartlett (among many others) cover expressions, from beginner introductions to advanced techniques.

Conclusion

After Effects expressions are a deep and powerful feature that can significantly enhance your animation capabilities and efficiency. Start with the basics like wiggle(), loopOut(), and time, and gradually explore more complex possibilities, including text animation expressions and dynamic styling. Happy animating!

Back to blog

Leave a comment

Please note, comments need to be approved before they are published.