Skip to main content
Mr.Dubb
Participant
August 29, 2023
Answered

Need help with with code for expression animation

  • August 29, 2023
  • 3 replies
  • 446 views

Hey there so basically I want to create an expression creating a position delay referencing the layer above using valueattime. then i want the trailing objects animation to be half that of the leading object so they arrive at the same point at the same time. I've tried a bunch of methods but I cant seem to get it to work. any advice? heres my current expression just for the delay which works fine. just need to know how to cut the animation in half after the delay. so leading animation is 12 frames, after 6 frames i want the second object to start and its animation only be 6 frames long.

 

framedelay = 6
frame = thisComp.frameDuration;
thisComp.layer(index-1).transform.position.valueAtTime(time-frame*framedelay)+[0,500]

This topic has been closed for replies.
Correct answer Sarah Talbot

If you only need to use two keyframes to set the base animation, you can try using linear() to convert when your animation starts instead of valueAtTime(), like below:

 

var startKey = thisComp.layer("Shape Layer 1").transform.position.key(1); //access the first keyframe
var endKey = thisComp.layer("Shape Layer 1").transform.position.key(2); //acces the second keyframe
var animDuration= Math.abs(endKey.time-startKey.time); //give you the duration in seconds, positive values only
var delay = animDuration/2; //your delay is the halfway point of the animation

linear(time, startKey.time+delay,endKey.time,startKey.value, endKey.value); // as time reaches the halfway point of the animation and approaches the end, interpolate the value of the position at the start time to the end time

 

You can add other bits of code to control which keyframes you access or how to offset your position values in space, but this should give you a base!

3 replies

Sarah Talbot
Sarah TalbotCorrect answer
Participating Frequently
August 29, 2023

If you only need to use two keyframes to set the base animation, you can try using linear() to convert when your animation starts instead of valueAtTime(), like below:

 

var startKey = thisComp.layer("Shape Layer 1").transform.position.key(1); //access the first keyframe
var endKey = thisComp.layer("Shape Layer 1").transform.position.key(2); //acces the second keyframe
var animDuration= Math.abs(endKey.time-startKey.time); //give you the duration in seconds, positive values only
var delay = animDuration/2; //your delay is the halfway point of the animation

linear(time, startKey.time+delay,endKey.time,startKey.value, endKey.value); // as time reaches the halfway point of the animation and approaches the end, interpolate the value of the position at the start time to the end time

 

You can add other bits of code to control which keyframes you access or how to offset your position values in space, but this should give you a base!

Sarah Talbot
Participating Frequently
August 29, 2023

Hah Looks like Rick and I had similar answers! Interpolation methods for the win!

Mr.Dubb
Mr.DubbAuthor
Participant
August 29, 2023

yeah very similar methods. thank you to both of you!

Community Expert
August 29, 2023

If the first layer that moves is below the second layer, I would use this expression for position on the top layer:

ref = thisComp.layer(index + 1).position;

t = time;
t1 = ref.key(1).time + (ref.key(2).time - ref.key(1).time) / 2;
t2 = ref.key(2).time;
p1 = ref.valueAtTime(ref.key(1).time);
p2 = ref.valueAtTime(ref.key(2).time);
ease(t, t1, t2, p1, p2);

You could also use an ease or easeIn interpolation on the last line.

 

The expression looks at the animated layer, determines the time of the keyframes, creates a starting time (t1) that is halfway between the first and second keyframes, and then moves the second (top layer) from the first layer's original position to the original layer's second position. You could use this expression for any property just by changing the property in the first line from position to rotation or anything else you want to copy. 

 

 

Mr.Dubb
Mr.DubbAuthor
Participant
August 29, 2023

thank you so much! I was in the ballpark with my attempts but this is very clear to where my mistakes were. I wasnt properly defining my keyframes which then messed up me referencing their valueattime and those combined were returning errors on my linear command. I started to really get into the weeds with this one when i knew it couldnt be too complicated. still a bit green to java so this is a huge help. 

Mylenium
Legend
August 29, 2023

You will need to compress the time by multiplying it with a factor of 2 to make it faster. Simple as time*2. Howwever, such an expression would need a fixed trigger point like a keyframe or a time value, which your current setup doesn't have. then it could be as simple as

 

if (time > triggerPoint+frameDelay)

{timeMul=time*2}

else

{timeMul=time};

 

Mylenium