Skip to content

Instantly share code, notes, and snippets.

@lucasteles
Created May 17, 2026 19:05
Show Gist options
  • Select an option

  • Save lucasteles/8928b5ce9ff9f0228cdd9f59b0693e13 to your computer and use it in GitHub Desktop.

Select an option

Save lucasteles/8928b5ce9ff9f0228cdd9f59b0693e13 to your computer and use it in GitHub Desktop.
Easing Funcs
public static class Easing
{
public static Fix Apply(EasingFn fn, Fix k, Fix value) => Calc(fn, k.ToFloat()) * value;
public static float Apply(EasingFn fn, float k, float value) => Calc(fn, k) * value;
public static float Calc(EasingFn fn, float k) => fn switch
{
EasingFn.Linear => Linear(k),
EasingFn.Backward => Backward(k),
EasingFn.QuadraticIn => Quadratic.In(k),
EasingFn.QuadraticOut => Quadratic.Out(k),
EasingFn.QuadraticInOut => Quadratic.InOut(k),
EasingFn.CubicIn => Cubic.In(k),
EasingFn.CubicOut => Cubic.Out(k),
EasingFn.CubicInOut => Cubic.InOut(k),
EasingFn.QuarticIn => Quartic.In(k),
EasingFn.QuarticOut => Quartic.Out(k),
EasingFn.QuarticInOut => Quartic.InOut(k),
EasingFn.QuinticIn => Quintic.In(k),
EasingFn.QuinticOut => Quintic.Out(k),
EasingFn.QuinticInOut => Quintic.InOut(k),
EasingFn.SinusoidalIn => Sinusoidal.In(k),
EasingFn.SinusoidalOut => Sinusoidal.Out(k),
EasingFn.SinusoidalInOut => Sinusoidal.InOut(k),
EasingFn.ExponentialIn => Exponential.In(k),
EasingFn.ExponentialOut => Exponential.Out(k),
EasingFn.ExponentialInOut => Exponential.InOut(k),
EasingFn.CircularIn => Circular.In(k),
EasingFn.CircularOut => Circular.Out(k),
EasingFn.CircularInOut => Circular.InOut(k),
EasingFn.ElasticIn => Elastic.In(k),
EasingFn.ElasticOut => Elastic.Out(k),
EasingFn.ElasticInOut => Elastic.InOut(k),
EasingFn.BackIn => Back.In(k),
EasingFn.BackOut => Back.Out(k),
EasingFn.BackInOut => Back.InOut(k),
EasingFn.BounceIn => Bounce.In(k),
EasingFn.BounceOut => Bounce.Out(k),
EasingFn.BounceInOut => Bounce.InOut(k),
EasingFn.Constant => Constant(k),
_ => k,
};
#pragma warning disable S1121
public static float Linear(float k) => k;
public static float Backward(float k) => 1f - k;
public static float Constant(float _) => 1f;
public static class Quadratic
{
public static float In(float k) => k * k;
public static float Out(float k) => k * (2f - k);
public static float InOut(float k) =>
(k *= 2f) < 1f
? 0.5f * k * k
: -0.5f * (((k -= 1f) * (k - 2f)) - 1f);
}
public static class Cubic
{
public static float In(float k) => k * k * k;
public static float Out(float k) => 1f + ((k -= 1f) * k * k);
public static float InOut(float k) =>
(k *= 2f) < 1f
? 0.5f * k * k * k
: 0.5f * (((k -= 2f) * k * k) + 2f);
}
public static class Quartic
{
public static float In(float k) => k * k * k * k;
public static float Out(float k) => 1f - ((k -= 1f) * k * k * k);
public static float InOut(float k) =>
(k *= 2f) < 1f
? 0.5f * k * k * k * k
: -0.5f * (((k -= 2f) * k * k * k) - 2f);
}
public static class Quintic
{
public static float In(float k) => k * k * k * k * k;
public static float Out(float k) => 1f + ((k -= 1f) * k * k * k * k);
public static float InOut(float k) =>
(k *= 2f) < 1f
? 0.5f * k * k * k * k * k
: 0.5f * (((k -= 2f) * k * k * k * k) + 2f);
}
public static class Sinusoidal
{
public static float In(float k) => 1f - MathF.Cos(k * MathF.PI / 2f);
public static float Out(float k) => MathF.Sin(k * MathF.PI / 2f);
public static float InOut(float k) => 0.5f * (1f - MathF.Cos(MathF.PI * k));
}
public static class Exponential
{
public static float In(float k) => k is 0f ? 0f : MathF.Pow(1024f, k - 1f);
public static float Out(float k) => k is 1f ? 1f : 1f - MathF.Pow(2f, -10f * k);
public static float InOut(float k)
{
if (k is 0f or 1f)
return k;
if ((k *= 2f) < 1f)
return 0.5f * MathF.Pow(1024f, k - 1f);
return 0.5f * (-MathF.Pow(2f, -10f * (k - 1f)) + 2f);
}
}
public static class Circular
{
public static float In(float k) => 1f - MathF.Sqrt(1f - (k * k));
public static float Out(float k) => MathF.Sqrt(1f - ((k -= 1f) * k));
public static float InOut(float k) =>
(k *= 2f) < 1f
? -0.5f * (MathF.Sqrt(1f - (k * k)) - 1)
: 0.5f * (MathF.Sqrt(1f - ((k -= 2f) * k)) + 1f);
}
public static class Elastic
{
public static float In(float k) =>
k is 0f or 1f
? k
: -MathF.Pow(2f, 10f * (k -= 1f)) * MathF.Sin((k - 0.1f) * (2f * MathF.PI) / 0.4f);
public static float Out(float k) =>
k is 0f or 1f
? k
: (MathF.Pow(2f, -10f * k) * MathF.Sin((k - 0.1f) * (2f * MathF.PI) / 0.4f)) + 1f;
public static float InOut(float k) =>
(k *= 2f) < 1f
? -0.5f * MathF.Pow(2f, 10f * (k -= 1f)) * MathF.Sin((k - 0.1f) * (2f * MathF.PI) / 0.4f)
: (MathF.Pow(2f, -10f * (k -= 1f)) * MathF.Sin((k - 0.1f) * (2f * MathF.PI) / 0.4f) * 0.5f) + 1f;
}
public static class Back
{
const float S = 1.70158f;
const float S2 = 2.5949095f;
public static float In(float k) => k * k * (((S + 1f) * k) - S);
public static float Out(float k) => ((k -= 1f) * k * (((S + 1f) * k) + S)) + 1f;
public static float InOut(float k) =>
(k *= 2f) < 1f
? 0.5f * (k * k * (((S2 + 1f) * k) - S2))
: 0.5f * (((k -= 2f) * k * (((S2 + 1f) * k) + S2)) + 2f);
}
public static class Bounce
{
public static float In(float k) => 1f - Out(1f - k);
public static float Out(float k) =>
k switch
{
< 1f / 2.75f => 7.5625f * k * k,
< 2f / 2.75f => (7.5625f * (k -= 1.5f / 2.75f) * k) + 0.75f,
< 2.5f / 2.75f => (7.5625f * (k -= 2.25f / 2.75f) * k) + 0.9375f,
_ => (7.5625f * (k -= 2.625f / 2.75f) * k) + 0.984375f,
};
public static float InOut(float k) =>
k < 0.5f
? In(k * 2f) * 0.5f
: (Out((k * 2f) - 1f) * 0.5f) + 0.5f;
}
#pragma warning restore S1121
}
public enum EasingFn : byte
{
Linear,
Backward,
QuadraticIn,
QuadraticOut,
QuadraticInOut,
CubicIn,
CubicOut,
CubicInOut,
QuarticIn,
QuarticOut,
QuarticInOut,
QuinticIn,
QuinticOut,
QuinticInOut,
SinusoidalIn,
SinusoidalOut,
SinusoidalInOut,
ExponentialIn,
ExponentialOut,
ExponentialInOut,
CircularIn,
CircularOut,
CircularInOut,
ElasticIn,
ElasticOut,
ElasticInOut,
BackIn,
BackOut,
BackInOut,
BounceIn,
BounceOut,
BounceInOut,
Constant,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment