Expressions & Snippets
Last update : 24 April 2021

Abstract

Here are list of useful expressions I curated and written.
⚠️This page is currently being sorted into the pages under Cookbook, so some expressions that you usually reference here has been moved to those pages.

Javascript basics

1
// Declaration
2
var myVariable;
3
var 🍎,🍐,🍐
4
​
5
// Initialization
6
var fruit = 🍎;
7
var fruitArray = [🍏,🍎,🍐,🍊,πŸ‹,🍌,πŸ‰,πŸ‡];
8
String
9
"string is text"
10
​
11
// For-Loops
12
for( var i = 0; i < value ; i++){
13
statement
14
}
15
​
16
//if/else statements
17
if (fruit){
18
statement} else {
19
statement}
20
​
21
// Shorthand if statement
22
if(x==1) 10;
23
24
// Using ternary operation
25
condition ? exprIfTrue : exprIfFalse
26
27
// ternary
28
x = (y>=5)? 20:50; // if checkbox is true, 20 else 50
29
​
30
//Object
31
var x = {firstName:"John", lastName:"Doe"}; //
32
​
33
// Regular Expressions (Regex)
34
"\n"
35
​
36
// Single line comment
37
​
38
/* Multi-line comment
39
Etiam aliquet et mi quis tempor.
40
Nulla ullamcorper, sapien in molestie rhoncus,
41
justo magna molestie dolor,
42
Nullam dignissim interdum mi sit a */
43
​
Copied!

Preferred shorthand for naming variables

1
velocity = v or vel
2
multiplier = mul;
3
position = pos, myPos
4
distance = dst
5
sourceRect = s
6
myLayer
7
myNumLayers
8
​
9
target = tgt
Copied!

Good practice

  • Declare variable before loop statements

Transformation

Constant value change using Time (drifting)

1
time*50;
2
​
3
// for adding to an alement in an array such as position:
4
value + [time*50,0]
5
​
6
// for value change to start at inPoint
7
(time-inPoint)*50
8
​
9
// Throw (move at a constant speed without keyframes)
10
veloc = -10; //horizontal velocity (pixels per second)
11
x = position[0] + (time - inPoint) *veloc;
12
y = position[1];
13
[x,y]
14
Copied!

Align to X-axis or Y-axis

basic
if X or Y
1
var dst = 50;
2
var x= thisComp.layer(index-1).transform.position[0]+dst ;
3
value + [x,0] ;
Copied!
1
var xy = 0;
2
var dst = 50;
3
var x= thisComp.layer(index-1).transform.position[0]+dst ;
4
var x= thisComp.layer(index-1).transform.position[0]+dst
5
xy==0? value+[x,0]: value+[0,y]; // Ternary conditional operator
Copied!

Changing anchor point

1
var s = sourceRectAtTime();
2
​
3
// Top left β†–
4
[s.left, s.top] //
5
​
6
// Top center ↑
7
[s.left, s.top] + [s.width / 2, 0];
8
​
9
// Top right β†—
10
[s.left, s.top] + [s.width, 0];
11
​
12
// Center left ←
13
[s.left, s.top] + [0, s.height / 2];
14
​
15
// Center
16
[s.left, s.top] + [s.width, s.height] / 2;
17
​
18
// Center right β†’
19
[s.left, s.top] + [s.width, s.height / 2]
20
​
21
// Bottom left ↙
22
​
23
[s.left, s.top] + [0, s.height]
24
​
25
// Bottom center ↓
26
[s.left, s.top] + [s.width / 2, s.height]
27
​
28
//Bottom right β†˜
29
[s.left, s.top] + [s.width, s.height]
Copied!

Random positioning XYZ

1
seed = 20;
2
min = [25,25,-1900]; // Connect to 3D Point Control for control
3
max = [thisComp.width,thisComp.height,50]
4
​
5
seedRandom(seed,true);
6
​
7
random(min,max);
8
​
9
// This is same as this
10
​
11
// x= random(min[0],max[0]);
12
// y= random(min[1],max[1]);
13
// z= random(min[2],max[2]);
14
​
15
//[x,y,z]
Copied!

Scale

Maintain Scale When Parented

