A falling leaf can be a pretty complicated simulation - sometimes they just
fall gently, sometimes they do barrel-rolls, sometimes glide back and forth, or
any combination. These expression roughly simulate the glide back and forth
variation. I tried this on a 3D solid positioned above the camera view,
oriented with Z pointing down and Y pointing in the positive Z direction
(orientation [90,0,0]).

Then I added these three expressions:

POSITION:

yVelocity = 200; //pixels per second
oscFreq = 1.5; //oscillations per second
oscDepth = 35; //oscillation depth (pixels)
drift = 25; // drift (wind?) (pixels per second: - = left, + = right)

value + [oscDepth*Math.sin(oscFreq*Math.PI*2*time) + drift *time,
yVelocity*time,0]

Z ROTATION:

seed_random(index,true);
random(360);

Y ROTATION:

oscFreq = 1.5;
maxTilt = 15; //degrees

maxTilt*Math.cos(oscFreq*Math.PI*2*time)

If you edit the parameters, you need to make sure that the oscillating
frequency is the same in both the position and y-rotation expressions (or map
it to a slider control). If you wanted to apply this to a bunch of leaves,
you'd want to introduce some randomness into the various parameters along with
a random starting phase.

Even though this post was 14 years ago it was still very useful to me and my current project, with one reservation: I can't see how to stop the falling leaf 's motion so it comes to rest on the floor I've created in AE. I'm not really very familiar with expressions but usually at the copy-and-paste stage right now. Could you give me an idea on how I might stop this animation at a precise frame so that the leaf does not continue through the floor but stops, producing a shadow. Thanks for the inspiration. I really must learn expressions!

I think that if you link all the variable’s numbers to slider controls you could be able to keyframe these numbers down to zero which would stop the object from moving.

You have to work out when the animation should end. The time it takes for the layer to hit the ground is the distance traveled / velocity, so you can use (start position - end position) / velocity.

let yVelocity = 200; //same as for position - you could use a slider to set it
let endTime = (transform.position.valueAtTime(inPoint)[1] - endYPos) / yVelocity; //the time when animation should stop
let oscFreq = 1.5;
let maxTilt = 15; //degrees
(time < endTime)?
maxTilt*Math.cos(oscFreq*Math.PI*2*time) :
maxTilt*Math.cos(oscFreq*Math.PI*2*endTime)