1
0
mirror of synced 2025-02-03 13:03:28 +01:00
OpenTaiko/TJAPlayer3/Helpers/HEasingMethods.cs

371 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Security;
namespace TJAPlayer3
{
internal class HEasingMethods
{
public enum EEaseType
{
IN = 0,
OUT,
INOUT,
OUTIN
}
public enum EEaseFunction
{
LINEAR = 0,
SINE,
QUAD,
CUBIC,
QUART,
QUINT,
EXPO,
CIRC,
ELASTIC,
BACK,
BOUNCE
}
private static readonly Dictionary<EEaseFunction, Func<double, double>> _easeMethods = new Dictionary<EEaseFunction, Func<double, double>>()
{
[EEaseFunction.LINEAR] = _easeLinear,
[EEaseFunction.SINE] = _easeSine,
[EEaseFunction.QUAD] = _easeQuad,
[EEaseFunction.CUBIC] = _easeCubic,
[EEaseFunction.QUART] = _easeQuart,
[EEaseFunction.QUINT] = _easeQuint,
[EEaseFunction.EXPO] = _easeExpo,
[EEaseFunction.CIRC] = _easeCirc,
[EEaseFunction.ELASTIC] = _easeElastic,
[EEaseFunction.BACK] = _easeBack,
[EEaseFunction.BOUNCE] = _easeBounce,
};
private static double _easeOut(Func<double, double> f, double x)
{
return 1.0 - f(1 - x);
}
private static double _easeInOut(Func<double, double> f, double x)
{
return (x < 0.5) ? 0.5 * f(x * 2) : 0.5 * (1 - f((1 - x) * 2)) + 0.5;
}
private static double _easeOutIn(Func<double, double> f, double x)
{
return (x < 0.5) ? 0.5 * (1 - f((1 - x) * 2)) : 0.5 * (1 - (1 - f(1 - (1 - x) * 2))) + 0.5;
}
private static double _easeLinear(double x)
{
return x;
}
private static double _easeQuad(double x)
{
return x * x;
}
private static double _easeCubic(double x)
{
return x * x * x;
}
private static double _easeQuart(double x)
{
return x * x * x * x;
}
private static double _easeQuint(double x)
{
return x * x * x * x * x;
}
private static double _easeExpo(double x)
{
return x == 0 ? 0 : Math.Pow(2, 10 * (x - 1));
}
private static double _easeSine(double x)
{
return 1.0 - Math.Cos((x * Math.PI) / 2.0);
}
private static double _easeCirc(double x)
{
return 1.0 - Math.Sqrt(1 - Math.Pow(x, 2));
}
private static double _easeBack(double x)
{
return x * x * (2.7 * x - 1.7);
}
private static double _easeElastic(double x)
{
if (x == 0 || x == 1) return x;
const double c4 = (2 * Math.PI) / 3;
return -Math.Pow(2, 10 * x - 10) * Math.Sin((x * 10 - 10.75) * c4);
}
private static double _easeBounce(double x)
{
const double c1 = 2.75;
const double c2 = 7.5625;
double c3 = x * x;
if (x < 1.0 / c1)
return c2 * c3;
else if (x < 2.0 / c1)
return c2 * c3 + 0.75;
else if (x < 2.5 / c1)
return c2 * c3 + 0.9375;
return c2 * c3 + 0.984375;
}
#region [Legacy]
/*
private static double _easeSine(EEaseType type, double x)
{
switch (type) {
case EEaseType.IN:
default:
return 1 - Math.Cos((x * Math.PI) / 2.0);
case EEaseType.OUT:
return Math.Sin((x * Math.PI) / 2.0);
case EEaseType.INOUT:
return -(Math.Cos(x * Math.PI) - 1) / 2.0;
case EEaseType.OUTIN:
return x;
}
}
private static double _easeQuad(EEaseType type, double x)
{
switch (type)
{
case EEaseType.IN:
default:
return x * x;
case EEaseType.OUT:
return 1 - (1 - x) * (1 - x);
case EEaseType.INOUT:
return x < 0.5 ? 2 * x * x : 1 - Math.Pow(-2 * x + 2, 2) / 2.0;
case EEaseType.OUTIN:
return x;
}
}
private static double _easeCubic(EEaseType type, double x)
{
switch (type)
{
case EEaseType.IN:
default:
return x * x * x;
case EEaseType.OUT:
return 1 - Math.Pow(1 - x, 3);
case EEaseType.INOUT:
return x < 0.5 ? 4 * x * x * x : 1 - Math.Pow(-2 * x + 2, 3) / 2.0;
case EEaseType.OUTIN:
return x;
}
}
private static double _easeQuart(EEaseType type, double x)
{
switch (type)
{
case EEaseType.IN:
default:
return x * x * x * x;
case EEaseType.OUT:
return 1 - Math.Pow(1 - x, 4);
case EEaseType.INOUT:
return x < 0.5 ? 8 * x * x * x * x : 1 - Math.Pow(-2 * x + 2, 4) / 2.0;
case EEaseType.OUTIN:
return x;
}
}
private static double _easeQuint(EEaseType type, double x)
{
switch (type)
{
case EEaseType.IN:
default:
return x * x * x * x * x;
case EEaseType.OUT:
return 1 - Math.Pow(1 - x, 5);
case EEaseType.INOUT:
return x < 0.5 ? 16 * x * x * x * x * x : 1 - Math.Pow(-2 * x + 2, 5) / 2.0;
case EEaseType.OUTIN:
return x;
}
}
private static double _easeExpo(EEaseType type, double x)
{
switch (type)
{
case EEaseType.IN:
default:
return x == 0 ? 0 : Math.Pow(2, 10 * x - 10);
case EEaseType.OUT:
return x == 1 ? 1 : 1 - Math.Pow(2, -10 * x);
case EEaseType.INOUT:
return x == 0
? 0
: x == 1
? 1
: x < 0.5
? Math.Pow(2, 20 * x - 10) / 2
: (2 - Math.Pow(2, -20 * x + 10)) / 2; ;
case EEaseType.OUTIN:
return x;
}
}
private static double _easeCirc(EEaseType type, double x)
{
switch (type)
{
case EEaseType.IN:
default:
return 1 - Math.Sqrt(1 - Math.Pow(x, 2));
case EEaseType.OUT:
return Math.Sqrt(1 - Math.Pow(x - 1, 2));
case EEaseType.INOUT:
return x < 0.5
? (1 - Math.Sqrt(1 - Math.Pow(2 * x, 2))) / 2
: (Math.Sqrt(1 - Math.Pow(-2 * x + 2, 2)) + 1) / 2;
case EEaseType.OUTIN:
return x;
}
}
private static double _easeBack(EEaseType type, double x)
{
const double c1 = 1.70158;
const double c2 = c1 * 1.525;
const double c3 = c1 + 1;
switch (type)
{
case EEaseType.IN:
default:
return c3 * x * x * x - c1 * x * x;
case EEaseType.OUT:
return 1 + c3 * Math.Pow(x - 1, 3) + c1 * Math.Pow(x - 1, 2);
case EEaseType.INOUT:
return x < 0.5
? (Math.Pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2
: (Math.Pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;
case EEaseType.OUTIN:
return x;
}
}
private static double _easeElastic(EEaseType type, double x)
{
const double c4 = (2 * Math.PI) / 3;
const double c5 = (2 * Math.PI) / 4.5;
switch (type)
{
case EEaseType.IN:
default:
return x == 0
? 0
: x == 1
? 1
: -Math.Pow(2, 10 * x - 10) * Math.Sin((x * 10 - 10.75) * c4);
case EEaseType.OUT:
return x == 0
? 0
: x == 1
? 1
: Math.Pow(2, -10 * x) * Math.Sin((x * 10 - 0.75) * c4) + 1;
case EEaseType.INOUT:
return x == 0
? 0
: x == 1
? 1
: x < 0.5
? -(Math.Pow(2, 20 * x - 10) * Math.Sin((20 * x - 11.125) * c5)) / 2
: (Math.Pow(2, -20 * x + 10) * Math.Sin((20 * x - 11.125) * c5)) / 2 + 1;
case EEaseType.OUTIN:
return x;
}
}
private static double _easeOutBounce(double x)
{
const double n1 = 7.5625;
const double d1 = 2.75;
if (x < 1 / d1)
return n1 * x * x;
else if (x < 2 / d1)
return n1 * (x -= 1.5 / d1) * x + 0.75;
else if (x < 2.5 / d1)
return n1 * (x -= 2.25 / d1) * x + 0.9375;
else
return n1 * (x -= 2.625 / d1) * x + 0.984375;
}
private static double _easeBounce(EEaseType type, double x)
{
switch (type)
{
case EEaseType.IN:
default:
return 1 - _easeOutBounce(1 - x);
case EEaseType.OUT:
return _easeOutBounce(x);
case EEaseType.INOUT:
return x < 0.5
? (1 - _easeOutBounce(1 - 2 * x)) / 2
: (1 + _easeOutBounce(2 * x - 1)) / 2;
case EEaseType.OUTIN:
return x;
}
}
*/
#endregion
public static double tCalculateEaseNorm(EEaseType type, EEaseFunction function, double ratio)
{
switch (type)
{
case EEaseType.IN:
default:
return _easeMethods[function](ratio);
case EEaseType.OUT:
return _easeOut(_easeMethods[function], ratio);
case EEaseType.INOUT:
return _easeInOut(_easeMethods[function], ratio);
case EEaseType.OUTIN:
return _easeOutIn(_easeMethods[function], ratio);
}
}
public static double tCalculateEase(EEaseType type, EEaseFunction function, double timeStart, double timeEnd, double timeCurrent, double valueStart, double valueEnd)
{
if (timeStart == timeEnd) return valueEnd;
double ratio = (timeCurrent - timeStart) / (timeEnd - timeStart);
double ratio_eased = tCalculateEaseNorm(type, function, ratio);//_easeMethods[function](type, ratio);
return valueStart + ratio_eased * (valueEnd - valueStart);
}
}
}