2. Apply Value Drift to Array Element eg. Position Y
value + [0, time * 5];
3. Constant Horizontal Motion From Layer's Start Point
offset = (time - inPoint) * -10;
x = position[0] + offset;
y = position[1];
[x, y]
Align to X-axis or Y-axis
X-Axis
var xOffset = 350;
var prevLayerX = thisComp.layer(index - 1).transform.position[0];
[xOffset + prevLayerX, value[1]];
Y-Axis
var yOffset = 350;
var prevLayerY = thisComp.layer(index - 1).transform.position[1];
[value[0], yOffset + prevLayerY];
Changing anchor point
var s = sourceRectAtTime();
// Top left ↖
[s.left, s.top] //
// Top center ↑
[s.left, s.top] + [s.width / 2, 0];
// Top right ↗
[s.left, s.top] + [s.width, 0];
// Center left ←
[s.left, s.top] + [0, s.height / 2];
// Center
[s.left, s.top] + [s.width, s.height] / 2;
// Center right →
[s.left, s.top] + [s.width, s.height / 2]
// Bottom left ↙
[s.left, s.top] + [0, s.height]
// Bottom center ↓
[s.left, s.top] + [s.width / 2, s.height]
//Bottom right ↘
[s.left, s.top] + [s.width, s.height]
Random positioning XYZ
// Seed for randomization
var seed = 20;
// Define the minimum values for randomization
var minX = 25;
var minY = 25;
var minZ = -1900;
// Define the maximum values for randomization
var maxX = thisComp.width;
var maxY = thisComp.height;
var maxZ = 50;
// Set the random seed
seedRandom(seed, true);
// Generate random values within the defined ranges
var randomX = random(minX, maxX);
var randomY = random(minY, maxY);
var randomZ = random(minZ, maxZ);
// Create an array with the random values
[randomX, randomY, randomZ];
Alternatively, you can use array variables for a preferred and shorter expression.
// Seed for randomization
var seed = 20;
// Define the minimum and maximum values for randomization
var minValues = [25, 25, -1900];
var maxValues = [thisComp.width, thisComp.height, 50];
// Set the random seed
seedRandom(seed, true);
// Create an array with the random values
random(minValues,maxValues)
Scale
Maintain Scale When Parented
var scaleFactor = [];
var parentScale = parent.transform.scale.value;
for (var i = 0; i < parentScale.length; i++) {
scaleFactor[i] = (value[i] * 100) / parentScale[i];
}
scaleFactor;
target = thisComp.layer("Null 1"); // set this to the layer to aim at
p = position - target.position;
radiansToDegrees( Math.atan2( p[1], p[0] ) )- 90
target = thisComp.layer("controls"); // set this to the layer to aim at
p = thisLayer.toWorld(anchorPoint) - target.position;
radiansToDegrees(Math.atan2(p[1], p[0])) - 90
target = thisComp.layer("Null 1");// set this to the layer to aim at
lookAt( position, target.position )
try{
cornerEase = 3;
p = transform.position;
t = Math.min(Math.max(time,p.key(1).time+.001),p.key(p.numKeys).time);
pre = position.valueAtTime(t-thisComp.frameDuration*cornerEase);
post = position.valueAtTime(t+thisComp.frameDuration*cornerEase);
delta = post-pre;
orient = radiansToDegrees(Math.atan2(delta[0],-delta[1]));
value+orient+180
}catch(err){value}
Ignore Parent Rotation
value – parent.transform.rotation
Opacity ✅
Flickering / Strobe
// VARIABLES
minSeg = 1.5; //minimum interval (must be > 0)
maxSeg = 2.5; //maximum interval (must be > minSeg)
// flickering duration
minFlicker = .5; //must be less than minSeg
maxFlicker = 1; // must be less than minSeg
flickerDur = random(minFlicker,maxFlicker);
//initial conditions
segEndTime = 0;
i = 1;
// Continuous loop: create a fixed random segment value and add to segEndTime
while (time >= segEndTime){
i += 1;
seedRandom(i,true);
segEndTime = segEndTime + random(minSeg,maxSeg);
}
// Switch back to use the current time as input to the random seed.
seedRandom(1,false);
// As time > threshold, flicker
if (time > segEndTime - flickerDur){random(0,100) }else{ 100 }
// Source: http://www.motionscript.com/expressions-lab-ae65/swinging-light.html
// Also see: http://www.motionscript.com/mastering-expressions/random-3.html
Random opacity wiggle
// control = thisComp.layer("control"); // connect to null layer with sliders
freq = 1;
amp = 100;
octave = 1;
amp_mult = 3;
wiggle(freq, amp, octave, amp_mult, time)
Random opacity wiggle with flicker
// control = thisComp.layer("control"); // connect to null layer with sliders
freq = 1;
amp = 100;
octave = 1;
amp_mult = 3;
opacity = wiggle(freq, amp, octave, amp_mult, time)
// VARIABLES
minSeg = control.effect("minSeg")("Slider"); //minimum interval (must be > 0)
maxSeg = control.effect("maxSeg")("Slider");; //maximum interval (must be > minSeg)
// flickering duration
minFlicker = control.effect("minFlicker")("Slider");; //must be less than minSeg
maxFlicker = control.effect("maxFlicker")("Slider");; // must be less than minSeg
flickerDur = random(minFlicker, maxFlicker);
//initial conditions
segStartTime = 0;
segEndTime = 0;
i = 1;
// Continuous loop: create a fixed random segment value and add to segEndTime
while (time >= segEndTime) {
i += 1;
seedRandom(i, true);
segStartTime = segEndTime;
segEndTime = segEndTime + random(minSeg, maxSeg);
}
// Switch back to use the current time as input to the random seed.
seedRandom(1, false);
// As time moves threshold, flicker
if (time > segEndTime - flickerDur) {
random(0, 100)
} else {
opacity
}
Random opacity with sin function
// Mass flickering
vel = 50;
seedRandom(0,true);
Math.sin(time*vel+random(index))*100;
f = 2; // number of frames before and after to average
v = [0,0];
for (i = -f; i <= f; i++){
v += position.velocityAtTime(i*thisComp.frameDuration + time);
}
v /= (f*2+1);
a = Math.atan2(v[1],v[0]);
radiansToDegrees(a)
// turn off auto-orient
//y-rotation for 3d layers
f = 2; // number of frames before and after to average
v = [0, 0, 0];
for (i = -f; i <= f; i++) {
v += position.velocityAtTime(i * thisComp.frameDuration + time);
}
v /= (f * 2 + 1);
a = Math.atan2(v[0], v[2]);
radiansToDegrees(a)
Motion
Wiggle
// frequency by amplitude = how fast by how much
wiggle(20,30);
[value[0], wiggle(20,30)[1]] // wiggle y-axis only
// Smooth wiggle — freq,amp,octave,amp_mult
wiggle(20,30,1,2,time)
// Jumpy Wiggle 1 (moves at a random FPS) Makes wiggle skip and hold rather than move fluidly.
v=wiggle(5,50);
if(v < 50)v=0;
if(v > 50)v=100;
v;
// Jumpy Wiggle 2 (moves at a defined FPS)
fps=5; //frequency
amount=50; //amplitude
wiggle(fps,amount,octaves = 1, amp_mult = 0.5,(Math.round(time*fps))/fps);
// Inertial Bounce (moves settle into place after bouncing around a little)
// // Source: https://forums.creativecow.net/docs/forums/post.php?forumid=227&postid=19145&univpostid=19145&pview=t
amp = .05;
freq = 4.0;
decay = 2.0; // springyness
n = 0;
if (numKeys > 0){
n = nearestKey(time).index;
if (key(n).time > time){
n--;
}
}
if (n == 0){
t = 0;
}else{
t = time - key(n).time;
}
if (n > 0){
v = velocityAtTime(key(n).time - thisComp.frameDuration/10);
value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
}else{
value;
}
Constant move in either x or y axis / Random walker
/* There needs to be two layers named 'startCard' & 'endCard'
This allows rotation value to dynamically change when layers are inserted or removed.
All duplicates need to be placed within these two layers
*/
//anchor point
radius = 500
value+[0,0,radius]
// Y rotation
startIndex=thisComp.layer("startCard").index;
endIndex = thisComp.layer("endCard").index;
numpt = startIndex-endIndex+1; // total number of layers
myIndex = index-startIndex;
angle = 360/numpt
myIndex*angle+
Linking layers' rotation with opacity
Using distance & vector position
// Make sure there is a camera
//Opacity
startVal = 0;
endVal = 100;
fadeAngle = 180;
v = toCompVec([0,0,1]); // layer position to comp position in Z
d = length(toWorld(anchorPoint),thisComp.layer("Camera 1").toWorld([0,0,0]));
c = v[2]/d;
ease(c,Math.cos(degreesToRadians(fadeAngle)),1.0,startVal,endVal)
Dynamic-sizing text box / lower-third (depreciated, see new code)
// Create two text layers named "DATA1" & "DATA2"
// Variables
pad = 50;
xPad = 15;
yPad = 15;
seed = 1 // allow you to change between two text layers
// Making it work
if(seed==1){
src = thisComp.layer("DATA1")
}else {
src = thisComp.layer("DATA2")
};
box = src.sourceRectAtTime(time-src.inPoint);
[box.width + pad + xPad, box.height+pad +yPad];
Slider with center fade on
v = transform.position[0] // x
d = length(v,thisComp.width/2);
maxDist= 960;
ease(d,0,maxDist,100,0)
Time Remapping / Playback ✅
Random frame playback
// Source Dan Ebbert
fr = 12; // frame rate;
numFrames = 8;
seedRandom(index,true);
seg = Math.floor(time*fr);
f = Math.floor(random(numFrames));
for (i = 0; i < seg; i++)
f = (f + Math.floor(random(1,numFrames)))%numFrames;
framesToTime(f);
Random delayed/advanced layer playback
seedRandom(index,true);
myDelay = random(1,10);
time + myDelay;
Play one frame at a time (without 'float time')
fps = 1;
x = framesToTime(Math.round(time*fps))
//There probably is a better way but I cannot figured it out right now.
Random still frame (Good for spriting)
//Apply this to a composition with a image sequence inside
seedRandom(0,true);
t= random(0,72);
framesToTime(t);
// Copying animation of a layer, and start it at inPoint of layer
thisComp.layer(index+1).transform.position.valueAtTime(time-inPoint)
// Using delay
offset = 1;
thisComp.layer(index+1).transform.position.valueAtTime(time-offset)
This expression references the X position of the layer above in the Composition panel and adds a fixed increment, resulting in a row of evenly spaced child layers.
A series of duplicated layers with random position values