Skip to main content
brandonb96942845
Inspiring
September 12, 2022
Answered

Keyframes Question: Delay adjustment by a set number of frames?

  • September 12, 2022
  • 2 replies
  • 1616 views

Hi all, got a question--is there a way to do something like this?

 

Time: 0:00:00

Keyframe 1: 0:00:00

Position X: 100

Actual Position: 100



Time: 0:04:00

Keyframe 2: 0:04:00

Position X: 250

Actual Position: 100



Time: 0:05:00

Actual position: 250

 

Basically, I'm looking to be able to set a keyframe (assume that they're all more than 1-2 seconds apart), and when AfterEffects detects the next keyframe (I'm imagining all of them being set to Hold interpolation), it'll backtrack from the keyframe's time by a set number of frames--I'm thinking 30 to start with--to start actually adjusting the property, so that by the time of Keyframe #2, the everything is where the keyframe says it should be. (Preferably with an Ease interpolation.) Alternatively, I could also do it the other way, I set a keyframe and then it takes 1-2 seconds for the object to actually shift to match the new value.

 

(And yes, I know this is a lot easier to do with multiple keyframes, but there's a reason I'm specifically looking to do this in this manner.)

 

I'm no stranger to sliders so if it would take a property being parented to a slider so it can compare last keyframe to next keyframe, I can do that too.

This topic has been closed for replies.
Correct answer Dan Ebberts

Try this one:

easeFrames = 30;
val = value;
if (numKeys > 0){
  n = nearestKey(time).index;
  if (time < key(n).time) n--;
  if (n > 1){
    d = framesToTime(easeFrames);
    t1 = key(n).time;
    if (n < numKeys){
      d = Math.min(d,key(n+1).time - t1);
    }
    t2 = t1 + d;
    v1 = key(n-1).value;
    v2 = key(n).value;
    val = ease(time,t1,t2,v1,v2);
  }
}
val

2 replies

Dan Ebberts
Community Expert
September 12, 2022

I think that would be like this:

easeFrames = 30;
val = value;
if (numKeys > 0){
  n = nearestKey(time).index;
  if (time > key(n).time && n < numKeys) n++;
  if (n > 1){
    d = framesToTime(easeFrames);
    t2 = key(n).time;
    t1 =  Math.max(key(n-1).time, t2 - d)
    v1 = key(n-1).value;
    v2 = key(n).value;
    val = ease(time,t1,t2,v1,v2);
  }
}
val
brandonb96942845
Inspiring
September 17, 2022

I finally had time to try this tonight, it's working exactly as we'd talked about but it doesn't work quite as well as I'd thought. Is there a way to reverse the effect, so that the delayed implemention starts at the keyframe itself instead of ending at it?

Dan Ebberts
Community Expert
September 17, 2022

Thanks, Dan. I find the first expression incredibly useful and have saved it with some modifications as an animation preset. You can quickly add keyframes in the timeline, or even markers, then make adjustments to the keyframes while you are watching. It's another brilliant idea from Dan the Man...


So I guess to get the second version to work with linear keyframes, you'd just need to hold the value of the first keyframe until you get to the second keyframe:

easeFrames = 30;
val = value;
if (numKeys > 0){
  n = nearestKey(time).index;
  if (time < key(n).time) n--;
  if (n > 1){
    d = framesToTime(easeFrames);
    t1 = key(n).time;
    if (n < numKeys){
      d = Math.min(d,key(n+1).time - t1);
    }
    t2 = t1 + d;
    v1 = key(n-1).value;
    v2 = key(n).value;
    val = ease(time,t1,t2,v1,v2);
  }else{
    val = key(1).value;
  }
}
val

 

Mylenium
Brainiac
September 12, 2022

That's no different than the usual fake bounce/ inertia/ overshoot expressions as found here:

 

http://www.motionscript.com/articles/bounce-and-overshoot.html

 

You just have to play with the parameters. Of course it won't work too well with hold keyframes and you may have to change your approach on that. Otherwise of course all manner of expressions can be created with valueAtTime() to mimic such behaviors and/ or the ones provided by Dan Ebberts be modified to suit.

 

Mylenium

brandonb96942845
Inspiring
September 12, 2022

Mylenium, actually what I described is completely different than bounce/inertia/overshoot expressions. You've managed to miss the point of what I'm trying to do entirely. And if you'll kindly re-read my post in its entrety, you'll notice that I have a problem that's more or less only solvable with Hold keyframes. So, more or less per usual, your reply is of no help whatsoever.