Expressions


toCompVec([0, 0, 1])[2]

Hide 3D inverted layers. Applies to opacity.





https://www.motionbynick.com/freebies/expressions

slider = effect("Slider Control")("Slider"); //use angle control for > million
numDecimals = 2;
commas = false;
dollarSign = true;
percentSign = false;
s = slider.value.toFixed(numDecimals);
prefix = "";
suffix = "";
if (s[0] == "-"){
  prefix = "-";
  s = s.substr(1);
}
if(dollarSign) prefix += "$";
if(percentSign) suffix = "%";
if (commas){
  decimals = "";
  if (numDecimals > 0){
    decimals = s.substr(-(numDecimals + 1));
    s = s.substr(0,s.length - (numDecimals + 1));
  }
  outStr = s.substr(-s.length, (s.length-1)%3 +1);
  for (i = Math.floor((s.length-1)/3); i > 0; i--){
    outStr += "," + s.substr(-i*3,3);
  }
  prefix + outStr + decimals + suffix;
}else{
  prefix + s + suffix;
}





Ctrl + Shift + H pour montrer/cacher les flèches d'une forme 3D et les tracés.





s = [];
ps = parent.transform.scale.value;
for (i = 0; i < ps.length; i++){
s[i] = value[i]*100/ps[i];
}
s

Divert objects through scale property of a null object. 





value / length(toComp([0,0]), toComp([0.7071,0.7071])) || 0.001;

Keep stroke width when scaling. 




var delay = 2; 
parent.fromComp( toComp( anchorPoint, time - framesToTime( delay ) ) );

Rajouter du délai dans l'animation d'une propriété par rapport au parant.

delay = .5;
parent.fromWorld(toWorld(anchorPoint,time-delay))

This one works 





https://www.goodboy.ninja/expressionscheatsheet




path1 = mask("Mask 1").maskPath;
path2 =  mask("Mask 2").maskPath;
r = [];
s = [];
s1 = [];
for(x=0;x<=1;x=x+0.22){
    r1 = path1.pointOnPath(x);
    r.push(r1);
    s.push([(path1.pointOnPath(x+(0.22*0.25))[0]-r1[0])*-1,(path1.pointOnPath(x+(0.22*0.25))[1]-r1[1])*-1]);
    s1.push([(path1.pointOnPath(x+(0.22*0.25))[0]-r1[0]),(path1.pointOnPath(x+(0.22*0.25))[1]-r1[1])]);

    if(x+(0.22/2)<=1){
    r2 = path2.pointOnPath(x+(0.22/2));
    r.push(r2);
    s.push([(path2.pointOnPath(x+(0.22*0.25))[0]-r2[0]),(path2.pointOnPath(x+(0.22*0.25))[1]-r2[1])]);
    s1.push([(path2.pointOnPath(x+(0.22*0.25))[0]-r2[0])*-1,(path2.pointOnPath(x+(0.22*0.25))[1]-r2[1])*-1]);
    };
};
createPath(points = r, inTangents = s, outTangents = s1, isClosed = false);


Waveforme between paths. Paste on third path of masks on a solid layer.

path1 = mask("Mask 1").maskPath;
path2 =  mask("Mask 2").maskPath;
r = [];
s = [];
s1 = [];
slider = clamp(effect("Slider Control")("Slider"),0.1,1);

for(x=-1+(time/5)%(slider);x<=1;x=x+slider){

    if(x>=0){
    r1 = path1.pointOnPath(x);
    r.push(r1);
    s.push([(path1.pointOnPath(x+(slider*0.25))[0]-r1[0])*-1,(path1.pointOnPath(x+(slider*0.25))[1]-r1[1])*-1]);
    s1.push([(path1.pointOnPath(x+(slider*0.25))[0]-r1[0]),(path1.pointOnPath(x+(slider*0.25))[1]-r1[1])]);};

    if(x+(slider/2)<=1 && x+(slider/2)>=0){
    r2 = path2.pointOnPath(x+(slider/2));
    r.push(r2);
    s.push([(path2.pointOnPath(x+(slider*0.25))[0]-r2[0]),(path2.pointOnPath(x+(slider*0.25))[1]-r2[1])]);
    s1.push([(path2.pointOnPath(x+(slider*0.25))[0]-r2[0])*-1,(path2.pointOnPath(x+(slider*0.25))[1]-r2[1])*-1]);

    };
};
createPath(points = r, inTangents = s, outTangents = s1, isClosed = false);


Same thing with a time expression.




