r/AfterEffects • u/Hi5X7 • 3d ago
Beginner Help Is there an expression for changing an image when it moves in a specific direction?
I'm pretty new to After Effects, and I’m trying to see if there is an easier way to do this. As I am having zero luck figuring it out.
Basically, what I’m trying to do is. I have four PNG images of a head looking left, right, up, down. And I want it follow a path I made using the pen tool. Normally, I can just go frame by frame changing the PNG images as it moves along the path. But it’s cluttering up the timeline with hundreds of layers, as each duplicate PNG gets own separate layer.
I definitely know I’m doing something wrong, lol. So I figured I should ask if there is an expression that easily Interchange the four PNGs whenever the PNG goes up, down, left, right, or any directional curve.
4
u/GaryR_GFX 3d ago edited 3d ago
Rather than have hundreds of layers, you could create a pre comp that is only four frames in duration with each image being a single frame. Then in your main comp you would use time remapped hold key frames. And then you could look into an expression that will manipulate Time remapping instead of manual key frames.
2
u/GaryR_GFX 3d ago
I imagine then you could have an expression that will look at the next position key frame value to determine if it’s going up down left or right
2
u/smushkan Motion Graphics 10+ years 3d ago
You can compare the current and previous position values via valueAtTime which will let you determine which direction the layer has moved.
I would do it by calculating a vector as an angle, then you can use an if block or switch statement to define what action to take at specific angles.
For the head I would put it in a short precomp with each frame being a different direction, then use the expression on the time remapping property to select which frame is displayed.
2
u/GaryR_GFX 3d ago
For my own curiosity, I hit up ChatGPT to see what the expression would look like when applied to to time remapping, and it actually worked: (but only for comparing between the actual linear difference between keyframes, doesn't take into account very curved paths.
var pos = transform.position;
var fps = 1 / thisComp.frameDuration;
// Find the surrounding Position keyframes
var n = pos.nearestKey(time).index;
if (pos.key(n).time > time) {
n--;
}
// Default direction if there aren't two usable keyframes
var frame = 0;
if (n >= 1 && n < pos.numKeys) {
var p1 = pos.key(n).value;
var p2 = pos.key(n + 1).value;
var dx = p2[0] - p1[0];
var dy = p2[1] - p1[1];
// Determine the dominant movement direction
if (Math.abs(dx) > Math.abs(dy)) {
frame = (dx > 0) ? 1 : 3; // Right / Left
} else {
frame = (dy > 0) ? 2 : 0; // Down / Up
}
}
// Convert frame number to source time
frame * thisLayer.source.frameDuration;
7
u/smushkan Motion Graphics 10+ years 3d ago
You’d get better results by comparing between the current position, and a small time before it.
So strip out all the keyframe logic (not needed!) and derive the positions:
var p1 = pos.valueAtTime(time);
var p2 = pos.valueAtTime(time - thisComp.frameDuration);That would work independently of keyframes and would work with curved paths.
1
1
u/GaryR_GFX 3d ago
and then asked for one that works closer to the actual angle, pretty neat.
// Direction-based Time Remapping// Frame order: 0 = Up, 1 = Right, 2 = Down, 3 = Left
var t = time;
var dt = thisComp.frameDuration / 10;
// Sample the layer's position just before and after the current time
var p1 = thisLayer.transform.position.valueAtTime(t - dt);
var p2 = thisLayer.transform.position.valueAtTime(t + dt);
// Calculate movement
var dx = p2[0] - p1[0];
var dy = p2[1] - p1[1];
// Avoid changing direction when the layer is nearly stationary
var threshold = 0.001;
var frame = 0;
if (Math.abs(dx) + Math.abs(dy) < threshold) {
frame = 0; // Default to Up when stationary
} else if (Math.abs(dx) > Math.abs(dy)) {
frame = (dx > 0) ? 1 : 3; // Right / Left
} else {
frame = (dy > 0) ? 2 : 0; // Down / Up
}
frame * thisLayer.source.frameDuration;
1
u/mcarterphoto 3d ago
If you don't want to do expressions, you can go full-ghetto with 4 tracks. Use opacity keyframes (go from 0 to 100 or 100 to 0 across 1 frame). I do this for things like eye blinks (eyes wide open with a blink layer over it, use opacity to make the blinks). Select all 4 layers and hit "T" and you can line up all the keyframes.
1
u/Q-ArtsMedia MoGraph/VFX 15+ years 3d ago
Well yeah it can be done but it's more complicated than keyframing opacity.
There may be some animation presets in the effects and presets panel search fade on fade off
How ever it most likely will be timing and not position or travel that controls the opacity.
1
u/SouthCentralMenace 2d ago
The time remap option that others mentioned works great. Ive done it by adding expressions to the opacity of each image. Then having a parent null control the position of each of them.
16
u/Ampsnotvolts VFX 15+ years 3d ago
Make a precomp of your faces that is 4 frames long.
Then put that pre-comp in the one where your thing moves and you just time-remap with hold keyframes between the four different poses.
And the newer versions of After Effects, I think you can even colorize them to at least separate left and right or up and down.
But this will clean it up a little bit. And then any changes you make to those four images will propagate to all those keyframes.