Extra2D/include/animation/tween.h

169 lines
3.6 KiB
C
Raw Normal View History

#pragma once
#include <animation/tween_easing.h>
#include <core/color.h>
#include <core/math_types.h>
#include <functional>
#include <initializer_list>
#include <memory>
#include <optional>
#include <string>
#include <vector>
namespace extra2d {
class Node;
struct TweenOptions {
TweenEasing easing = TweenEasing::Linear;
std::function<void()> onStart = nullptr;
std::function<void(float progress)> onUpdate = nullptr;
std::function<void()> onComplete = nullptr;
};
struct TweenProperty {
std::optional<Vec2> position;
std::optional<Vec2> scale;
std::optional<float> rotation;
std::optional<float> opacity;
std::optional<Color> color;
};
class TweenAction {
public:
enum class Type : uint8_t {
Interval,
Delay,
Call,
Parallel,
};
virtual ~TweenAction() = default;
virtual void update(float dt) = 0;
virtual bool isFinished() const = 0;
virtual float getDuration() const = 0;
virtual float getElapsed() const = 0;
virtual void reset() = 0;
Type getType() const { return type_; }
protected:
TweenAction(Type type) : type_(type) {}
Type type_;
};
class Tween {
public:
using Ptr = std::shared_ptr<Tween>;
using Callback = std::function<void()>;
explicit Tween(Node *target);
Tween(Node *target, const std::string &name);
~Tween();
Tween(const Tween &) = delete;
Tween &operator=(const Tween &) = delete;
Tween(Tween &&) = default;
Tween &operator=(Tween &&) = default;
static Tween create(Node *target);
static Tween create(Node *target, const std::string &name);
Tween &to(float duration, const TweenProperty &props,
const TweenOptions &options = {});
Tween &by(float duration, const TweenProperty &props,
const TweenOptions &options = {});
Tween &set(const TweenProperty &props);
Tween &delay(float seconds);
Tween &call(Callback callback);
Tween &parallel();
Tween &endParallel();
Tween &union_();
Tween &repeat(int times);
Tween &repeatForever();
Tween &yoyo(bool enabled = true);
void start();
void stop();
void pause();
void resume();
void update(float dt);
bool isFinished() const;
bool isPlaying() const;
bool isPaused() const;
float getTotalDuration() const;
void setName(const std::string &name) { name_ = name; }
const std::string &getName() const { return name_; }
private:
Node *target_ = nullptr;
std::string name_;
std::vector<std::unique_ptr<TweenAction>> actions_;
size_t currentActionIndex_ = 0;
bool playing_ = false;
bool paused_ = false;
bool finished_ = false;
int repeatCount_ = 1;
int currentRepeat_ = 0;
bool yoyo_ = false;
bool reverse_ = false;
bool repeatForever_ = false;
bool inParallel_ = false;
std::vector<std::unique_ptr<TweenAction>> parallelActions_;
void addAction(std::unique_ptr<TweenAction> action);
void advanceToNextAction();
void resetAllActions();
};
namespace tween {
inline TweenProperty pos(const Vec2 &p) {
TweenProperty props;
props.position = p;
return props;
}
inline TweenProperty pos(float x, float y) { return pos(Vec2(x, y)); }
inline TweenProperty scl(const Vec2 &s) {
TweenProperty props;
props.scale = s;
return props;
}
inline TweenProperty scl(float s) { return scl(Vec2(s, s)); }
inline TweenProperty rot(float degrees) {
TweenProperty props;
props.rotation = degrees;
return props;
}
inline TweenProperty opa(float opacity) {
TweenProperty props;
props.opacity = opacity;
return props;
}
inline TweenProperty col(const Color &c) {
TweenProperty props;
props.color = c;
return props;
}
TweenProperty combine(std::initializer_list<TweenProperty> props);
} // namespace tween
} // namespace extra2d