Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity › Forums › Adobe After Effects Expressions › Ease In (Out) based on velocity between 2 keyframes…

  • Ease In (Out) based on velocity between 2 keyframes…

    Posted by Mike Olson on February 9, 2009 at 6:35 pm

    I need help with an expression that would allow an object to slow to a stop AFTER a keyframe.

    Let me explain: If I change the position of a layer (or object) using 2 keyframes, I want the layer (or object) to float (keep moving in the same direction) to a stop based on the velocity it was moving between the 2 keyframes.

    Does anyone know if this can be done?

    Thanks in advance.

    Mike Olson replied 17 years, 7 months ago 3 Members · 4 Replies
  • 4 Replies
  • Dan Ebberts

    February 9, 2009 at 10:37 pm

    Will there only ever be two keyframes? If not, what happens after the second one?

    Dan

  • Mike Olson

    February 9, 2009 at 10:49 pm

    Thanks for the reply Dan,

    Right now I only want to use two keyframes to bring my layer/object into position. Once the timeline hits the second keyframe, I want the layer/object to continue drifting to a stop.

    Using a third keyframe and Easing IN to the third keyframe just doesn’t “look right”. Yes, I could play with the animation (F) curves. But, I have a lot of things to move this way and having to mess with the F-curves for each object (they will all move different amounts and speeds) will be a real pain.

    Mike

  • Filip Vandueren

    February 10, 2009 at 6:14 am

    Hey Mike,

    Personally I like using the smooth- function a lot. It does a sort of ease ‘around’ your keyframes.
    something like smooth(width=0.2,samples=25);

    pros: – The timing is different and more natural than a normal ease.
    – You know the exact values at which the smooth will start and end (the keyframed values) and it will get there “width/2 seconds” later.

    cons: – it does it for every keyframe, not just the last one.
    – it ‘cuts corners’ on intermediate values: because of the rounding, you will not go exactly through each point.

    Back to what you were asking for:
    this expression should do the trick.


    decayTime=0.2;

    if (numKeys && decayTime>0) {
    last_key_time=key(numKeys).time;
    if (time>last_key_time) {
    t=Math.min(time-last_key_time , decayTime);

    overshoot= (t - t*t/(decayTime*2))*velocityAtTime(last_key_time-0.001);

    value + overshoot;
    } else {
    value;
    }
    } else {
    value;
    }

    The objects will ‘overshoot’ their last keyframe. They will continue slowing down for ‘decayTime’ seconds untill they stop.
    If you look at the f-curves with Speed Graph and the expression f-curves enabled, you’ll see what’s happening.

    warning: by design you have no idea where the layer will settle, it will be beyond your keyframe.

    It’s based on the velocity (speed + direction) the layer was moving at a millisecond before the last keyframe. If you use the velocity exactly at the last keyframe, you get strange behaviours when the point has a very small bezier-handle.

    This will also work on 1d properties like rotation or 3d position

  • Mike Olson

    February 10, 2009 at 7:49 pm

    This is great Filip! Thank you so much. You are a living deity.

    However, now that I see it in action, I believe having my object move at half the speed(velocity) it was traveling between the two keyframes is closer to what I’m thinking of (very fast between the 2 frames, then overshooting the last keyframe at half or a third of the speed it was traveling, coming to a slow stop). I can get close to this idea by dividing the “overshoot” by 2:

    overshoot= (t – t*t/(decayTime*2))*velocityAtTime(last_key_time-0.001)/2;

    Unless you have a better way of achieving this?

    Thanks again!

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy