I have got solution of this problem

Is it possible to control last keyframe value with this slider control with keeping keyframe interpolation / Easy Ease In

There are a few ways to do this.
What about the first keyframe? Will that stay the same or shall the value be changed as well?

1 Like

First keyframe value will be same, just need to change the last keyframe value

If you don’t add more keyframes, this expression should be enough.

c = thisComp.layer("CONTROLS").effect("Slider Control 2")(1);

if (key(1) > key(2)) {
	val1 = c;
	val2 = key(1);
} else {
	val1 = key(1);
	val2 = c;
	key(1), key(2),
	val1, val2

Thanks brother it’s working perfectly

1 Like

Why exactly do you check for key(1)>key(2) and then switch the order? c should always be val2 and key(1) always val1 as I understand it.

If the current keyframe animation goes from 1 to 0 and the OP wants it to go from 1 to 0.5 this will not work, as it will go from 0.5 to 1 instead.

It does work in this case as obviously the first keyframe is lower than the second keyframe value but if you remove the if/else and only leave the else part this is doing more what was requested, imho.

Try it :wink:
I made this switch exactly because of this problem. Without if/else expression will not work. Just try. )

My expression will not work only in such situations:

In all other situation it will work fine:
image image image

UPD: linear() function don’t know which direction it should go, if you don’t use time. So I must switch values to help function understand the basic vector of the movement.

1 Like

You are right, but it is odd… a linear interpretation changing “1 to 0” to “0 to 1” should actually make out of every 1 a 0 and out of every 0 a 1, don’t you agree?

I have another solution to the OP’s request, this is how I did these things in the past. This will work with any graph, even overshooting ones where the linear function seems to fail. The question is already answered by you but I thought I’d give my solution for… science :smiley:

For this, we need to set the keyframe animation to go from 0 to 1. We will change it back to what we need with expressions:

startValue = 42; //any number you need, you can also link this to a slider control
endValue = thisComp.layer("CONTROLS").effect("Slider Control 2")(1);
delta = endValue - startValue;

1 Like

Ha! Nice solution and so obvious :grinning:
I think I work with linear() because in all my previews situations, first I did animation (with more than 2 keyframes) and only after that create expressions. And never think that I can change values of my keyframes to 0 and 1. :grin:

Yes, linear() may looks odd when you don’t use time, because time go only forward or backward. And you always know when you go for example from 0 to 10, or from 10 to 0. So you manually switch 0 and 10 without even thinking about it.
For example if you need to rise something from 3 to 60 and your time go forward, what you do? linear(time, 0, 10, 3, 60). But what if time goes backward? linear(time, 10, 0, 3, 60) - This is works right? So I did the switch.
But what if I don’t know, time will go forward or backward? I need to check 10 > 0 or not.
So in my expression above I know normalize vector from keyframe index. key(1) goes before key(2). But linear() function don’t operate with keyframe indexes, in my case it only “see” values. So when key(1).value become larger than key(2).value, I need to switch values or my animation will go backward.
Hope my explanation helps to understand the logic. :grinning:

Anyway I modified your solution, and now you don’t need to change keyframe values. It just works in any case, except when key(1).value == key(2).value.

// put any slider controls on startValue and endValue
// or type "key(1)" or "key(2)" to use keyframe values
startValue = key(1);
endValue = thisComp.layer("CONTROLS").effect("Slider Control 2")(1);

delta = endValue - startValue;
valNorm = (value - key(1)) / (key(2) - key(1));
valNorm * delta + startValue;
1 Like

I’m still trying to wrap my head around your explanation but I guess the outcome will be: Yeah I understand the limitations of linear() but it would be more logical if it would operate otherwise. In the end, it could take any given range of numbers and convert any single number inside this range (or even outside, if we want to) to the equivalent number of another range of numbers in a linear fashion.
So for example, if I say change 0-10 to 0-20 then the simple conversion is x2. It could do that with any number, even if the range is going from 10 to 0 instead of 0-10.

It shouldn’t care about if “time goes forward or backwards” (using your analogy) as it should just take any given value at any given time and if that falls in the range convert it to the equivalent number of the new range.

This limitation you describe can be understood but the function would be much more logical if it would work this way.

Nice addition you made to my code. I work with 0 to 1 keyframes because it is easier to understand when setting it up the first time. To get rid of your exception, you can add a check for (key(2)-key(1)!=0) so that you won’t divide by 0.

// put any slider controls on startValue and endValue
// or type "key(1)" or "key(2)" to use keyframe values
startValue = key(1);
endValue = thisComp.layer("CONTROLS").effect("Slider Control 2")(1);

delta = endValue - startValue;
valNorm = (value - key(1)) / (key(2) - key(1));
valNorm * delta + startValue;

