Work-In-Progress tween code.

This commit is contained in:
2025-02-10 14:45:59 -05:00
parent fc65e9d229
commit 251daa4070
4 changed files with 274 additions and 16 deletions

View File

@@ -64,32 +64,52 @@ namespace JUI {
void TweenPositionTo(const UDim2& goal)
{
std::function<void(float)> updateTillGoalReached = [this, goal] (float elapsed)
UDim2 start_position = this->Position();
float progress = 0;
Tween t;
std::function<void(float)> updateTillGoalReached = [this, t, start_position, progress, goal] (float elapsed) mutable
{
auto pos = this->Position();
UDim2 current_pos = this->Position();
// TODO: Implement UDim equality operators (with epsilon)
// TODO: Implement Easing Functions
// TODO: Implement UDim::Lerp
// TODO: Implement UDim2::Lerp
if (pos.X.Pixels == goal.X.Pixels && pos.Y.Pixels == goal.Y.Pixels && pos.X.Scale == goal.X.Scale && pos.Y.Scale == goal.Y.Scale)
if (current_pos.X.Pixels == goal.X.Pixels && current_pos.Y.Pixels == goal.Y.Pixels && current_pos.X.Scale == goal.X.Scale && current_pos.Y.Scale == goal.Y.Scale)
{
// Reached Goal, Complete this tween.
return;
}
float lerp_factor = 1.f/1000.f;
pos.X.Pixels = Math::Lerp(pos.X.Pixels, goal.X.Pixels, lerp_factor);
pos.Y.Pixels = Math::Lerp(pos.Y.Pixels, goal.Y.Pixels, lerp_factor);
pos.X.Scale = Math::Lerp(pos.X.Scale, goal.X.Scale, lerp_factor);
pos.Y.Scale = Math::Lerp(pos.Y.Scale, goal.Y.Scale, lerp_factor);
progress += elapsed;
if (progress >= 1.f)
{
progress = 1.f;
t.Completed.Invoke();
return;
}
float modified_progress = EasingFunctions::EaseOutElastic(progress);
UDim2 pos = current_pos;
pos.X.Pixels = Math::Lerp(start_position.X.Pixels, goal.X.Pixels, modified_progress);
pos.Y.Pixels = Math::Lerp(start_position.Y.Pixels, goal.Y.Pixels, modified_progress);
pos.X.Scale = Math::Lerp(start_position.X.Scale, goal.X.Scale, modified_progress);
pos.Y.Scale = Math::Lerp(start_position.Y.Scale, goal.Y.Scale, modified_progress);
Position(pos);
};
Tween t;
t.tick = updateTillGoalReached;
t.tick_func = updateTillGoalReached;
tweens.push_back(t);

View File

@@ -1,15 +1,104 @@
#include <functional>
#pragma once
#include <functional>
#include "Event.h"
namespace JUI
{
namespace EasingFunctions
{
float EaseInOutLinear(float t);
/// Speed is determined by a sine wave for gentle easing motion.
float EaseInSine(float t);
/// Speed is determined by a sine wave for gentle easing motion.
float EaseOutSine(float t);
/// Speed is determined by a sine wave for gentle easing motion.
float EaseInOutSine(float t);
/// Similar to Sine but with a slightly sharper curve based on quadratic interpolation.
float EaseInQuad(float t);
/// Similar to Sine but with a slightly sharper curve based on quadratic interpolation.
float EaseOutQuad(float t);
/// Similar to Sine but with a slightly sharper curve based on quadratic interpolation.
float EaseInOutQuad(float t);
/// Similar to Quad but with a slightly sharper curve based on cubic interpolation.
float EaseInCubic(float t);
/// Similar to Quad but with a slightly sharper curve based on cubic interpolation.
float EaseOutCubic(float t);
/// Similar to Quad but with a slightly sharper curve based on cubic interpolation.
float EaseInOutCubic(float t);
/// Similar to Cubic but with an even sharper curve based on quartic interpolation.
float EaseInQuart(float t);
/// Similar to Cubic but with an even sharper curve based on quartic interpolation.
float EaseOutQuart(float t);
/// Similar to Cubic but with an even sharper curve based on quartic interpolation.
float EaseInOutQuart(float t);
/// Similar to Quart but with an even sharper curve based on quintic interpolation.
float EaseInQuint(float t);
/// Similar to Quart but with an even sharper curve based on quintic interpolation.
float EaseOutQuint(float t);
/// Similar to Quart but with an even sharper curve based on quintic interpolation.
float EaseInOutQuint(float t);
/// The sharpest curve based on exponential interpolation.
float EaseInExpo(float t);
/// The sharpest curve based on exponential interpolation.
float EaseOutExpo(float t);
/// The sharpest curve based on exponential interpolation.
float EaseInOutExpo(float t);
/// Follows a circular arc, such that acceleration is more sudden and deceleration more gradual versus Quint or Exponential.
float EaseInCirc(float t);
/// Follows a circular arc, such that acceleration is more sudden and deceleration more gradual versus Quint or Exponential.
float EaseOutCirc(float t);
/// Follows a circular arc, such that acceleration is more sudden and deceleration more gradual versus Quint or Exponential.
float EaseInOutCirc(float t);
/// Slightly overshoots the target, then backs into place.
float EaseInBack(float t);
/// Slightly overshoots the target, then backs into place.
float EaseOutBack(float t);
/// Slightly overshoots the target, then backs into place.
float EaseInOutBack(float t);
float EaseInElastic(float t);
float EaseOutElastic(float t);
float EaseInOutElastic(float t);
float EaseInBounce(float t);
float EaseOutBounce(float t);
float EaseInOutBounce(float t);
}
/// A class that represents an animation-in-action.
class Tween {
public:
Event<> Completed;
void Update(float elapsed)
{
}
std::function<float(float)> easing_func;
std::function<void(float)> tick_func;
/// Duration of the tween, in seconds.
float time;
/// Time of delay until the tween begins, in seconds.
float delay_time;
/// Number of times the tween repeats. -1 indicates indefinite repetition.
int repeat_count;
/// Whether or not the tween interpolates in reverse once the initial tween completes.
bool reverses;
std::function<void(float)> tick;
float lifetime = 5;
float progress = 0;
bool alive = true;
@@ -20,6 +109,6 @@ namespace JUI
void Resume() { paused = false; }
bool Paused() const { return paused; }
bool Completed() const { return completed; }
bool HasCompleted() const { return completed; }
};
}

View File

@@ -286,6 +286,11 @@ public:
int main()
{
for (float i = 0; i < 1; i += 0.01f)
{
std::cout << JUI::EasingFunctions::EaseInSine(i) << std::endl;
}
using namespace ReWindow;
// TODO: Find out new jlog api for silencing specific loggers.

View File

@@ -1,7 +1,151 @@
#include <JUI/Tween.hpp>
#include <J3ML/J3ML.hpp>
namespace JUI
{
using namespace J3ML;
float EasingFunctions::EaseInSine(float t) { return Math::Sin(Math::PiOverTwo * t); }
float EasingFunctions::EaseOutSine(float t) { return 1 + Math::Sin(Math::PiOverTwo * (--t)); }
float EasingFunctions::EaseInOutSine(float t) { return 0.5f * (1 + Math::Sin(Math::Pi * (t - 0.5f))); }
float EasingFunctions::EaseInQuad(float t) { return t * t;}
float EasingFunctions::EaseOutQuad(float t) { return t * (2.f - t);}
float EasingFunctions::EaseInOutQuad(float t) { return t < 0.5f ? 2.f * t * t : t * (4.f - 2.f * t) - 1; }
float EasingFunctions::EaseInCubic(float t) { return t * t * t;}
float EasingFunctions::EaseOutCubic(float t) { return 1.f + (--t) * t * t; }
float EasingFunctions::EaseInOutCubic(float t) { return t < 0.5f ? 4.f * t * t * t : 1 + (--t) * (2 * (--t)) * (2 * t); }
float EasingFunctions::EaseInQuart(float t) {
t *= t;
return t * t;
}
float EasingFunctions::EaseOutQuart(float t) {
t = (--t) * t;
return 1.f - t * t;
}
float EasingFunctions::EaseInOutQuart(float t) {
if (t < 0.5f) {
t *= t;
return 8 * t * t;
} else {
t = (--t) * t;
return 1 - 8 * t * t;
}
}
float EasingFunctions::EaseInQuint(float t) {
float t2 = t * t;
return t * t2 * t2;
}
float EasingFunctions::EaseOutQuint(float t) {
float t2 = (--t) * t;
return 1 + t * t2 * t2;
}
float EasingFunctions::EaseInOutQuint(float t) {
float t2;
if ( t < 0.5f) {
t2 = t * t;
return 16 * t * t2 * t2;
} else {
t2 = (--t) * t;
return 1 + 16 * t * t2 * t2;
}
}
float EasingFunctions::EaseInExpo(float t) {
return (Math::Pow(2, 8*t) - 1) / 255;
}
float EasingFunctions::EaseOutExpo(float t) {
return 1 - Math::Pow(2, -8*t);
}
float EasingFunctions::EaseInOutExpo(float t) {
if (t < 0.5f) {
return (Math::Pow(2, 16 * t) - 1) / 510;
} else {
return 1 - 0.5f * Math::Pow(2, -16 * (t - 0.5f));
}
}
float EasingFunctions::EaseInCirc(float t) {
return 1 - Math::Sqrt(1 - t);
}
float EasingFunctions::EaseOutCirc(float t) {
return Math::Sqrt(t);
}
float EasingFunctions::EaseInOutCirc(float t) {
if (t < 0.5f) {
return (1 - Math::Sqrt(1 - 2 * t)) * 0.5f;
} else {
return (1 + Math::Sqrt(2 * t - 1)) * 0.5f;
}
}
float EasingFunctions::EaseInBack(float t) { return t * t * (2.70158f * t - 1.70158f); }
float EasingFunctions::EaseOutBack(float t) { return 1 + (--t) * t * (2.70158 * t + 1.70158); }
float EasingFunctions::EaseInOutBack(float t) {
if (t < 0.5f) {
return t * t * (7 * t - 2.5f) * 2.f;
} else {
return 1 + (--t) * t * 2 * (7 * t + 2.5f);
}
}
float EasingFunctions::EaseInElastic(float t) {
float t2 = t * t;
return t2 * t2 * Math::Sin(t * Math::Pi * 4.5f);
}
float EasingFunctions::EaseOutElastic(float t) {
float t2 = (t - 1) * (t - 1);
return 1 - t2 * t2 * Math::Cos(t * Math::Pi * 4.5f);
}
float EasingFunctions::EaseInOutElastic(float t) {
float t2;
if (t < 0.45f) {
t2 = t * t;
return 8 * t2 * t2 * Math::Sin(t * Math::Pi * 9);
} else if (t < 0.55f) {
return 0.5f + 0.75f * Math::Sin(t * Math::Pi * 4);
} else {
t2 = (t - 1) * (t - 1);
return 1 - 8 * t2 * t2 * Math::Sin(t * Math::Pi * 9);
}
}
float EasingFunctions::EaseInBounce(float t) {
return Math::Pow(2, 6 * (t - 1)) * Math::Abs(Math::Sin(t * Math::Pi * 3.5f));
}
float EasingFunctions::EaseOutBounce(float t) {
return 1 - Math::Pow(2, -6 * t ) * Math::Abs(Math::Cos(t * Math::Pi * 3.5f));
}
float EasingFunctions::EaseInOutBounce(float t) {
if (t < 0.5f) {
return 8 * Math::Pow(2, 8 * (t - 1)) * Math::Abs(Math::Sin(t * Math::Pi));
} else {
return 1 - 8 * Math::Pow(2, -8 * t) * Math::Abs(Math::Sin(t * Math::Pi * 7));
}
}
float EasingFunctions::EaseInOutLinear(float t) { return t;}
}