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 pmI 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 pmWill there only ever be two keyframes? If not, what happens after the second one?
Dan
-
Mike Olson
February 9, 2009 at 10:49 pmThanks 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 amHey Mike,
Personally I like using the smooth- function a lot. It does a sort of ease ‘around’ your keyframes.
something likesmooth(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 pmThis 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!
Reply to this Discussion! Login or Sign Up