I think we are overengineering this :smiley: I miss the old Expression Thread, some cool questions and solutions were there.

Yep, I think about this check, but it also will not work in this case:
You will get a line instead of curve.
To make it perfect and work with any number of keyframes in any situation we need… Ok, I stop this, because it would be definitely overmuch. :smiley: Miss Expression Thread, too. :disappointed:

About linear(). We have key(1) and it’s value is constant. So when key(2) is bigger, linear() function increase numbers. When key(2) is smaller, linear() function decrease numbers. We have two directions: up and down (or forward and backward). Everything is okay when both control slider and key(2) values are bigger (or smaller) than key(1). The direction of movement stays the same. But what happens when control slider is smaller, and key(2) is bigger. linear() function “see” UP direction (because key(2) bigger than key(1)), but we need to go DOWN (because control slider value is smaller than key(1))… And what linear() function do. It can’t swap values, so it swap time, in key(1) you have control slider value, in key(2) you have key(1) value. The direction for linear() function stay the same, it goes UP, because control slider value is lower than key(1) value.

Example with numbers.

key(1) = 0;
key(2) = 10;
slider = -10;
linear(value, 0, 10, 0, 10); //goes up, last number 10 is from key(2)
linear(value, 0, 10, 0, -10);
//but if we change 10 to -10 (because slider value is -10), it goes down

There is no time variable to define what should go the first and what will be the next. And we need that time variable, because key(1) value is constant and should go the first. So to fix that, I just swap values.

Change the post 6 times, to make it more understandable. :sweat_smile:

Thanks, you spend your time to make me understand why the linear function does this, but with “this” I mean a flaw in the function and not the correct expected behaviour of what the function actually should do.

In a perfect world linear() would work as I described in my last post. Obviously there are flaws in the function’s code that lead to the behaviour you talk about but it is still a flaw and not the wanted outcome, in my opinion.

time, upvector etc should be totally irrelevant to the function. I’m not sure if you are guessing here or if you do really know the code inside the linear function, but whatever the code is, it messes up where we set a range that goes down instead of up. If it was smart, it would check for the direction of the range itself and act accordingly.

linear(x, 10, 0, 10, 0) should not change anything. By its own syntax, this means "Convert range “10 to 0” to “10 to 0” in a linear way and this means essentially: do nothing.
A human would get this correct. The linear() function converts “10 to 0” to “0 to 10” here and that is in my eyes a simple bug. It messes up if the second value is bigger than the third and this could be easily fixed.

If I know it, okay, I know now that it has to say linear(x, 0, 10, 0, 10) but in a perfect world either one would work :slight_smile:

linear(x, a, b, a, b) != linear(x, b, a, b, a) and this should not be the case.

Thank you for taking the time to explain the behaviour Dog, I really appreciate it. But I hope we can agree that this behaviour is a flaw rather than a wanted behaviour?

You forget one thing. In AE we always have time. So in your example linear(x,0,10,0,10) will go UP if “x” rises over time. If “x” goes down, linear() also goes down. X is variable that we can’t predict. So just imagine that “x” goes up over time, and we have linear(x, 0,10,0,10). The line goes UP. Because first “x” will be 0, then 1, etc. But what if we change expression like this linear(x, 0, -10, 0, 10)… The line also will go UP. Because we don’t change “x”, x goes up. And in this case it will go -10, -9, -8 over time.
The problem here is that without “time” variable it’s hard to image how linear() will work in timeline.

The problem exists indepent of what is happening with x. The problem occurs when the third argument is lower than the second argument.

If the range we give linear as the base range is not going up, it messes up.

I can add this expressions to any value set to 0, not animated at all, and it will change the value to 10:

linear(value, 10, 0, 10, 0)

the same happens with time:

linear(time, 10, 0, 10, 0) does give a result of 10 at the time of 0, and a result of 0 at the time of 10 instead of a result of 10 at the time of 10, and a result of 0 at the time of 0.

this function: linear(x, 10, 0, 10, 0) is the same as linear(x, 0, 10, 10, 0) and x can be time, value, or anything else.

The flaw does exist with any value no matter if it can go up, down, in circles or stays the same forever. It happens if the range we set as base is going down. If this is known it can be easily circumvented and you correctly did reverse your second range to fix this. However, it is not what I would assume the correct behaviour of linear()…

Now I don’t understand anything. :joy: Yes, there is something odd in it. linear() always try to go from smaller to bigger number, no matter of variable position. linear(x,10,0,0,10) is same as linear(x,0,10,0,10). That is not what I expected. :sweat_smile:

Interesting, while we talk about AE expressions this topic moved from videohive category to themeforest :grinning:

Yes I think some people are annoyed by our highly intelligent scientific conversation :smiley:

1 Like

:rofl: Nerds!

1 Like