both axis
uniform
1
s = [];
2
ps = parent.transform.scale.value;
3
for (i = 0; i < ps.length; i++){
4
s[i] = value[i]*100/ps[i];
5
}
6
s
Copied!
1
arr = value;
2
ps = parent.transform.scale.value;
3
ratio = 100/ ps[0];
4
​
5
arr*ratio;
Copied!

Rotation

​Aim constraint by Kevin Camp / Dan Ebberts

no parent
w/ parent
3D layers
1
target = thisComp.layer("Null 1"); // set this to the layer to aim at
2
p = position - target.position;
3
radiansToDegrees( Math.atan2( p[1], p[0] ) )- 90
Copied!
1
target = thisComp.layer("controls"); // set this to the layer to aim at
2
p = thisLayer.toWorld(anchorPoint) - target.position;
3
radiansToDegrees(Math.atan2(p[1], p[0])) - 90
Copied!
1
target = thisComp.layer("Null 1");// set this to the layer to aim at
2
lookAt( position, target.position )
Copied!
1
L = thisComp.layer("Null 1");
2
v = L.toWorldVec([1,0]);
3
radiansToDegrees(Math.atan2(v[1],v[0]))
Copied!

Auto-orient along path by Videolancer​

1
try{
2
cornerEase = 3;
3
p = transform.position;
4
t = Math.min(Math.max(time,p.key(1).time+.001),p.key(p.numKeys).time);
5
pre = position.valueAtTime(t-thisComp.frameDuration*cornerEase);
6
post = position.valueAtTime(t+thisComp.frameDuration*cornerEase);
7
delta = post-pre;
8
orient = radiansToDegrees(Math.atan2(delta[0],-delta[1]));
9
value+orient+180
10
}catch(err){value}
Copied!

Parent

Avoid inhering rotation

1
value – parent.transform.rotation
Copied!

Opacity βœ…

Flickering / Strobe

1
// VARIABLES
2
minSeg = 1.5; //minimum interval (must be > 0)
3
maxSeg = 2.5; //maximum interval (must be > minSeg)
4
5
// flickering duration
6
minFlicker = .5; //must be less than minSeg
7
maxFlicker = 1; // must be less than minSeg
8
flickerDur = random(minFlicker,maxFlicker);
9
10
//initial conditions
11
segEndTime = 0;
12
i = 1;
13
​
14
// Continuous loop: create a fixed random segment value and add to segEndTime
15
while (time >= segEndTime){
16
i += 1;
17
seedRandom(i,true);
18
segEndTime = segEndTime + random(minSeg,maxSeg);
19
}
20
​
21
// Switch back to use the current time as input to the random seed.
22
seedRandom(1,false);
23
​
24
// As time > threshold, flicker
25
if (time > segEndTime - flickerDur){random(0,100) }else{ 100 }
26
​
27
// Source: http://www.motionscript.com/expressions-lab-ae65/swinging-light.html
28
// Also see: http://www.motionscript.com/mastering-expressions/random-3.html
Copied!

Random opacity wiggle

1
// control = thisComp.layer("control"); // connect to null layer with sliders
2
freq = 1;
3
amp = 100;
4
octave = 1;
5
amp_mult = 3;
6
​
7
wiggle(freq, amp, octave, amp_mult, time)
Copied!

Random opacity wiggle with flicker

1
// control = thisComp.layer("control"); // connect to null layer with sliders
2
freq = 1;
3
amp = 100;
4
octave = 1;
5
amp_mult = 3;
6
​
7
opacity = wiggle(freq, amp, octave, amp_mult, time)
8
​
9
​
10
// VARIABLES
11
minSeg = control.effect("minSeg")("Slider"); //minimum interval (must be > 0)
12
maxSeg = control.effect("maxSeg")("Slider");; //maximum interval (must be > minSeg)
13
​
14
// flickering duration
15
minFlicker = control.effect("minFlicker")("Slider");; //must be less than minSeg
16
maxFlicker = control.effect("maxFlicker")("Slider");; // must be less than minSeg
17
flickerDur = random(minFlicker, maxFlicker);
18
​
19
//initial conditions
20
segStartTime = 0;
21
segEndTime = 0;
22
i = 1;
23
​
24
// Continuous loop: create a fixed random segment value and add to segEndTime
25
while (time >= segEndTime) {
26
i += 1;
27
seedRandom(i, true);
28
segStartTime = segEndTime;
29
segEndTime = segEndTime + random(minSeg, maxSeg);
30
}
31
​
32
// Switch back to use the current time as input to the random seed.
33
seedRandom(1, false);
34
​
35
// As time moves threshold, flicker
36
if (time > segEndTime - flickerDur) {
37
random(0, 100)
38
} else {
39
opacity
40
}
Copied!

