Skip to content

Commit

Permalink
rewrite tween
Browse files Browse the repository at this point in the history
  • Loading branch information
actboy168 committed Jan 20, 2024
1 parent 0a70737 commit 0b9a627
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 151 deletions.
2 changes: 1 addition & 1 deletion pkg/ant.rmlui/src/core/ElementAnimation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Property ElementInterpolate::Update(float t0, float t1, float t, const Tween& tw
if (t1 - t0 > eps)
alpha = (t - t0) / (t1 - t0);
alpha = std::clamp(alpha, 0.0f, 1.0f);
alpha = tween.get(alpha);
alpha = TweenGet(tween, alpha);
if (alpha > 1.f) alpha = 1.f;
if (alpha < 0.f) alpha = 0.f;
return PropertyVisit(InterpolateVisitor { id, p0, p1, alpha }, p0, p1);
Expand Down
173 changes: 68 additions & 105 deletions pkg/ant.rmlui/src/core/Tween.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <core/Tween.h>
#include <utility>
#include <math.h>
#include <bee/nonstd/to_underlying.h>
#include <bee/nonstd/unreachable.h>

#include <version>
Expand All @@ -13,8 +14,6 @@ static constexpr float const_pi = static_cast<float>(3.141592653589793);

namespace Rml {

namespace TweenFunctions {

// Tweening functions below.
// Partly based on http://libclaw.sourceforge.net/tweeners.html

Expand Down Expand Up @@ -76,127 +75,91 @@ static float sine(float t) {
return 1.f - cosf(t * const_pi * 0.5f);
}

}
enum class Direction : uint8_t {
In = 0,
Out,
InOut
};

static float TweenIn(Tween::Type type, float t) {
using namespace TweenFunctions;
switch (type) {
case Tween::Type::Back:
return back(t);
case Tween::Type::Bounce:
return bounce(t);
case Tween::Type::Circular:
return circular(t);
case Tween::Type::Cubic:
return cubic(t);
case Tween::Type::Elastic:
return elastic(t);
case Tween::Type::Exponential:
return exponential(t);
case Tween::Type::Linear:
return linear(t);
case Tween::Type::Quadratic:
return quadratic(t);
case Tween::Type::Quartic:
return quartic(t);
case Tween::Type::Quintic:
return quintic(t);
case Tween::Type::Sine:
return sine(t);
default:
std::unreachable();
}
static float TweenIn(float t) {
return t;
}

static float TweenOut(Tween::Type type, float t) {
return 1.0f - TweenIn(type, 1.0f - t);
static float TweenOut(float t) {
return 1.0f - TweenIn(1.0f - t);
}

static float TweenInOut(Tween::Type type, float t) {
static float TweenInOut(float t) {
if (t < 0.5f)
return TweenIn(type, 2.0f * t) * 0.5f;
return TweenIn(2.0f * t) * 0.5f;
else
return 0.5f + TweenOut(type, 2.0f * t - 1.0f) * 0.5f;
}

static std::string TweenToString(Tween::Type type) {
switch (type) {
case Tween::Type::Back:
return "back";
case Tween::Type::Bounce:
return "bounce";
case Tween::Type::Circular:
return "circular";
case Tween::Type::Cubic:
return "cubic";
case Tween::Type::Elastic:
return "elastic";
case Tween::Type::Exponential:
return "exponential";
case Tween::Type::Linear:
return "linear";
case Tween::Type::Quadratic:
return "quadratic";
case Tween::Type::Quartic:
return "quartic";
case Tween::Type::Quintic:
return "quintic";
case Tween::Type::Sine:
return "sine";
default:
std::unreachable();
}
return 0.5f + TweenOut(2.0f * t - 1.0f) * 0.5f;
}

static std::string TweenToString(Tween::Direction direction) {
switch (direction) {
case Tween::Direction::In:
return "-in";
case Tween::Direction::Out:
return "-out";
case Tween::Direction::InOut:
return "-in-out";
default:
std::unreachable();
}
}

static Tween::Type TweenGetType(uint8_t v) {
return (Tween::Type)((v >> 4) & 0xF);
}

static Tween::Direction TweenGetDirection(uint8_t v) {
return (Tween::Direction)(v & 0xF);
}

static uint8_t TweenMake(Tween::Type type, Tween::Direction direction) {
return (uint8_t(type) << 4) | uint8_t(direction);
}

Tween::Tween()
: v(0)
{ }

Tween::Tween(Type type, Direction direction)
: v(TweenMake(type, direction))
{ }

float Tween::get(float t) const {
switch (TweenGetDirection(v)) {
static float TweenGet(Direction dir, float t) {
switch (dir) {
case Direction::In:
return TweenIn(TweenGetType(v), t);
return TweenIn(t);
case Direction::Out:
return TweenOut(TweenGetType(v), t);
return TweenOut(t);
case Direction::InOut:
return TweenInOut(TweenGetType(v), t);
return TweenInOut(t);
default:
std::unreachable();
}
return t;
}

std::string Tween::ToString() const {
return TweenToString(TweenGetType(v)) + TweenToString(TweenGetDirection(v));
float TweenGet(Tween tween, float t) {
Direction dir = (Direction)(std::to_underlying(tween) % 3);
switch (tween) {
case Tween::LinearIn:
case Tween::LinearOut:
case Tween::LinearInOut:
return TweenGet(dir, linear(t));
case Tween::BackIn:
case Tween::BackOut:
case Tween::BackInOut:
return TweenGet(dir, back(t));
case Tween::BounceIn:
case Tween::BounceOut:
case Tween::BounceInOut:
return TweenGet(dir, bounce(t));
case Tween::CircularIn:
case Tween::CircularOut:
case Tween::CircularInOut:
return TweenGet(dir, circular(t));
case Tween::CubicIn:
case Tween::CubicOut:
case Tween::CubicInOut:
return TweenGet(dir, cubic(t));
case Tween::ElasticIn:
case Tween::ElasticOut:
case Tween::ElasticInOut:
return TweenGet(dir, elastic(t));
case Tween::ExponentialIn:
case Tween::ExponentialOut:
case Tween::ExponentialInOut:
return TweenGet(dir, exponential(t));
case Tween::QuadraticIn:
case Tween::QuadraticOut:
case Tween::QuadraticInOut:
return TweenGet(dir, quadratic(t));
case Tween::QuarticIn:
case Tween::QuarticOut:
case Tween::QuarticInOut:
return TweenGet(dir, quartic(t));
case Tween::QuinticIn:
case Tween::QuinticOut:
case Tween::QuinticInOut:
return TweenGet(dir, quintic(t));
case Tween::SineIn:
case Tween::SineOut:
case Tween::SineInOut:
return TweenGet(dir, sine(t));
default:
std::unreachable();
}
}

}
48 changes: 36 additions & 12 deletions pkg/ant.rmlui/src/core/Tween.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,42 @@

namespace Rml {

class Tween {
public:
enum class Type : uint8_t { Linear = 0, Back, Bounce, Circular, Cubic, Elastic, Exponential, Quadratic, Quartic, Quintic, Sine };
enum class Direction : uint8_t { In = 0, Out, InOut };

Tween();
Tween(Type type, Direction direction);
float get(float t) const;
std::string ToString() const;

private:
uint8_t v;
enum class Tween : uint8_t {
LinearIn,
LinearOut,
LinearInOut,
BackIn,
BackOut,
BackInOut,
BounceIn,
BounceOut,
BounceInOut,
CircularIn,
CircularOut,
CircularInOut,
CubicIn,
CubicOut,
CubicInOut,
ElasticIn,
ElasticOut,
ElasticInOut,
ExponentialIn,
ExponentialOut,
ExponentialInOut,
QuadraticIn,
QuadraticOut,
QuadraticInOut,
QuarticIn,
QuarticOut,
QuarticInOut,
QuinticIn,
QuinticOut,
QuinticInOut,
SineIn,
SineOut,
SineInOut,
};

float TweenGet(Tween tween, float t);

}
66 changes: 33 additions & 33 deletions pkg/ant.rmlui/src/css/PropertyParserAnimation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,39 +24,39 @@ static const std::unordered_map<std::string, Keyword> keywords = {
{"all", {Keyword::ALL}},
{"alternate", {Keyword::ALTERNATE}},
{"infinite", {Keyword::INFINITE}},
{"back-in", {Keyword::TWEEN, {Tween::Type::Back, Tween::Direction::In}}},
{"back-out", {Keyword::TWEEN, {Tween::Type::Back, Tween::Direction::Out}}},
{"back-in-out", {Keyword::TWEEN, {Tween::Type::Back, Tween::Direction::InOut}}},
{"bounce-in", {Keyword::TWEEN, {Tween::Type::Bounce, Tween::Direction::In}}},
{"bounce-out", {Keyword::TWEEN, {Tween::Type::Bounce, Tween::Direction::Out}}},
{"bounce-in-out", {Keyword::TWEEN, {Tween::Type::Bounce, Tween::Direction::InOut}}},
{"circular-in", {Keyword::TWEEN, {Tween::Type::Circular, Tween::Direction::In}}},
{"circular-out", {Keyword::TWEEN, {Tween::Type::Circular, Tween::Direction::Out}}},
{"circular-in-out", {Keyword::TWEEN, {Tween::Type::Circular, Tween::Direction::InOut}}},
{"cubic-in", {Keyword::TWEEN, {Tween::Type::Cubic, Tween::Direction::In}}},
{"cubic-out", {Keyword::TWEEN, {Tween::Type::Cubic, Tween::Direction::Out}}},
{"cubic-in-out", {Keyword::TWEEN, {Tween::Type::Cubic, Tween::Direction::InOut}}},
{"elastic-in", {Keyword::TWEEN, {Tween::Type::Elastic, Tween::Direction::In}}},
{"elastic-out", {Keyword::TWEEN, {Tween::Type::Elastic, Tween::Direction::Out}}},
{"elastic-in-out", {Keyword::TWEEN, {Tween::Type::Elastic, Tween::Direction::InOut}}},
{"exponential-in", {Keyword::TWEEN, {Tween::Type::Exponential, Tween::Direction::In}}},
{"exponential-out", {Keyword::TWEEN, {Tween::Type::Exponential, Tween::Direction::Out}}},
{"exponential-in-out", {Keyword::TWEEN, {Tween::Type::Exponential, Tween::Direction::InOut}}},
{"linear-in", {Keyword::TWEEN, {Tween::Type::Linear, Tween::Direction::In}}},
{"linear-out", {Keyword::TWEEN, {Tween::Type::Linear, Tween::Direction::Out}}},
{"linear-in-out", {Keyword::TWEEN, {Tween::Type::Linear, Tween::Direction::InOut}}},
{"quadratic-in", {Keyword::TWEEN, {Tween::Type::Quadratic, Tween::Direction::In}}},
{"quadratic-out", {Keyword::TWEEN, {Tween::Type::Quadratic, Tween::Direction::Out}}},
{"quadratic-in-out", {Keyword::TWEEN, {Tween::Type::Quadratic, Tween::Direction::InOut}}},
{"quartic-in", {Keyword::TWEEN, {Tween::Type::Quartic, Tween::Direction::In}}},
{"quartic-out", {Keyword::TWEEN, {Tween::Type::Quartic, Tween::Direction::Out}}},
{"quartic-in-out", {Keyword::TWEEN, {Tween::Type::Quartic, Tween::Direction::InOut}}},
{"quintic-in", {Keyword::TWEEN, {Tween::Type::Quintic, Tween::Direction::In}}},
{"quintic-out", {Keyword::TWEEN, {Tween::Type::Quintic, Tween::Direction::Out}}},
{"quintic-in-out", {Keyword::TWEEN, {Tween::Type::Quintic, Tween::Direction::InOut}}},
{"sine-in", {Keyword::TWEEN, {Tween::Type::Sine, Tween::Direction::In}}},
{"sine-out", {Keyword::TWEEN, {Tween::Type::Sine, Tween::Direction::Out}}},
{"sine-in-out", {Keyword::TWEEN, {Tween::Type::Sine, Tween::Direction::InOut}}},
{"back-in", {Keyword::TWEEN, Tween::BackIn}},
{"back-out", {Keyword::TWEEN, Tween::BackOut}},
{"back-in-out", {Keyword::TWEEN, Tween::BackInOut}},
{"bounce-in", {Keyword::TWEEN, Tween::BounceIn}},
{"bounce-out", {Keyword::TWEEN, Tween::BounceOut}},
{"bounce-in-out", {Keyword::TWEEN, Tween::BounceInOut}},
{"circular-in", {Keyword::TWEEN, Tween::CircularIn}},
{"circular-out", {Keyword::TWEEN, Tween::CircularOut}},
{"circular-in-out", {Keyword::TWEEN, Tween::CircularInOut}},
{"cubic-in", {Keyword::TWEEN, Tween::CubicIn}},
{"cubic-out", {Keyword::TWEEN, Tween::CubicOut}},
{"cubic-in-out", {Keyword::TWEEN, Tween::CubicInOut}},
{"elastic-in", {Keyword::TWEEN, Tween::ElasticIn}},
{"elastic-out", {Keyword::TWEEN, Tween::ElasticOut}},
{"elastic-in-out", {Keyword::TWEEN, Tween::ElasticInOut}},
{"exponential-in", {Keyword::TWEEN, Tween::ExponentialIn}},
{"exponential-out", {Keyword::TWEEN, Tween::ExponentialOut}},
{"exponential-in-out", {Keyword::TWEEN, Tween::ExponentialInOut}},
{"linear-in", {Keyword::TWEEN, Tween::LinearIn}},
{"linear-out", {Keyword::TWEEN, Tween::LinearOut}},
{"linear-in-out", {Keyword::TWEEN, Tween::LinearInOut}},
{"quadratic-in", {Keyword::TWEEN, Tween::QuadraticIn}},
{"quadratic-out", {Keyword::TWEEN, Tween::QuadraticOut}},
{"quadratic-in-out", {Keyword::TWEEN, Tween::QuadraticInOut}},
{"quartic-in", {Keyword::TWEEN, Tween::QuarticIn}},
{"quartic-out", {Keyword::TWEEN, Tween::QuarticOut}},
{"quartic-in-out", {Keyword::TWEEN, Tween::QuarticInOut}},
{"quintic-in", {Keyword::TWEEN, Tween::QuinticIn}},
{"quintic-out", {Keyword::TWEEN, Tween::QuinticOut}},
{"quintic-in-out", {Keyword::TWEEN, Tween::QuinticInOut}},
{"sine-in", {Keyword::TWEEN, Tween::SineIn}},
{"sine-out", {Keyword::TWEEN, Tween::SineOut}},
{"sine-in-out", {Keyword::TWEEN, Tween::SineInOut}},
};

Property PropertyParseAnimation(PropertyId id, const std::string& value) {
Expand Down

0 comments on commit 0b9a627

Please sign in to comment.