blob: fd96d815e3f5a3adaeaf0ea5156a5a970943b01d [file] [log] [blame]
#include "rive/animation/elastic_ease.hpp"
#include "rive/math/math_types.hpp"
#include "math.h"
using namespace rive;
ElasticEase::ElasticEase(float amplitude, float period) :
m_amplitude(amplitude),
m_period(period),
m_s(amplitude < 1.0f ? period / 4.0f : period / (2.0f * math::PI) * asinf(1.0f / amplitude))
{}
float ElasticEase::computeActualAmplitude(float time) const
{
if (m_amplitude < 1.0f)
{
/// We use this when the amplitude is less than 1.0 (amplitude is
/// described as factor of change in value). We also precompute s which is
/// the effective starting period we use to align the decaying sin with
/// our keyframe.
float t = abs(m_s);
float absTime = abs(time);
if (absTime < t)
{
float l = absTime / t;
return (m_amplitude * l) + (1.0f - l);
}
}
return m_amplitude;
}
float ElasticEase::easeOut(float factor) const
{
float time = factor;
float actualAmplitude = computeActualAmplitude(time);
return (actualAmplitude * pow(2.0f, 10.0f * -time) *
sinf((time - m_s) * (2.0f * math::PI) / m_period)) +
1.0f;
}
float ElasticEase::easeIn(float factor) const
{
float time = factor - 1.0f;
float actualAmplitude = computeActualAmplitude(time);
return -(actualAmplitude * pow(2.0f, 10.0f * time) *
sinf((-time - m_s) * (2.0f * math::PI) / m_period));
}
float ElasticEase::easeInOut(float factor) const
{
float time = factor * 2.0f - 1.0f;
float actualAmplitude = computeActualAmplitude(time);
if (time < 0.0f)
{
return -0.5f * actualAmplitude * pow(2.0f, 10.0f * time) *
sinf((-time - m_s) * (2.0f * math::PI) / m_period);
}
else
{
return 0.5f * (actualAmplitude * pow(2.0f, 10.0f * -time) *
sinf((time - m_s) * (2.0f * math::PI) / m_period)) +
1.0f;
}
}