diff --git a/Tween.h b/Tween.h index 54b4fd1..5b2fa86 100644 --- a/Tween.h +++ b/Tween.h @@ -11,22 +11,18 @@ namespace EasingFunc { // typedef float (*eFunc)(float); // тип easing-функции, как у Вас - // Статические данные для обёртки - static const TimeWarp* g_warp = nullptr; - static eFunc g_baseEasing = nullptr; - // Обёртка с модификатором времени (вызывается Tween'ом) - inline float _easingWithWarp(float t) { - if (!g_warp || !g_baseEasing) return t; - float warpedT = g_warp->apply(t); - return g_baseEasing(warpedT); + inline float _easingWithWarp(float t, const TimeWarp* warp, eFunc baseEasing) { + if (!warp || !baseEasing) return t; + float warpedT = warp->apply(t); + return baseEasing(warpedT); } - // Установить текущий модификатор времени - inline eFunc withTimeWarp(eFunc easing, const TimeWarp& warp) { - g_warp = &warp; - g_baseEasing = easing; - return _easingWithWarp; + // Создать обёртку с модификатором времени + inline std::function withTimeWarp(eFunc easing, const TimeWarp& warp) { + return [easing, &warp](float t) -> float { + return _easingWithWarp(t, &warp, easing); + }; } }; // namespace EasingFunc @@ -91,6 +87,7 @@ private: float to; float duration; EasingFunc::eFunc easing = nullptr; + std::function easingFunc = nullptr; float progress; bool isPlayingF; bool triggerLastTick = false; // Флаг последнего тика @@ -121,7 +118,13 @@ public: progress = constrain(progress + dt, 0, duration); float normProgress = constrain(progress / duration, 0, 1); - current = Tween::lerp(from, to, easing(normProgress)); + if (easingFunc) { + current = Tween::lerp(from, to, easingFunc(normProgress)); + } else if (easing) { + current = Tween::lerp(from, to, easing(normProgress)); + } else { + current = Tween::lerp(from, to, normProgress); + } if (progress >= duration) { current = to; @@ -142,6 +145,23 @@ public: void start(float from_, float to_, uint16_t durationMs, EasingFunc::eFunc easing_ = nullptr) { // если easing не задан, используем линейную easing = (easing_ != nullptr) ? easing_ : EasingFunc::easeLinear; + easingFunc = nullptr; // сбрасываем функцию с TimeWarp + + from = from_; + to = to_; + duration = durationMs / 1000.0f; + progress = 0; + current = from; + uint32_t now = millis(); + oldMillis = now; + frameRateTimer = now; + isPlayingF = true; + triggerLastTick = false; + } + + void start(float from_, float to_, uint16_t durationMs, std::function easingFunc_) { + easing = nullptr; // сбрасываем обычную функцию + easingFunc = easingFunc_; from = from_; to = to_; @@ -221,7 +241,8 @@ class AnimationChain : public TweenListener { FromFunc fromFunc = nullptr; float to; uint16_t duration; // мс - EasingFunc::eFunc easing; + EasingFunc::eFunc easing = nullptr; + std::function easingFunc = nullptr; }; private: @@ -233,7 +254,11 @@ class AnimationChain : public TweenListener { void launchCurrent() { const Anim& a = animations[currentIndex]; - tween.start(a.fromFunc ? a.fromFunc() : a.from, a.to, a.duration, a.easing); + if (a.easingFunc) { + tween.start(a.fromFunc ? a.fromFunc() : a.from, a.to, a.duration, a.easingFunc); + } else { + tween.start(a.fromFunc ? a.fromFunc() : a.from, a.to, a.duration, a.easing); + } } public: @@ -248,10 +273,16 @@ class AnimationChain : public TweenListener { //------------------------------------------------------------------ void addAnim(float from, float to, uint16_t duration, EasingFunc::eFunc easing = nullptr) { - animations.push_back({from, {}, to, duration, easing}); + animations.push_back({from, {}, to, duration, easing, nullptr}); } void addAnim(FromFunc fromF, float to, uint16_t duration, EasingFunc::eFunc easing = nullptr) { - animations.push_back({0, fromF, to, duration, easing}); + animations.push_back({0, fromF, to, duration, easing, nullptr}); + } + void addAnim(float from, float to, uint16_t duration, std::function easingFunc) { + animations.push_back({from, {}, to, duration, nullptr, easingFunc}); + } + void addAnim(FromFunc fromF, float to, uint16_t duration, std::function easingFunc) { + animations.push_back({0, fromF, to, duration, nullptr, easingFunc}); } void clear() { animations.clear(); }