frequency = 2;
amplitude = 10;
w = wiggle(frequency, amplitude);
[value[0],w[1]]


Wiggle sur une dimension.



https://aescripts.com/learn/how-to-make-layers-react-to-a-mask-in-after-effects/
// Make Layers React to a Mask
// Based on knowledge from The Power of Expression Book
// https://aescripts.com/the-power-of-expression/
//
// Requires the new 'Javascript' expressions engine introduced in AE 16.0 (CC2019)
// You can set this in File -> Project Settings: https://drop.aescripts.com/NQurXWmG
// If you replace all "let" to "var" this expression will should work in previous versions
//
// v1 initial version
// v2 added feathering support
// v3 added parenting support

let maskToUse = thisComp.layer("MASK").mask("Mask 1").maskPath.points();
let positionLayer = thisLayer.toComp([transform.anchorPoint[0],transform.anchorPoint[1]]);

let inside = function(point, path) {
    let x = point[0],
        y = point[1];
        let result = 0;
    let inside = false;
    for (let i = 0, j = path.length - 1; i < path.length; j = i++) {
        let xi = path[i][0],
            yi = path[i][1];
        let xj = path[j][0],
            yj = path[j][1];
        let intersect = ((yi > y) != (yj > y)) &&
        (x <
            (xj - xi) * (y - yi) / (yj - yi) + xi);
        if (intersect) inside = !inside;

                let t1 = length(path[i],point);
                let t2 = length(path[result],point);
                if (t1 < t2){
                        result = i;}


    }
    return [inside,result];
};


let lengthToLine =  function(a, b, c) {
        let line = Math.pow(length(b,c),2);
        if (line === 0) return Math.pow(length(a,b),2);
        let d = ((a[0] - b[0]) * (c[0] - b[0]) + (a[1] - b[1]) * (c[1] - b[1])) / line;
        d = Math.max(0, Math.min(1, d));
        let distance =  Math.pow(length(a, [ b[0] + d * (c[0] - b[0]), b[1] + d * (c[1] - b[1]) ]),2);

        return Math.sqrt(distance);
};

let r = inside(positionLayer, maskToUse);
let final, distance1, distance2, result2;
if (r[0] == true) {
    thisProperty.key(2).value;
} else {
        let closest = r[1];
        let fallOff = thisComp.layer("MASK").mask("Mask 1").maskFeather[0];
        final = thisProperty.key(1).value;

        if (fallOff!=0){

if (closest==0){
        distance1 = lengthToLine (positionLayer, maskToUse[closest], maskToUse[maskToUse.length-1]);
        distance2 = lengthToLine (positionLayer, maskToUse[closest], maskToUse[closest+1]);
} else if ((closest+1)==maskToUse.length){
        distance1 = lengthToLine (positionLayer, maskToUse[closest], maskToUse[closest-1]);
        distance2 = lengthToLine (positionLayer, maskToUse[closest], maskToUse[0]);
} else {
        distance1 = lengthToLine (positionLayer, maskToUse[closest], maskToUse[closest-1]);
        distance2 = lengthToLine (positionLayer, maskToUse[closest], maskToUse[closest+1]);
};


if (distance1 < distance2){
        result2 = distance1;
}else{
        result2 = distance2;
};


        final = linear(result2,0,fallOff,thisProperty.key(2).value,thisProperty.key(1).value);
};

        final;

};






// Set the random seed based on layer name/index so it's fixed
seedRandom(index, true);

// Define composition size and margins
var compWidth = thisComp.width;
var compHeight = thisComp.height;
var margin = 400;

// Calculate max/min values within margins
var x = random(margin, compWidth - margin);
var y = random(margin, compHeight - margin);

// Return the final position
[x, y]

Placer de façon fixe des calques dans une composition avec une marge





var colors = [
    [244/255, 247/255, 242/255, 1], // #f4f7f2
    [229/255, 224/255, 214/255, 1], // #e5e0d6
    [197/255, 188/255, 173/255, 1], // #c5bcad
    [117/255, 113/255, 110/255, 1], // #75716e
    [249/255, 37/255, 22/255, 1],   // #f92516
    [15/255, 15/255, 15/255, 1],    // #0F0F0F
    [249/255, 249/255, 249/255, 1]  // #f9f9f9
];

seedRandom(index, true);
colors[Math.floor(random(colors.length))];

Couleur fixe aléatoire parmi une liste de couleurs





var pathLayer = thisComp.layer("PathLayer"); // Your mask path layer
var maskPath = pathLayer.mask("Mask 1").maskPath;
var total = pathLayer.index-1; // total number of layers
var t = (index - 1) / (total - 1); // position along the path (0–1)

// Sample the path at time = 0 to extract points
maskPath.pointOnPath(t, 0);

Sur la position pour répartir des calques sur un tracé référé dans un masque sur un calque tout en dessus de la pile de calques.





a = thisLayer.sourceRectAtTime();
height = a.height;
width = a.width;
top = a.top;
left = a.left;

x = left + width/2;
y = top + height/2;
[x,y];

Auto-placing anchor points expressions. Mostly for MOGRT files.

Play with the positional attributes "left" and "top" and the dimensional attributes "width" and "height".

Giga subtilité : le timecode source est très important pour l'outil "sourceRectAtTime". 




// Get the positions of objects A, B, and C
var posA = thisComp.layer("[SR2][SR3][SR4] Ctrlr 3").transform.position;
var posB = thisComp.layer("[SR1][SR3][SR4] Ctrlr 2").transform.position;
var posC = thisComp.layer("[SR1][SR2][SR3] Ctrlr 1").transform.position;

// Calculate the normal vector of the plane defined by A, B, and C
var normalVector = cross(posB - posA, posC - posA);
normalVector = normalize(normalVector);

// Calculate the rotation angles from the normal vector
var pitch = Math.atan2(normalVector[1], normalVector[2]) * (180 / Math.PI);
var yaw = Math.atan2(normalVector[0], normalVector[2]) * (180 / Math.PI);
var roll = Math.atan2(normalVector[0], normalVector[1]) * (180 / Math.PI);

// Apply the calculated rotation
[pitch, yaw, roll] + [90, 0, 0];

Faire s'orienter perpendiculairement un objet par raport au plan formé par 3 objets en 3D.






const numPoints = points().length;
let pts = [];
const delay = 1; //enter frame input here
for (let i = 0; i < numPoints; i++){
   const p = points(time-i*framesToTime(delay))[i];
   pts.push(p);
}
createPath(pts, [], [], false);


To delay animation by point index in a path.
If for bezier paths, change last line to :
createPath(pts, inTangents(), outTangents(), false)


https://x.com/textperimentor/status/1689453049880666113?s=20





https://x.com/DenisStefanides/status/1711765883054412188?s=20

Double CC Repetile to tile things like a text layer.
The first one to control spacing and tiling set to none. 
The second one with 1000 on each direction and tiling set to repeat.





var s = thisProperty,
start = s.key(1).value,
end = s.key(2).value,
t = (time - s.key(1).time) / (s.key(2).time - s.key(1).time);
t = Math.max(0, Math.min(1, t));
Array.isArray(start) ? start.map(function(v, i)
{ return Math.pow(end[i] / Math.max(v, .01), t) *
    Math.max(v, .01); }) :
Math.pow(end / Math.max(start, .01), t)
* Math.max(start, .01);


Linear to exponentiel expression




https://www.linkedin.com/posts/zac-miller-889564131_aftereffects-aftereffectstutorial-tutorial-activity-7149147972910428160-hq4W?utm_source=share&utm_medium=member_desktop

540 - ((index-1)*54)

t = thisComp.layer("Null Sections Wild Tile").effect("Dropdown Menu Control")("Menu");
if (t == index) 100;
    else 0;

[position.value[0],0,position.value[2]]

thisComp.layer(index+1).transform.xRotation + value

Seperate into sections and control bend. 





// Get the positions of the three 3D Nulls
pointA = thisComp.layer("Null 1").transform.position;
pointB = thisComp.layer("Null 2").transform.position;
pointC = thisComp.layer("Null 3").transform.position;

// Calculate the centroid of the triangle
centroid = (pointA + pointB + pointC) / 3;

// Assign the centroid position to the position property of the new Null
centroid;

Centrer en 3D un objet entre 3 Objets. Avec ChatGPT




try{
timeStart = thisProperty.key(1).time;
duration = thisProperty.key(thisProperty.numKeys).time-timeStart;
pingPong = false; //change to true value if you want to loop animation back & forth 
quant=Math.floor((time-timeStart)/duration);
  if(quant<0) quant = 0
  if(quant%2 == 1 && pingPong == true){   t = 2*timeStart+ (quant+1)*duration - time;
}
else{
  t = time-quant*duration;
}
}
catch(err){
  t = time;
}
thisProperty.valueAtTime(t)

loopOut function for paths. 



Nathan Massenet — 2025