Random opacity with sin function

1
// Mass flickering
2
vel = 50;
3
seedRandom(0,true);
4
Math.sin(time*vel+random(index))*100;
Copied!
1
// 'Wave flickering'
2
vel = 50;
3
seedRandom(0,true);
4
Math.sin(time*vel+index)*100;
5
​
6
// Combining
7
bool = 1 ;
8
vel = 50;
9
seedRandom(0,true);
10
wave=Math.sin(time*vel+index)*100;
11
rand =Math.sin(time*vel+random(index))*100;
12
bool==0 ? wave : rand;
Copied!

Random opacity turn on

1
seed = 29;
2
threshold = linear(time,0,thisComp.duration,0,100); // or Connect to slider to animate switch on & off
3
​
4
seedRandom(seed,true);
5
randValue = random(0,90);
6
​
7
if(randValue < threshold){
8
100;} else 0
Copied!

Random opacity fade on

v1
v2
1
seed = 29;
2
seedRandom(seed,true);
3
delay = random(0,1);
4
t = framesToTime(20) // or usethisComp.duration
5
​
6
linear(time, 0+delay,t+delay,0,100)
Copied!
1
//VARIABLES
2
fadeDuration = 1;
3
maxDelay = .5
4
​
5
//SETUP
6
seedRandom(index,true);
7
delay = random(maxDelay);
8
t = time -(inPoint + delay);
9
​
10
// EXECUTION
11
linear(t,0,fadeDuration,0,100);
Copied!

Distance-based opacity fade by Animoplex

1
// Distance Based Opacity Fade
2
// Original: https://helpx.adobe.com/after-effects/using/expression-examples.html
3
// Full Tutorial: https://www.youtube.com/watch?v=I-Acdl_l9G0&t=14s
4
​
5
startFade = 500;
6
endFade = 3000;
7
try {
8
C = thisComp.activeCamera.toWorld([0,0,0]);
9
} catch(err) {
10
w = thisComp.width * thisComp.pixelAspect;
11
z = (w / 2)/Math.tan(degreesToRadians(19.799));
12
C = [0,0,-z];
13
}
14
P = toWorld(anchorPoint);
15
d = length(C, P);
16
linear(d, startFade, endFade, 100, 0)
Copied!

Transparent backside of 3D layer

1
if (toCompVec([0, 0, 1])[2] > 0 ) value else 0
Copied!

Colour

1
txt = thisComp.layer("Text").text.sourceText;
2
c = parseInt(txt,16);
3
r = c >> 16;
4
g = (c & 0x00ff00) >> 8;
5
b = c & 0xff;
6
[r,g,b,255]/255
Copied!

Random fill

1
// Apply on fill
2
seedRandom(index,true); // change true to 0 for constant change
3
random([0,0,0,1],[1,1,1,1])
Copied!

Camera

x-rot
y-rot
1
f = 2; // number of frames before and after to average
2
v = [0,0];
3
for (i = -f; i <= f; i++){
4
v += position.velocityAtTime(i*thisComp.frameDuration + time);
5
}
6
v /= (f*2+1);
7
a = Math.atan2(v[1],v[0]);
8
radiansToDegrees(a)
9
​
10
// turn off auto-orient
Copied!
1
//y-rotation for 3d layers
2
​
3
f = 2; // number of frames before and after to average
4
v = [0, 0, 0];
5
for (i = -f; i <= f; i++) {
6
v += position.velocityAtTime(i * thisComp.frameDuration + time);
7
}
8
v /= (f * 2 + 1);
9
a = Math.atan2(v[0], v[2]);
10
radiansToDegrees(a)
Copied!

