Skip to content

Instantly share code, notes, and snippets.

@adrianseeley
Created February 1, 2023 11:18
Show Gist options
  • Save adrianseeley/e94568e2dfce3ee50b4b3008f3e6523c to your computer and use it in GitHub Desktop.
Save adrianseeley/e94568e2dfce3ee50b4b3008f3e6523c to your computer and use it in GitHub Desktop.
Updated Ease
/// <summary>
/// Use:
/// 1. Create a new instance of the ease class where steps are time, and values are
/// the value you want to ease over that time.
/// For example moving 100 pixels in 3 seconds:
///
/// Ease myEase = new Ease
/// (
/// currentStep: 0f,
/// totalSteps: 3f,
/// startValue: 500f,
/// valueChange: 100f
/// );
///
/// 2. At every update, call the step function to progress the ease forward without
/// overruning the end. The boolean value returned indicates if the ease is completed.
/// For example using the gameTime to progress the ease forward:
///
/// bool myEaseCompleted = myEase.Step
/// (
/// stepChange: (float)gameTime.ElapsedGameTime.TotalSeconds
/// );
///
/// 3. Once the step function has been called the eased value can then be interpolated
/// by calling any of the non-modifying interpolation functions such as Linear, SinIn, etc.
/// For example getting the ExponentialIn interpolation:
///
/// float currentValue = myEase.ExponentialIn();
///
/// 4. Once the currentValue has been reflected in the scene the completion boolean
/// can be used to clean up the ease or trigger further state changes.
///
/// Note:
///
/// Because the interpolation functions are non-modifying, any number may be called in a
/// single step without changing any internal values of the ease. This can be useful for
/// demoing multiple eases at once, for example:
///
/// myEase.Step(...);
/// float a = myEase.ExponentialIn();
/// float b = myEase.Linear();
/// float c = myEase.CircularOut();
/// myEase.Step(...);
/// etc.
///
/// </summary>
public class Ease
{
public float currentStep;
public float totalSteps;
public float startValue;
public float valueChange;
public Ease(float currentStep, float totalSteps, float startValue, float valueChange)
{
this.currentStep = currentStep;
this.totalSteps = totalSteps;
this.startValue = startValue;
this.valueChange = valueChange;
}
public bool Step(float stepChange)
{
currentStep += stepChange;
if (currentStep > totalSteps)
{
currentStep = totalSteps;
return true;
}
else
{
return false;
}
}
public float Linear()
{
return valueChange * (currentStep / totalSteps) + startValue;
}
public float SinIn()
{
return -valueChange * MathF.Cos(currentStep / totalSteps * (MathF.PI / 2)) + valueChange + startValue;
}
public float SinOut()
{
return valueChange * MathF.Sin(currentStep / totalSteps * (MathF.PI / 2)) + startValue;
}
public float SinInOut()
{
return -valueChange / 2 * (MathF.Cos(MathF.PI * currentStep / totalSteps) - 1) + startValue;
}
public float QuadraticIn()
{
return valueChange * (currentStep /= totalSteps) * currentStep + startValue;
}
public float QuadraticOut()
{
return -valueChange * (currentStep /= totalSteps) * (currentStep - 2) + startValue;
}
public float QuadraticInOut()
{
if ((currentStep /= totalSteps / 2) < 1)
{
return valueChange / 2 * currentStep * currentStep + startValue;
}
else
{
return -valueChange / 2 * ((--currentStep) * (currentStep - 2) - 1) + startValue;
}
}
public float CubicIn()
{
return valueChange * (currentStep /= totalSteps) * currentStep * currentStep + startValue;
}
public float CubicOut()
{
return valueChange * ((currentStep = currentStep / totalSteps - 1) * currentStep * currentStep + 1) + startValue;
}
public float CubicInOut()
{
if ((currentStep /= totalSteps / 2) < 1)
{
return valueChange / 2 * currentStep * currentStep * currentStep + startValue;
}
else
{
return valueChange / 2 * ((currentStep -= 2) * currentStep * currentStep + 2) + startValue;
}
}
public float QuarticIn()
{
return valueChange * (currentStep /= totalSteps) * currentStep * currentStep * currentStep + startValue;
}
public float QuarticOut()
{
return -valueChange * ((currentStep = currentStep / totalSteps - 1) * currentStep * currentStep * currentStep - 1) + startValue;
}
public float QuarticInOut()
{
if ((currentStep /= totalSteps / 2) < 1)
{
return valueChange / 2 * currentStep * currentStep * currentStep * currentStep + startValue;
}
else
{
return -valueChange / 2 * ((currentStep -= 2) * currentStep * currentStep * currentStep - 2) + startValue;
}
}
public float QuinticIn()
{
return valueChange * (currentStep /= totalSteps) * currentStep * currentStep * currentStep * currentStep + startValue;
}
public float QuinticOut()
{
return valueChange * ((currentStep = currentStep / totalSteps - 1) * currentStep * currentStep * currentStep * currentStep + 1) + startValue;
}
public float QuinticInOut()
{
if ((currentStep /= totalSteps / 2) < 1)
{
return valueChange / 2 * currentStep * currentStep * currentStep * currentStep * currentStep + startValue;
}
else
{
return valueChange / 2 * ((currentStep -= 2) * currentStep * currentStep * currentStep * currentStep + 2) + startValue;
}
}
public float ExponentialIn()
{
if (currentStep == 0)
{
return startValue;
}
else
{
return valueChange * MathF.Pow(2, 10 * (currentStep / totalSteps - 1)) + startValue;
}
}
public float ExponentialOut()
{
if (currentStep == totalSteps)
{
return startValue + valueChange;
}
else
{
return valueChange * (-MathF.Pow(2, -10 * currentStep / totalSteps) + 1) + startValue;
}
}
public float ExponentialInOut()
{
if (currentStep == 0)
{
return startValue;
}
else if (currentStep == totalSteps)
{
return startValue + valueChange;
}
else if ((currentStep /= totalSteps / 2) < 1)
{
return valueChange / 2 * MathF.Pow(2, 10 * (currentStep - 1)) + startValue;
}
else
{
return valueChange / 2 * (-MathF.Pow(2, -10 * --currentStep) + 2) + startValue;
}
}
public float CircularIn()
{
return -valueChange * (MathF.Sqrt(1 - (currentStep /= totalSteps) * currentStep) - 1) + startValue;
}
public float CircularOut()
{
return valueChange * MathF.Sqrt(1 - (currentStep = currentStep / totalSteps - 1) * currentStep) + startValue;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment