This repository has been archived on 2025-10-18. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
RDTKEditor/RhythmBaseCore/Components/Easing/Ease.cs
T

283 lines
8.5 KiB
C#

namespace RhythmBase.Components.Easing
{
///<summary>
/// The EaseType enumeration represents various types of easing functions.
/// These functions are used to create smooth transitions in animations.
///</summary>
public enum EaseType
{
/// <summary>
/// Unset.
/// </summary>
Unset = -1,
///<summary>
///Ease Linear.
///</summary>
Linear,
///<summary>
///Ease InSine.
///</summary>
InSine,
///<summary>
///Ease OutSine.
///</summary>
OutSine,
///<summary>
///Ease InOutSine.
///</summary>
InOutSine,
///<summary>
///Ease InQuad.
///</summary>
InQuad,
///<summary>
///Ease OutQuad.
///</summary>
OutQuad,
///<summary>
///Ease InOutQuad.
///</summary>
InOutQuad,
///<summary>
///Ease InCubic.
///</summary>
InCubic,
///<summary>
///Ease OutCubic.
///</summary>
OutCubic,
///<summary>
///Ease InOutCubic.
///</summary>
InOutCubic,
///<summary>
///Ease InQuart.
///</summary>
InQuart,
///<summary>
///Ease OutQuart.
///</summary>
OutQuart,
///<summary>
///Ease InOutQuart.
///</summary>
InOutQuart,
///<summary>
///Ease InQuint.
///</summary>
InQuint,
///<summary>
///Ease OutQuint.
///</summary>
OutQuint,
///<summary>
///Ease InOutQuint.
///</summary>
InOutQuint,
///<summary>
///Ease InExpo.
///</summary>
InExpo,
///<summary>
///Ease OutExpo.
///</summary>
OutExpo,
///<summary>
///Ease InOutExpo.
///</summary>
InOutExpo,
///<summary>
///Ease InCirc.
///</summary>
InCirc,
///<summary>
///Ease OutCirc.
///</summary>
OutCirc,
///<summary>
///Ease InOutCirc.
///</summary>
InOutCirc,
///<summary>
///Ease InElastic.
///</summary>
InElastic,
///<summary>
///Ease OutElastic.
///</summary>
OutElastic,
///<summary>
///Ease InOutElastic.
///</summary>
InOutElastic,
///<summary>
///Ease InBack.
///</summary>
InBack,
///<summary>
///Ease OutBack.
///</summary>
OutBack,
///<summary>
///Ease InOutBack.
///</summary>
InOutBack,
///<summary>
///Ease InBounce.
///</summary>
InBounce,
///<summary>
///Ease OutBounce.
///</summary>
OutBounce,
///<summary>
///Ease InOutBounce.
///</summary>
InOutBounce,
///<summary>
///Ease SmoothStep.
///</summary>
SmoothStep,
}
/// <summary>
/// Ease Calculate module.
/// </summary>
public static class Ease
{
/// <summary>
/// Calculates the value with the specified ease type.
/// </summary>
/// <param name="type">Ease type.</param>
/// <param name="x">A doubleing-point number in the range of 0 to 1.</param>
/// <returns>Easing result.</returns>
public static double Calculate(this EaseType type, double x) => type switch
{
EaseType.Unset => EaseFunction.None(x),
EaseType.Linear => EaseFunction.Linear(x),
EaseType.InSine => EaseFunction.InSine(x),
EaseType.OutSine => EaseFunction.OutSine(x),
EaseType.InOutSine => EaseFunction.InOutSine(x),
EaseType.InQuad => EaseFunction.InQuad(x),
EaseType.OutQuad => EaseFunction.OutQuad(x),
EaseType.InOutQuad => EaseFunction.InOutQuad(x),
EaseType.InCubic => EaseFunction.InCubic(x),
EaseType.OutCubic => EaseFunction.OutCubic(x),
EaseType.InOutCubic => EaseFunction.InOutCubic(x),
EaseType.InQuart => EaseFunction.InQuart(x),
EaseType.OutQuart => EaseFunction.OutQuart(x),
EaseType.InOutQuart => EaseFunction.InOutQuart(x),
EaseType.InQuint => EaseFunction.InQuint(x),
EaseType.OutQuint => EaseFunction.OutQuint(x),
EaseType.InOutQuint => EaseFunction.InOutQuint(x),
EaseType.InExpo => EaseFunction.InExpo(x),
EaseType.OutExpo => EaseFunction.OutExpo(x),
EaseType.InOutExpo => EaseFunction.InOutExpo(x),
EaseType.InCirc => EaseFunction.InCirc(x),
EaseType.OutCirc => EaseFunction.OutCirc(x),
EaseType.InOutCirc => EaseFunction.InOutCirc(x),
EaseType.InElastic => EaseFunction.InElastic(x),
EaseType.OutElastic => EaseFunction.OutElastic(x),
EaseType.InOutElastic => EaseFunction.InOutElastic(x),
EaseType.InBack => EaseFunction.InBack(x),
EaseType.OutBack => EaseFunction.OutBack(x),
EaseType.InOutBack => EaseFunction.InOutBack(x),
EaseType.InBounce => EaseFunction.InBounce(x),
EaseType.OutBounce => EaseFunction.OutBounce(x),
EaseType.InOutBounce => EaseFunction.InOutBounce(x),
EaseType.SmoothStep => EaseFunction.SmoothStep(x),
_ => 0,
};
/// <summary>
/// Calculates the value with the specified ease type.
/// </summary>
/// <param name="Type">Ease type.</param>
/// <param name="x">A doubleing-point number in the range of 0 to 1.</param>
/// <param name="from">The starting value of the easing result.</param>
/// <param name="to">The endding value of the easing result</param>
/// <returns>Easing result.</returns>
public static double Calculate(this EaseType Type, double x, double from, double to) => Type.Calculate(x) * (to - from) + from;
/// <summary>
/// Ease types.
/// </summary>
private static class EaseFunction
{
private const double c1 = 1.525;
private const double c2 = 1.70158;
public static double None(double x) => 0;
public static double Linear(double x) => x;
public static double InSine(double x) => 1 - Math.Cos(x * double.Pi / 2);
public static double OutSine(double x) => Math.Sin(x * double.Pi / 2);
public static double InOutSine(double x) => -(Math.Cos(x * double.Pi) - 1) / 2;
public static double InQuad(double x) => Math.Pow(x, 2);
public static double OutQuad(double x) => 1 - Math.Pow(1 - x, 2);
public static double InOutQuad(double x) => x < 0.5 ? 2 * Math.Pow(x, 2) : 1 - Math.Pow(-2 * x + 2, 2) / 2;
public static double InCubic(double x) => Math.Pow(x, 3);
public static double OutCubic(double x) => 1 - Math.Pow(1 - x, 3);
public static double InOutCubic(double x) => x < 0.5 ? 4 * Math.Pow(x, 3) : 1 - Math.Pow(-2 * x + 2, 3) / 2;
public static double InQuart(double x) => Math.Pow(x, 4);
public static double OutQuart(double x) => 1 - Math.Pow(1 - x, 4);
public static double InOutQuart(double x) => x < 0.5 ? 8 * Math.Pow(x, 4) : 1 - Math.Pow(-2 * x + 2, 4) / 2;
public static double InQuint(double x) => Math.Pow(x, 5);
public static double OutQuint(double x) => 1 - Math.Pow(1 - x, 5);
public static double InOutQuint(double x) => x < 0.5 ? 16 * Math.Pow(x, 5) : 1 - Math.Pow(-2 * x + 2, 5) / 2;
public static double InExpo(double x) => x == 0 ? 0 : Math.Pow(2, 10 * x - 10);
public static double OutExpo(double x) => x == 1 ? 1 : 1 - Math.Pow(2, -10 * x);
public static double InOutExpo(double x) => x == 0
? 0
: x == 1
? 1
: x < 0.5 ? Math.Pow(2, 20 * x - 10) / 2
: (2 - Math.Pow(2, -20 * x + 10)) / 2;
public static double InCirc(double x) => 1 - Math.Sqrt(1 - Math.Pow(x, 2));
public static double OutCirc(double x) => Math.Sqrt(1 - Math.Pow(x - 1, 2));
public static double InOutCirc(double x) => x < 0.5
? (1 - Math.Sqrt(1 - Math.Pow(2 * x, 2))) / 2
: (Math.Sqrt(1 - Math.Pow(-2 * x + 2, 2)) + 1) / 2;
public static double InElastic(double x) => x == 0
? 0
: x == 1
? 1
: -Math.Pow(2, 10 * x - 10) * Math.Sin((x * 10 - 10.75) * (2 * double.Pi / 3));
public static double OutElastic(double x) => x == 0
? 0
: x == 1
? 1
: Math.Pow(2, -10 * x) * Math.Sin((x * 10 - 0.75) * (2 * double.Pi / 3)) + 1;
public static double InOutElastic(double x) => x == 0
? 0
: x == 1
? 1
: x < 0.5
? -(Math.Pow(2, 20 * x - 10) * Math.Sin((20 * x - 11.125) * (2 * double.Pi / 4.5))) / 2
: Math.Pow(2, -20 * x + 10) * Math.Sin((20 * x - 11.125) * (2 * double.Pi / 4.5)) / 2 + 1;
public static double InBack(double x) => (c2 + 1) * x * x * x - c2 * x * x;
public static double OutBack(double x) => 1 + (c2 + 1) * Math.Pow(x - 1, 3) + c2 * Math.Pow(x - 1, 2);
public static double InOutBack(double x) => x < 0.5
? Math.Pow(2 * x, 2) * ((c2 * c1 + 1) * 2 * x - c2 * c1) / 2
: (Math.Pow(2 * x - 2, 2) * ((c2 * c1 + 1) * (x * 2 - 2) + c2 * c1) + 2) / 2;
public static double InBounce(double x) =>
1 - OutBounce(1 - x);
public static double OutBounce(double x)
{
const double n1 = 7.5625;
const double d1 = 2.75;
return x switch
{
< 1 / d1 => n1 * x * x,
< 2 / d1 => n1 * (x -= 1.5 / d1) * x + 0.75,
< 2.5 / d1 => n1 * (x -= 2.25 / d1) * x + 0.9375,
_ => n1 * (x -= 2.625 / d1) * x + 0.984375,
};
}
public static double InOutBounce(double x) =>
x < 0.5
? (1 - OutBounce(1 - 2 * x)) / 2
: (1 + OutBounce(2 * x - 1)) / 2;
public static double SmoothStep(double x) =>
(3 - 2 * x) * Math.Pow(x, 2);
}
}
}