Motion

Wiggle

1
// frequency by amplitude = how fast by how much
2
wiggle(20,30);
3
​
4
[value[0], wiggle(20,30)[1]] // wiggle y-axis only
5
​
6
​
7
// Smooth wiggle β€” freq,amp,octave,amp_mult
8
wiggle(20,30,1,2,time)
9
​
10
​
11
// Jumpy Wiggle 1 (moves at a random FPS) Makes wiggle skip and hold rather than move fluidly.
12
​
13
v=wiggle(5,50);
14
if(v < 50)v=0;
15
if(v > 50)v=100;
16
v;
17
​
18
// Jumpy Wiggle 2 (moves at a defined FPS)
19
fps=5; //frequency
20
amount=50; //amplitude
21
wiggle(fps,amount,octaves = 1, amp_mult = 0.5,(Math.round(time*fps))/fps);
Copied!

Inertial Bounce / Overshoot

1
// Inertial Bounce (moves settle into place after bouncing around a little)
2
// // Source: https://forums.creativecow.net/docs/forums/post.php?forumid=227&postid=19145&univpostid=19145&pview=t
3
amp = .05;
4
freq = 4.0;
5
decay = 2.0; // springyness
6
n = 0;
7
if (numKeys > 0){
8
n = nearestKey(time).index;
9
if (key(n).time > time){
10
n--;
11
}
12
}
13
if (n == 0){
14
t = 0;
15
}else{
16
t = time - key(n).time;
17
}
18
​
19
if (n > 0){
20
v = velocityAtTime(key(n).time - thisComp.frameDuration/10);
21
​
22
value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
23
}else{
24
value;
25
}
Copied!

Constant move in either x or y axis / Random walker

1
WIP---
2
choice = Math.floor(random(0,2));
3
seedRandom(0,false);
4
stepx = random(0,50);
5
stepy = random(0,20);
6
if(choice ==0){
7
value + [stepx,0];} else if( choice ==1){
8
value +[0,stepy];}
Copied!

​

Responsive Systems / Setups

Dynamic-sizing text box / lower-third (depreciated, see new code)

1
// Create two text layers named "DATA1" & "DATA2"
2
// Variables
3
pad = 50;
4
xPad = 15;
5
yPad = 15;
6
​
7
seed = 1 // allow you to change between two text layers
8
​
9
// Making it work
10
if(seed==1){
11
src = thisComp.layer("DATA1")
12
}else {
13
src = thisComp.layer("DATA2")
14
};
15
​
16
box = src.sourceRectAtTime(time-src.inPoint);
17
[box.width + pad + xPad, box.height+pad +yPad];
Copied!

Slider with center fade on

1
v = transform.position[0] // x
2
d = length(v,thisComp.width/2);
3
maxDist= 960;
4
​
5
ease(d,0,maxDist,100,0)
Copied!
1
/* There needs to be two layers named 'startCard' & 'endCard'
2
This allows rotation value to dynamically change when layers are inserted or removed.
3
All duplicates need to be placed within these two layers
4
*/
5
​
6
//anchor point
7
radius = 500
8
value+[0,0,radius]
9
​
10
// Y rotation
11
​
12
startIndex=thisComp.layer("startCard").index;
13
endIndex = thisComp.layer("endCard").index;
14
numpt = startIndex-endIndex+1; // total number of layers
15
myIndex = index-startIndex;
16
angle = 360/numpt
17
​
18
myIndex*angle+
Copied!

Linking layers' rotation with opacity

Using distance & vector position

1
// Make sure there is a camera
2
​
3
//Opacity
4
startVal = 0;
5
endVal = 100;
6
fadeAngle = 180;
7
​
8
v = toCompVec([0,0,1]); // layer position to comp position in Z
9
d = length(toWorld(anchorPoint),thisComp.layer("Camera 1").toWorld([0,0,0]));
10
c = v[2]/d;
11
ease(c,Math.cos(degreesToRadians(fadeAngle)),1.0,startVal,endVal)
12
​
Copied!

Using rotation

1
angle = transform.yRotation%360;
2
minAngle = 0;
3
maxAngle = 360;
4
mid = (maxAngle+minAngle)/2;
5
if (angle < mid)
6
linear(angle,minAngle,mid,100,0)
7
else
8
linear(angle,mid,maxAngle,0,100)
Copied!

Time Remapping / Playback βœ…

Random frame playback

1
// Source Dan Ebbert
2
​
3
fr = 12; // frame rate;
4
​
5
numFrames = 8;
6
​
7
seedRandom(index,true);
8
​
9
seg = Math.floor(time*fr);
10
​
11
f = Math.floor(random(numFrames));
12
​
13
for (i = 0; i < seg; i++)
14
​
15
f = (f + Math.floor(random(1,numFrames)))%numFrames;
16
​
17
framesToTime(f);
Copied!

Random delayed/advanced layer playback

1
seedRandom(index,true);
2
myDelay = random(1,10);
3
time + myDelay;
Copied!

Play one frame at a time (without 'float time')

1
fps = 1;
2
x = framesToTime(Math.round(time*fps))
3
//There probably is a better way but I cannot figured it out right now.
Copied!

Random still frame (Good for spriting)

1
//Apply this to a composition with a image sequence inside
2
seedRandom(0,true);
3
t= random(0,72);
4
framesToTime(t);
Copied!

Playback at every nth frames

1
n = 3 // frames
2
time*n
Copied!

Hold and play every nth frames [source]

1
n = 3; // play every __ frames
2
m = 3; // hold each frame ___ times
3
​
4
f= timeToFrames(timeRemap);
5
​
6
p=Math.floor(f/m);
7
​
8
framesToTime(p*n);
Copied!

Triggering animations with marker

Workflow

  1. 1.
    Create a preComp with all the different types of animation
  2. 2.
    In the main Comp, put an expression on the time remapping of that preComp
  3. 3.
    Add markers to trigger animations
  4. 4.
    Learn more
1
//https://gist.github.com/animoplex/cecf1c64aec4f2733ecd0edbebf4786d
Copied!

Staggering animations

1
// Copying animation of a layer, and start it at inPoint of layer
2
thisComp.layer(index+1).transform.position.valueAtTime(time-inPoint)
3
​
4
// Using delay
5
offset = 1;
6
thisComp.layer(index+1).transform.position.valueAtTime(time-offset)
Copied!

Radial scale up staggering βœ…

nsc
OF
1
// VARIABLES + SETUP
2
target = thisComp.layer("master").transform.scale;
3
maxDist = 1000;
4
maxDelay = 1;
5
​
6
dst = length(transform.position,[thisComp.width/2,thisComp.height/2]);
7
delay = linear(dst,0,maxDist,0,maxDelay);
8
​
9
// EXECUTION
10
target.valueAtTime(time-delay)
Copied!
1
//apply to scale
2
target = thisComp.layer("fade");
3
fade = target.effect("scale")(1);
4
delay = target.effect("delay")(1)*thisComp.frameDuration;
5
dist = length(thisLayer.toWorld(thisLayer.anchorPoint), target.toWorld(target.anchorPoint));
6
seed = seedRandom(15, true)
7
randomRange = target.effect("random")("Slider");
8
rand = (random(-randomRange, randomRange))*thisComp.frameDuration;
9
offset = delay/dist;
10
s = fade.valueAtTime(time - offset - rand);
11
[s,s]
Copied!

Effector opacity fade on βœ…

nsc
OF
1
//Create a null named "EFFECTOR"
2
//Add 2 Slider Control Effects renamed to "maxDist" and "delay"
3
​
4
​
5
// EXECUTE
6
target = thisComp.layer("EFFECTOR").transform
7
maxDist = thisComp.layer("EFFECTOR").effect("maxDist")("Slider");
8
maxDelay = thisComp.layer("EFFECTOR").effect("delay")("Slider");
9
​
10
dst = length(transform.position, target.position);
11
delay = linear(dst, 0, maxDist, 0, maxDelay);
12
​
13
// EXECUTION
14
target.opacity.valueAtTime(time - delay)
Copied!
1
​
2
​
Copied!

​

Last modified 3mo ago