Loading...
Searching...
No Matches
Easing.h
Go to the documentation of this file.
1// Copyright (c) 2025 Dave R. Smith.
2// Malena Framework — Licensed under PolyForm Noncommercial 1.0.0; commercial use requires a paid license. See LICENSE.
3
4//
5// Easing.h — pure easing functions for the Animate subsystem.
6//
7
8#ifndef MALENA_EASING_H
9#define MALENA_EASING_H
10
11#pragma once
12
13#include <cmath>
14
15namespace ml
16{
32 struct Easing
33 {
34 using Fn = float (*)(float);
35
36 static constexpr float kPi = 3.14159265358979323846f;
37
38 // ── Linear ──────────────────────────────────────────────────────────
39 static float Linear(float t) { return t; }
40
41 // ── Quadratic ───────────────────────────────────────────────────────
42 static float EaseInQuad(float t) { return t * t; }
43 static float EaseOutQuad(float t) { return 1.f - (1.f - t) * (1.f - t); }
44 static float EaseInOutQuad(float t) {
45 return t < 0.5f ? 2.f * t * t : 1.f - std::pow(-2.f * t + 2.f, 2.f) / 2.f;
46 }
47
48 // ── Cubic ───────────────────────────────────────────────────────────
49 static float EaseInCubic(float t) { return t * t * t; }
50 static float EaseOutCubic(float t) { return 1.f - std::pow(1.f - t, 3.f); }
51 static float EaseInOutCubic(float t) {
52 return t < 0.5f ? 4.f * t * t * t : 1.f - std::pow(-2.f * t + 2.f, 3.f) / 2.f;
53 }
54
55 // ── Quartic ─────────────────────────────────────────────────────────
56 static float EaseInQuart(float t) { return t * t * t * t; }
57 static float EaseOutQuart(float t) { return 1.f - std::pow(1.f - t, 4.f); }
58 static float EaseInOutQuart(float t) {
59 return t < 0.5f ? 8.f * t * t * t * t : 1.f - std::pow(-2.f * t + 2.f, 4.f) / 2.f;
60 }
61
62 // ── Quintic ─────────────────────────────────────────────────────────
63 static float EaseInQuint(float t) { return t * t * t * t * t; }
64 static float EaseOutQuint(float t) { return 1.f - std::pow(1.f - t, 5.f); }
65 static float EaseInOutQuint(float t) {
66 return t < 0.5f ? 16.f * t * t * t * t * t : 1.f - std::pow(-2.f * t + 2.f, 5.f) / 2.f;
67 }
68
69 // ── Sine ────────────────────────────────────────────────────────────
70 static float EaseInSine(float t) { return 1.f - std::cos((t * kPi) / 2.f); }
71 static float EaseOutSine(float t) { return std::sin((t * kPi) / 2.f); }
72 static float EaseInOutSine(float t) { return -(std::cos(kPi * t) - 1.f) / 2.f; }
73
74 // ── Exponential ─────────────────────────────────────────────────────
75 static float EaseInExpo(float t) { return t <= 0.f ? 0.f : std::pow(2.f, 10.f * t - 10.f); }
76 static float EaseOutExpo(float t) { return t >= 1.f ? 1.f : 1.f - std::pow(2.f, -10.f * t); }
77 static float EaseInOutExpo(float t) {
78 if (t <= 0.f) return 0.f;
79 if (t >= 1.f) return 1.f;
80 return t < 0.5f ? std::pow(2.f, 20.f * t - 10.f) / 2.f
81 : (2.f - std::pow(2.f, -20.f * t + 10.f)) / 2.f;
82 }
83
84 // ── Circular ────────────────────────────────────────────────────────
85 static float EaseInCirc(float t) { return 1.f - std::sqrt(1.f - t * t); }
86 static float EaseOutCirc(float t) { return std::sqrt(1.f - (t - 1.f) * (t - 1.f)); }
87 static float EaseInOutCirc(float t) {
88 return t < 0.5f
89 ? (1.f - std::sqrt(1.f - std::pow(2.f * t, 2.f))) / 2.f
90 : (std::sqrt(1.f - std::pow(-2.f * t + 2.f, 2.f)) + 1.f) / 2.f;
91 }
92
93 // ── Back (overshoots) ───────────────────────────────────────────────
94 static float EaseInBack(float t) {
95 const float c1 = 1.70158f, c3 = c1 + 1.f;
96 return c3 * t * t * t - c1 * t * t;
97 }
98 static float EaseOutBack(float t) {
99 const float c1 = 1.70158f, c3 = c1 + 1.f;
100 return 1.f + c3 * std::pow(t - 1.f, 3.f) + c1 * std::pow(t - 1.f, 2.f);
101 }
102 static float EaseInOutBack(float t) {
103 const float c1 = 1.70158f, c2 = c1 * 1.525f;
104 return t < 0.5f
105 ? (std::pow(2.f * t, 2.f) * ((c2 + 1.f) * 2.f * t - c2)) / 2.f
106 : (std::pow(2.f * t - 2.f, 2.f) * ((c2 + 1.f) * (t * 2.f - 2.f) + c2) + 2.f) / 2.f;
107 }
108
109 // ── Elastic (springs) ───────────────────────────────────────────────
110 static float EaseInElastic(float t) {
111 if (t <= 0.f) return 0.f;
112 if (t >= 1.f) return 1.f;
113 const float c4 = (2.f * kPi) / 3.f;
114 return -std::pow(2.f, 10.f * t - 10.f) * std::sin((t * 10.f - 10.75f) * c4);
115 }
116 static float EaseOutElastic(float t) {
117 if (t <= 0.f) return 0.f;
118 if (t >= 1.f) return 1.f;
119 const float c4 = (2.f * kPi) / 3.f;
120 return std::pow(2.f, -10.f * t) * std::sin((t * 10.f - 0.75f) * c4) + 1.f;
121 }
122 static float EaseInOutElastic(float t) {
123 if (t <= 0.f) return 0.f;
124 if (t >= 1.f) return 1.f;
125 const float c5 = (2.f * kPi) / 4.5f;
126 return t < 0.5f
127 ? -(std::pow(2.f, 20.f * t - 10.f) * std::sin((20.f * t - 11.125f) * c5)) / 2.f
128 : (std::pow(2.f, -20.f * t + 10.f) * std::sin((20.f * t - 11.125f) * c5)) / 2.f + 1.f;
129 }
130
131 // ── Bounce ──────────────────────────────────────────────────────────
132 static float EaseOutBounce(float t) {
133 const float n1 = 7.5625f, d1 = 2.75f;
134 if (t < 1.f / d1) return n1 * t * t;
135 else if (t < 2.f / d1) { t -= 1.5f / d1; return n1 * t * t + 0.75f; }
136 else if (t < 2.5f / d1){ t -= 2.25f / d1; return n1 * t * t + 0.9375f; }
137 else { t -= 2.625f/ d1; return n1 * t * t + 0.984375f; }
138 }
139 static float EaseInBounce(float t) { return 1.f - EaseOutBounce(1.f - t); }
140 static float EaseInOutBounce(float t) {
141 return t < 0.5f
142 ? (1.f - EaseOutBounce(1.f - 2.f * t)) / 2.f
143 : (1.f + EaseOutBounce(2.f * t - 1.f)) / 2.f;
144 }
145 };
146
147} // namespace ml
148
149#endif // MALENA_EASING_H
Definition Animate.h:25
Easing curves for animation, as pure functions of normalized time.
Definition Easing.h:33
static float EaseOutBack(float t)
Definition Easing.h:98
static float EaseOutCirc(float t)
Definition Easing.h:86
static float EaseOutExpo(float t)
Definition Easing.h:76
static float EaseInSine(float t)
Definition Easing.h:70
static float EaseOutSine(float t)
Definition Easing.h:71
static float EaseInOutQuint(float t)
Definition Easing.h:65
static float EaseInQuad(float t)
Definition Easing.h:42
static float EaseOutElastic(float t)
Definition Easing.h:116
static float Linear(float t)
Definition Easing.h:39
static float EaseInOutExpo(float t)
Definition Easing.h:77
static float EaseOutQuint(float t)
Definition Easing.h:64
static constexpr float kPi
Definition Easing.h:36
static float EaseInOutCubic(float t)
Definition Easing.h:51
static float EaseInBounce(float t)
Definition Easing.h:139
static float EaseInOutBack(float t)
Definition Easing.h:102
static float EaseOutQuad(float t)
Definition Easing.h:43
static float EaseInBack(float t)
Definition Easing.h:94
static float EaseInExpo(float t)
Definition Easing.h:75
static float EaseOutCubic(float t)
Definition Easing.h:50
static float EaseInQuart(float t)
Definition Easing.h:56
static float EaseInCirc(float t)
Definition Easing.h:85
static float EaseInElastic(float t)
Definition Easing.h:110
static float EaseInOutQuad(float t)
Definition Easing.h:44
float(*)(float) Fn
Definition Easing.h:34
static float EaseInCubic(float t)
Definition Easing.h:49
static float EaseOutBounce(float t)
Definition Easing.h:132
static float EaseInOutElastic(float t)
Definition Easing.h:122
static float EaseInOutBounce(float t)
Definition Easing.h:140
static float EaseInOutQuart(float t)
Definition Easing.h:58
static float EaseInOutCirc(float t)
Definition Easing.h:87
static float EaseInQuint(float t)
Definition Easing.h:63
static float EaseInOutSine(float t)
Definition Easing.h:72
static float EaseOutQuart(float t)
Definition Easing.h:57