axmol/extensions/fairygui/tween/EaseManager.cpp

201 lines
6.7 KiB
C++

#include "EaseManager.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
USING_NS_AX;
static const float _PiOver2 = (float)(M_PI * 0.5f);
static const float _TwoPi = (float)(M_PI * 2);
class Bounce
{
public:
static float easeIn(float time, float duration);
static float easeOut(float time, float duration);
static float easeInOut(float time, float duration);
};
float EaseManager::evaluate(EaseType easeType, float time, float duration, float overshootOrAmplitude, float period)
{
switch (easeType)
{
case EaseType::Linear:
return time / duration;
case EaseType::SineIn:
return -(float)cos(time / duration * _PiOver2) + 1;
case EaseType::SineOut:
return (float)sin(time / duration * _PiOver2);
case EaseType::SineInOut:
return -0.5f * ((float)cos(M_PI * time / duration) - 1);
case EaseType::QuadIn:
time /= duration;
return time * time;
case EaseType::QuadOut:
time /= duration;
return -time * (time - 2);
case EaseType::QuadInOut:
time /= duration * 0.5f;
if (time < 1) return 0.5f * time * time;
--time;
return -0.5f * (time * (time - 2) - 1);
case EaseType::CubicIn:
time /= duration;
return time * time * time;
case EaseType::CubicOut:
time = time / duration - 1;
return time * time * time + 1;
case EaseType::CubicInOut:
time /= duration * 0.5f;
if (time < 1) return 0.5f * time * time * time;
time -= 2;
return 0.5f * (time * time * time + 2);
case EaseType::QuartIn:
time /= duration;
return time * time * time * time;
case EaseType::QuartOut:
time = time / duration - 1;
return -(time * time * time * time - 1);
case EaseType::QuartInOut:
time /= duration * 0.5f;
if (time < 1) return 0.5f * time * time * time * time;
time -= 2;
return -0.5f * (time * time * time * time - 2);
case EaseType::QuintIn:
time /= duration;
return time * time * time * time * time;
case EaseType::QuintOut:
time = time / duration - 1;
return (time * time * time * time * time + 1);
case EaseType::QuintInOut:
time /= duration * 0.5f;
if (time < 1) return 0.5f * time * time * time * time * time;
time -= 2;
return 0.5f * (time * time * time * time * time + 2);
case EaseType::ExpoIn:
return (time == 0) ? 0 : (float)pow(2, 10 * (time / duration - 1));
case EaseType::ExpoOut:
if (time == duration) return 1;
return (-(float)pow(2, -10 * time / duration) + 1);
case EaseType::ExpoInOut:
if (time == 0) return 0;
if (time == duration) return 1;
if ((time /= duration * 0.5f) < 1) return 0.5f * (float)pow(2, 10 * (time - 1));
return 0.5f * (-(float)pow(2, -10 * --time) + 2);
case EaseType::CircIn:
time /= duration;
return -((float)sqrt(1 - time * time) - 1);
case EaseType::CircOut:
time = time / duration - 1;
return (float)sqrt(1 - time * time);
case EaseType::CircInOut:
time /= duration * 0.5f;
if (time < 1) return -0.5f * ((float)sqrt(1 - time * time) - 1);
time -= 2;
return 0.5f * ((float)sqrt(1 - time * time) + 1);
case EaseType::ElasticIn:
float s0;
if (time == 0) return 0;
if ((time /= duration) == 1) return 1;
if (period == 0) period = duration * 0.3f;
if (overshootOrAmplitude < 1)
{
overshootOrAmplitude = 1;
s0 = period / 4;
}
else s0 = period / _TwoPi * (float)asin(1 / overshootOrAmplitude);
time -= 1;
return -(overshootOrAmplitude * (float)pow(2, 10 * time) * (float)sin((time * duration - s0) * _TwoPi / period));
case EaseType::ElasticOut:
float s1;
if (time == 0) return 0;
if ((time /= duration) == 1) return 1;
if (period == 0) period = duration * 0.3f;
if (overshootOrAmplitude < 1)
{
overshootOrAmplitude = 1;
s1 = period / 4;
}
else s1 = period / _TwoPi * (float)asin(1 / overshootOrAmplitude);
return (overshootOrAmplitude * (float)pow(2, -10 * time) * (float)sin((time * duration - s1) * _TwoPi / period) + 1);
case EaseType::ElasticInOut:
float s;
if (time == 0) return 0;
if ((time /= duration * 0.5f) == 2) return 1;
if (period == 0) period = duration * (0.3f * 1.5f);
if (overshootOrAmplitude < 1)
{
overshootOrAmplitude = 1;
s = period / 4;
}
else s = period / _TwoPi * (float)asin(1 / overshootOrAmplitude);
if (time < 1)
{
time -= 1;
return -0.5f * (overshootOrAmplitude * (float)pow(2, 10 * time) * (float)sin((time * duration - s) * _TwoPi / period));
}
time -= 1;
return overshootOrAmplitude * (float)pow(2, -10 * time) * (float)sin((time * duration - s) * _TwoPi / period) * 0.5f + 1;
case EaseType::BackIn:
time /= duration;
return time * time * ((overshootOrAmplitude + 1) * time - overshootOrAmplitude);
case EaseType::BackOut:
time = time / duration - 1;
return (time * time * ((overshootOrAmplitude + 1) * time + overshootOrAmplitude) + 1);
case EaseType::BackInOut:
time /= duration * 0.5f;
overshootOrAmplitude *= (1.525f);
if (time < 1) return 0.5f * (time * time * ((overshootOrAmplitude + 1) * time - overshootOrAmplitude));
time -= 2;
return 0.5f * (time * time * ((overshootOrAmplitude + 1) * time + overshootOrAmplitude) + 2);
case EaseType::BounceIn:
return Bounce::easeIn(time, duration);
case EaseType::BounceOut:
return Bounce::easeOut(time, duration);
case EaseType::BounceInOut:
return Bounce::easeInOut(time, duration);
default:
time /= duration;
return -time * (time - 2);
}
}
float Bounce::easeIn(float time, float duration)
{
return 1 - easeOut(duration - time, duration);
}
float Bounce::easeOut(float time, float duration)
{
time /= duration;
if (time < (1 / 2.75f))
{
return (7.5625f * time * time);
}
if (time < (2 / 2.75f))
{
time -= (1.5f / 2.75f);
return (7.5625f * time * time + 0.75f);
}
if (time < (2.5f / 2.75f))
{
time -= (2.25f / 2.75f);
return (7.5625f * time * time + 0.9375f);
}
time -= (2.625f / 2.75f);
return (7.5625f * time * time + 0.984375f);
}
float Bounce::easeInOut(float time, float duration)
{
if (time < duration * 0.5f)
{
return easeIn(time * 2, duration) * 0.5f;
}
return easeOut(time * 2 - duration, duration) * 0.5f + 0.5f;
}
NS_FGUI_END