using UnityEngine;
namespace YKMoon
{
public class TweenEasingHandler
{
///
/// Apply the specified easingType, t, b, c and d.
///
/// Easing type.
/// Elapsed time.
/// Starting value.
/// Target value.
/// Duration.
public static float Apply(TweenEasing e, float time, float startV, float endV, float duration)
{
switch(e) {
case TweenEasing.Swing: {
return -endV * (time /= duration) * (time - 2f) + startV;
}
case TweenEasing.InQuad: {
return endV * (time /= duration) * time + startV;
}
case TweenEasing.OutQuad: {
return -endV * (time /= duration) * (time - 2) + startV;
}
case TweenEasing.InOutQuad: {
if((time /= duration / 2) < 1)
return endV / 2 * time * time + startV;
return -endV / 2 * ((--time) * (time - 2) - 1) + startV;
}
case TweenEasing.InCubic: {
return endV * (time /= duration) * time * time + startV;
}
case TweenEasing.OutCubic: {
return endV * ((time = time / duration - 1) * time * time + 1) + startV;
}
case TweenEasing.InOutCubic: {
if((time /= duration / 2) < 1)
return endV / 2 * time * time * time + startV;
return endV / 2 * ((time -= 2) * time * time + 2) + startV;
}
case TweenEasing.InQuart: {
return endV * (time /= duration) * time * time * time + startV;
}
case TweenEasing.OutQuart: {
return -endV * ((time = time / duration - 1) * time * time * time - 1) + startV;
}
case TweenEasing.InOutQuart: {
if((time /= duration / 2) < 1)
return endV / 2 * time * time * time * time + startV;
return -endV / 2 * ((time -= 2) * time * time * time - 2) + startV;
}
case TweenEasing.InQuint: {
return endV * (time /= duration) * time * time * time * time + startV;
}
case TweenEasing.OutQuint: {
return endV * ((time = time / duration - 1) * time * time * time * time + 1) + startV;
}
case TweenEasing.InOutQuint: {
if((time /= duration / 2) < 1)
return endV / 2 * time * time * time * time * time + startV;
return endV / 2 * ((time -= 2) * time * time * time * time + 2) + startV;
}
case TweenEasing.InSine: {
return -endV * Mathf.Cos(time / duration * (Mathf.PI / 2)) + endV + startV;
}
case TweenEasing.OutSine: {
return endV * Mathf.Sin(time / duration * (Mathf.PI / 2)) + startV;
}
case TweenEasing.InOutSine: {
return -endV / 2 * (Mathf.Cos(Mathf.PI * time / duration) - 1) + startV;
}
case TweenEasing.InExpo: {
return (time == 0) ? startV : endV * Mathf.Pow(2, 10 * (time / duration - 1)) + startV;
}
case TweenEasing.OutExpo: {
return (time == duration) ? startV + endV : endV * (-Mathf.Pow(2, -10 * time / duration) + 1) + startV;
}
case TweenEasing.InOutExpo: {
if(time == 0)
return startV;
if(time == duration)
return startV + endV;
if((time /= duration / 2) < 1)
return endV / 2 * Mathf.Pow(2, 10 * (time - 1)) + startV;
return endV / 2 * (-Mathf.Pow(2, -10 * --time) + 2) + startV;
}
case TweenEasing.InCirc: {
return -endV * (Mathf.Sqrt(1 - (time /= duration) * time) - 1) + startV;
}
case TweenEasing.OutCirc: {
return endV * Mathf.Sqrt(1 - (time = time / duration - 1) * time) + startV;
}
case TweenEasing.InOutCirc: {
if((time /= duration / 2) < 1)
return -endV / 2 * (Mathf.Sqrt(1 - time * time) - 1) + startV;
return endV / 2 * (Mathf.Sqrt(1 - (time -= 2) * time) + 1) + startV;
}
case TweenEasing.InBack: {
float s = 1.70158f;
return endV * (time /= duration) * time * ((s + 1f) * time - s) + startV;
}
case TweenEasing.OutBack: {
float s = 1.70158f;
return endV * ((time = time / duration - 1f) * time * ((s + 1f) * time + s) + 1f) + startV;
}
case TweenEasing.InOutBack: {
float s = 1.70158f;
if((time /= duration / 2f) < 1f)
return endV / 2f * (time * time * (((s *= (1.525f)) + 1f) * time - s)) + startV;
return endV / 2f * ((time -= 2f) * time * (((s *= (1.525f)) + 1f) * time + s) + 2f) + startV;
}
case TweenEasing.InBounce: {
return endV - TweenEasingHandler.Apply(TweenEasing.OutBounce, duration - time, 0f, endV, duration) + startV;
}
case TweenEasing.OutBounce: {
if((time /= duration) < (1f / 2.75f)) {
return endV * (7.5625f * time * time) + startV;
} else if(time < (2f / 2.75f)) {
return endV * (7.5625f * (time -= (1.5f / 2.75f)) * time + .75f) + startV;
} else if(time < (2.5f / 2.75f)) {
return endV * (7.5625f * (time -= (2.25f / 2.75f)) * time + .9375f) + startV;
} else {
return endV * (7.5625f * (time -= (2.625f / 2.75f)) * time + .984375f) + startV;
}
}
case TweenEasing.InOutBounce: {
if(time < duration / 2f)
return TweenEasingHandler.Apply(TweenEasing.InBounce, time * 2f, 0f, endV, duration) * .5f + startV;
return TweenEasingHandler.Apply(TweenEasing.OutBounce, time * 2f - duration, 0f, endV, duration) * .5f + endV * .5f + startV;
}
case TweenEasing.InElastic: {
float s = 1.70158f;
float p = 0f;
float a = endV;
if(time == 0f)
return startV;
if((time /= duration) == 1f)
return startV + endV;
if(p == 0f)
p = duration * .3f;
if(a < Mathf.Abs(endV)) { a = endV; s = p / 4f; } else
s = p / (2f * Mathf.PI) * Mathf.Asin(endV / a);
if(float.IsNaN(s))
s = 0f;
return -(a * Mathf.Pow(2f, 10f * (time -= 1f)) * Mathf.Sin((time * duration - s) * (2f * Mathf.PI) / p)) + startV;
}
case TweenEasing.OutElastic: {
float s = 1.70158f;
float p = 0f;
float a = endV;
if(time == 0f)
return startV;
if((time /= duration) == 1f)
return startV + endV;
if(p == 0f)
p = duration * .3f;
if(a < Mathf.Abs(endV)) { a = endV; s = p / 4f; } else
s = p / (2f * Mathf.PI) * Mathf.Asin(endV / a);
if(float.IsNaN(s))
s = 0f;
return a * Mathf.Pow(2f, -10f * time) * Mathf.Sin((time * duration - s) * (2f * Mathf.PI) / p) + endV + startV;
}
case TweenEasing.InOutElastic: {
float s = 1.70158f;
float p = 0f;
float a = endV;
if(time == 0f)
return startV;
if((time /= duration / 2f) == 2f)
return startV + endV;
if(p == 0f)
p = duration * (.3f * 1.5f);
if(a < Mathf.Abs(endV)) { a = endV; s = p / 4f; } else
s = p / (2f * Mathf.PI) * Mathf.Asin(endV / a);
if(float.IsNaN(s))
s = 0f;
if(time < 1f)
return -.5f * (a * Mathf.Pow(2f, 10f * (time -= 1f)) * Mathf.Sin((time * duration - s) * (2f * Mathf.PI) / p)) + startV;
return a * Mathf.Pow(2f, -10f * (time -= 1f)) * Mathf.Sin((time * duration - s) * (2f * Mathf.PI) / p) * .5f + endV + startV;
}
case TweenEasing.Linear:
default: {
return endV * time / duration + startV;
}
}
}
}
}