• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Modifying linear interpolation methods for different curves.

Community Expert ,
Oct 02, 2022 Oct 02, 2022

Copy link to clipboard

Copied

I have successfully modified an expression to give me an exponential increase in speed based on a layer's in-point. I'm having problems with an exponential decrease in speed. I guess what I am trying to do is modify the ease-out curve.

 

Here's what I have so far:

 

 

 

st = 1/thisComp.frameDuration;
movD = 20; // end position in % of comp width
mov = st; // move timing in frames
L = sourceRectAtTime();
LLeft = L.left;
LWidth = L.width;
t = time - inPoint;
tMin = 0;
tMax = tMin + mov * thisComp.frameDuration;
value1 = 0 - LWidth - LLeft;
value2 = thisComp.width * movD * .01;
x = linear(Math.exp(-t*10), tMin, tMax, value2 - LLeft, value1);
y = value[1];
[x, y]

 

 

 

 Math.exp(-t*10) will give me about a half-second duration for the animation. If I set the "move" variable to 1/frame duration, the move will start at the layers in-point. What I want to do is be able to set the "mov" value to the number of frames it will take to bring the layer to a stop. I can get close by changing the "t" multiplier. Smaller numbers increase the time. 

 

The expression I have come up with works, but I haven't figured out to define the ending point of the animation and control the curve. 

 

Any suggestions would be appreciated. 

RickGerard_0-1664741119339.gif

I'd like to give a shout-out to Dan Ebberts. If anyone has a solution at the top of their head, it is Dan.

 

 

TOPICS
Expressions , How to , Scripting

Views

493

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Oct 03, 2022 Oct 03, 2022

OK, so what I've got here is a kind of Frankenstein mash-up of your setup a something I had squirreled away. It has functions for accelerate (pow_in) and decelerate (pow_out), but the example is setup to use just decelerate. I'm only using 2 sliders--one to define the move frames and one to set the extremeness of the exponential curve. I hope you find it helpful. I recommend setting the Power slider up so it only has a range of 1-10.

// slider range 1 to 10 (1 = linear, 10 slightly more extreme 
...

Votes

Translate

Translate
Community Expert ,
Oct 02, 2022 Oct 02, 2022

Copy link to clipboard

Copied

I should mention that I figured out how to do what I want to do using keyframes. Just can't figure out how to do it based on layer-in-point and time.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 02, 2022 Oct 02, 2022

Copy link to clipboard

Copied

I suspect I might be able to help you get there, but I'm having trouble deciphering exactly what you're trying to do and how you're approaching it. Maybe you could back up a little and focus more on the requirements/objective rather than what you've done so far.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 02, 2022 Oct 02, 2022

Copy link to clipboard

Copied

I am trying to create an Animation Preset that allows me to move a layer into the frame based on the layers in point then move it out based on the layers out-point. I have created about a dozen of these, all of them have a slider to select the number of frames for the move, and all use the layer's in point plus a specified number of frames to move the layer into position. They all use the ease, ease in, or ease out interpolation method. Some of them have a bounce or overshoot added. Some work with 3D layers utilizing the camera's angle of view to move a layer into position and then fly it out based on the out point. For most of the presets, all I do is place the layer where I want it to end up and apply the preset. The layer then flys in to the frame, rests in it's hero position, and then flys out. The problem is that they all rely on the standard interpolation methods, and there is no adjustment for the speed. To give the animations a more professional and polished look I am tring to gain control of the acceleration and deceleration curves.

 

I worked out the acceleration of the problem. I use t = Math.pow(t, speedSlider) for that one. The timing is completely controllable but I can change the curve from linear to exponential acceleration easily. Control over acceleration is working just fine.

 

The expression I posted gives me different shaped speed graphs for deceleration, but I cannot control when the move starts or ends. If I try and change the curve I change the start and end point of the move. The only time the start of the move corresponds to the in-point of the layer is when the Move In Frames matches the comp's frame rate 

 

I want to maintain the timing but have the same kind of control over the deceleration curve that I have for the acceleration curve. I can then add an if/else argument to the expression to switch from an acceleration curve to a deceleration curve without changing the timing or fouling up the start point. 

RickGerard_0-1664779076873.gif

I hope this helps you help me figure out a solution. I can achieve this kind of control if I have two keyframes, but I don't want to do that when I have hundreds of layers to animate.

 

I included a project file if that helps.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Oct 03, 2022 Oct 03, 2022

Copy link to clipboard

Copied

Wouldn't you rather use Math.log(duration,1)? Seems like you want to figure out the base rather than the exponent.

 

Mylenium

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 03, 2022 Oct 03, 2022

Copy link to clipboard

Copied

I posted the wrong project. Here's the right one and the latest and closest version of the expression:

movD = effect("Move Distance")("Slider"); // end position in % of comp width
mov = effect("Move In Frames")("Slider"); // move timing in frames
curve = effect("Curve")("Slider");
L = sourceRectAtTime();
LLeft = L.left;
LWidth = L.width;
t = time - inPoint;
tMin = 0;
tMax = tMin + mov * thisComp.frameDuration;
value1 = 0 - LWidth - LLeft;
value2 = thisComp.width * movD * .01;
x = linear(Math.exp(-t * curve ), tMin, tMax, value2 - LLeft, value1);y = value[1];
[x, y]

Note the time change with the curve change. I'm trying to avoid that.

RickGerard_0-1664782202747.png

 

RickGerard_1-1664782213868.png

Mylenium, I'll give your suggestion a try.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 03, 2022 Oct 03, 2022

Copy link to clipboard

Copied

OK, so what I've got here is a kind of Frankenstein mash-up of your setup a something I had squirreled away. It has functions for accelerate (pow_in) and decelerate (pow_out), but the example is setup to use just decelerate. I'm only using 2 sliders--one to define the move frames and one to set the extremeness of the exponential curve. I hope you find it helpful. I recommend setting the Power slider up so it only has a range of 1-10.

// slider range 1 to 10 (1 = linear, 10 slightly more extreme than exponential)

function pow_in(curT,t1,t2,v1,v2,n){
  if(curT <= t1)return v1;
  if(curT >= t2)return v2;
  dt = t2 - t1;
  dv = v2 - v1;
  t = (curT-t1)/dt;
  return v1 + dv*Math.pow(t,n);
}

function pow_out(curT,t1,t2,v1,v2,n){
  if(curT <= t1)return v1;
  if(curT >= t2)return v2;
  dt = t2 - t1;
  dv = v2 - v1;
  t = (curT-t1)/dt;
  return v1 + dv*(1-Math.pow(1-t,n));
}

s = effect("Power")("Slider").value;
mov = effect("Move In Frames")("Slider");

if (time < (inPoint + outPoint)/2){
  val1 = [-width/2,value[1]];
  val2 = [thisComp.width/2,value[1]];
  time1 = inPoint;
  time2 = inPoint + framesToTime(mov);
}else{
  val1 = [thisComp.width/2,value[1]];
  val2 = [thisComp.width + width/2,value[1]];
  time1 = outPoint - framesToTime(mov);
  time2 = outPoint;
}
pow_out(time,time1,time2,val1,val2,s);

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 03, 2022 Oct 03, 2022

Copy link to clipboard

Copied

One other thing, I set this up on a 100x100 solid, so all the positioning stuff would be different for a Shape layer.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 04, 2022 Oct 04, 2022

Copy link to clipboard

Copied

LATEST

Thanks, Dan Ebberts, you got me going in the right direction. A few tweaks and a couple more siders and I've got it.  I'll share the present when it's done. This will save me a lot of time on an upcoming project. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines