| #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; | |
| } | |
| } |