From 220ec0791d2e6c82a97b5ad2d4d18bcda5cee39a Mon Sep 17 00:00:00 2001 From: DashyFox Date: Mon, 4 Mar 2024 09:23:57 +0300 Subject: [PATCH] Initial commit --- .gitattributes | 2 + Easing.h | 166 +++++++++++++++++++++++++++++++++++++++++++++++++ Tween.h | 104 +++++++++++++++++++++++++++++++ 3 files changed, 272 insertions(+) create mode 100644 .gitattributes create mode 100644 Easing.h create mode 100644 Tween.h diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/Easing.h b/Easing.h new file mode 100644 index 0000000..e794919 --- /dev/null +++ b/Easing.h @@ -0,0 +1,166 @@ +#pragma once +namespace EasingFunc { + float easeInSine(float t) { + return sin(1.5707963 * t); + } + + float easeOutSine(float t) { + return 1 + sin(1.5707963 * (--t)); + } + + float easeInOutSine(float t) { + return 0.5 * (1 + sin(3.1415926 * (t - 0.5))); + } + + float easeInQuad(float t) { + return t * t; + } + + float easeOutQuad(float t) { + return t * (2 - t); + } + + float easeInOutQuad(float t) { + return t < 0.5 ? 2 * t * t : t * (4 - 2 * t) - 1; + } + + float easeInCubic(float t) { + return t * t * t; + } + + float easeOutCubic(float t) { + return 1 + (--t) * t * t; + } + + float easeInOutCubic(float t) { + return t < 0.5 ? 4 * t * t * t : 1 + (--t) * (2 * (--t)) * (2 * t); + } + + float easeInQuart(float t) { + t *= t; + return t * t; + } + + float easeOutQuart(float t) { + t = (--t) * t; + return 1 - t * t; + } + + float easeInOutQuart(float t) { + if (t < 0.5) { + t *= t; + return 8 * t * t; + } else { + t = (--t) * t; + return 1 - 8 * t * t; + } + } + + float easeInQuint(float t) { + float t2 = t * t; + return t * t2 * t2; + } + + float easeOutQuint(float t) { + float t2 = (--t) * t; + return 1 + t * t2 * t2; + } + + float easeInOutQuint(float t) { + float t2; + if (t < 0.5) { + t2 = t * t; + return 16 * t * t2 * t2; + } else { + t2 = (--t) * t; + return 1 + 16 * t * t2 * t2; + } + } + + float easeInExpo(float t) { + return (pow(2, 8 * t) - 1) / 255; + } + + float easeOutExpo(float t) { + return 1 - pow(2, -8 * t); + } + + float easeInOutExpo(float t) { + if (t < 0.5) { + return (pow(2, 16 * t) - 1) / 510; + } else { + return 1 - 0.5 * pow(2, -16 * (t - 0.5)); + } + } + + float easeInCirc(float t) { + return 1 - sqrt(1 - t); + } + + float easeOutCirc(float t) { + return sqrt(t); + } + + float easeInOutCirc(float t) { + if (t < 0.5) { + return (1 - sqrt(1 - 2 * t)) * 0.5; + } else { + return (1 + sqrt(2 * t - 1)) * 0.5; + } + } + + float easeInBack(float t) { + return t * t * (2.70158 * t - 1.70158); + } + + float easeOutBack(float t) { + return 1 + (--t) * t * (2.70158 * t + 1.70158); + } + + float easeInOutBack(float t) { + if (t < 0.5) { + return t * t * (7 * t - 2.5) * 2; + } else { + return 1 + (--t) * t * 2 * (7 * t + 2.5); + } + } + + float easeInElastic(float t) { + float t2 = t * t; + return t2 * t2 * sin(t * PI * 4.5); + } + + float easeOutElastic(float t) { + float t2 = (t - 1) * (t - 1); + return 1 - t2 * t2 * cos(t * PI * 4.5); + } + + float easeInOutElastic(float t) { + float t2; + if (t < 0.45) { + t2 = t * t; + return 8 * t2 * t2 * sin(t * PI * 9); + } else if (t < 0.55) { + return 0.5 + 0.75 * sin(t * PI * 4); + } else { + t2 = (t - 1) * (t - 1); + return 1 - 8 * t2 * t2 * sin(t * PI * 9); + } + } + + float easeInBounce(float t) { + return pow(2, 6 * (t - 1)) * abs(sin(t * PI * 3.5)); + } + + float easeOutBounce(float t) { + return 1 - pow(2, -6 * t) * abs(cos(t * PI * 3.5)); + } + + float easeInOutBounce(float t) { + if (t < 0.5) { + return 8 * pow(2, 8 * (t - 1)) * abs(sin(t * PI * 7)); + } else { + return 1 - 8 * pow(2, -8 * t) * abs(sin(t * PI * 7)); + } + } +} \ No newline at end of file diff --git a/Tween.h b/Tween.h new file mode 100644 index 0000000..c4cf46f --- /dev/null +++ b/Tween.h @@ -0,0 +1,104 @@ +#pragma once +#include "Easing.h" +// namespace TweenNameSpace { +typedef float(*eFunc)(float); +// }; +// using namespace TweenNameSpace; + +typedef float(*eFunc)(float); +class Tween { + + /////// +private: + static inline Tween* head = nullptr; + static inline Tween* last = nullptr; + static inline uint32_t frameRateTimer; + Tween* next; +public: + static void tick() { + Tween* current = Tween::head; + while (current != nullptr) { + current->update(); + current = current->next; + } + } + + Tween(uint16_t fps) { + frameTime = 1000 / fps; + if (Tween::head == nullptr) { + Tween::head = this; + } + if (last != nullptr) { + last->next = this; + } + last = this; + } + /////// + +private: + uint16_t frameTime; + float dt; + uint32_t oldMillis; + static float lerp(float a, float b, float t) { + return a + (b - a) * t; + } + + float from; + float to; + float duration; + eFunc easing = nullptr; + float progress; + bool isPlayingF; + +public: + void update() { + if (!isPlayingF || easing == nullptr) return; + if (millis() - frameRateTimer > frameTime) { + frameRateTimer = millis(); + dtTick(); + if (current == to || progress >= duration) { stop(); return; } + current = clamp(Tween::lerp(from, to, easing(progress / duration)), from, to); + progress = progress + Tween::dt; + } + } + float current; + + void dtTick() { + uint32_t loopStartTime = millis(); + dt = (loopStartTime - oldMillis) / 1000.0; + oldMillis = loopStartTime; + } + + void start(float from, float to, uint16_t duration, eFunc easing) { + if (from == to) { return; } + this->from = from; + this->to = to; + this->duration = duration / 1000.0; + this->easing = easing; + resetToStart(); + dtTick(); + isPlayingF = true; + } + + void resetToStart() { + progress = 0; + } + void stop() { + isPlayingF = false; + } + + bool isPlaying() { + return isPlayingF; + } +private: + int clamp(int value, int a, int b) { + if (a > b) { + a ^= b; + b ^= a; + a ^= b; + } + if (value < a) return a; + else if (value > b) return b; + else return value; + } +}; \ No newline at end of file