I've seen this done in many programs. For example in the 3D world you can create a branch out of a single leaf, and a tree out of a single branch, automatically, by randomizing position and start of animation.

Can After Effects do anything like that? I have a simple animation I want to repeat hundreds of times, like tiles, and in a pseudo random pattern, sort of like noise. Naturally, since it's hundreds of copies of the same animation, I want to avoid placing them manually one by one, for obvious reasons!


If the animation is going to be relatively small in size on screen, but repeated a lot, I would look at using a Particle engine to repeat the pattern. You could use the built in ones in After Effects, or something like Red Giant’s Trapcode Particular or Form. It is possible to randomise the position of the repeats, and also to randomise the time within each animation as it repeats.

Example of using a leaf to create many leaves using Trapcode Particular:


To randomise the position apply an expression to the position property using the random() function. This takes two parameters, the minimum and the maximum, and returns a random number between the two. Normally it returns a different number every time the frame gets rendered, which is not what we want, so we need to 'seed' it with a value and set it to timeless with the seedRandom() function. We also need to return a two dimensional result because we need an x and y coordinate.

Putting that together:

seedRandom(index, timeless = true);
[random(12, 34), random(45, 67)]

Where 12, 34, 45, 67 are the values for the left, right, top and bottom minimum and maximums. Hard coding them is annoying if you want to be able to change the values later, so we'll set up a better system.

Add a null to the comp and apply the slider effect to it (effects>expression controls>slider) name the slider "left", then duplicate to make 3 more, called right, bottom and top. Make sure they're all visible in your timeline.

Now, in your layer's position expression, at the start type

let left = 

Then grab the expression pick-whip and drag it to the left slider. It will auto-fill something like

let left = thisComp.layer("null 1").effect("left")("slider")

I'm on my phone so I can't remember if this is exactly right, but as long as you select the slider with your pick whip you're golden. Add a semicolon at the end of the line because that's how we roll in JavaScript.

Now repeat, changing left to right, bottom, and top, and pick-whipping the appropriate slider each time. The word left here and the words right, bottom, top are variables (we could have called them anything, like fee, fie, foe, fum, but you want your code to be readable). We'll use those variables instead of the hard coded values.

One last detail. Random is good, but it returns a random number that is evenly distributed between the minimum and maximum, you probably want something that clusters toward the middle, so that the leaves are denser near the branch. The gaussRandom() function does that, so swap it for random.

Now we have:

 let left = thisComp.layer("null 1").effect("left")("slider");
 let right = thisComp.layer("null 1").effect("right")("slider");             
 let top = thisComp.layer("null 1").effect("top")("slider");
 let bottom = thisComp.layer("null 1").effect("bottom")("slider");
seedRandom(index, timeless = true);
[gaussRandom(left, right), gaussRandom(top, bottom)];

Copy this expression to all your leaf layers and you'll have a cloud of leaves the size and position of which is controlled by your sliders. It's a DIY particle system.

To make the animation offset, apply the time remap effect to the layer, then use another expression. In this we generate a timeless random number between 0 and the length of the layer, and add that to the time remap value. To loop it back to the beginning at the end, we use the modulus operator ٪, which returns the remainder of the first number divided by the second. Apply this to the time remap property:

seedRandom(index, timeless = true);
let myDuration = thisLayer.outPoint - thisLayer.inPoint;
(value + random(myDuration)) % myDuration;

In the seedRandom() function you'll notice we're using index as the first parameter. index is the index of the layer, so for each different layer it returns a unique 'seed' for the random() function, like spinning the roulette wheel each time. Also note that if you only give random() one parameter it assumes that you want random numbers in the range 0 to that number.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.