-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathAnimation.h
115 lines (96 loc) · 3.41 KB
/
Animation.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//
// Animation.h
// Termin8or
//
// Created by Rasmus Anthin on 2024-11-18.
//
#pragma once
#include <Core/Math.h>
#include <functional>
namespace easings
{
std::function<float(float)> ease_lin = [](float t)
{
return t;
};
std::function<float(float)> ease_in_sine = [](float t)
{
return 1.f - std::cos((t * math::c_pi) * 0.5f);
};
std::function<float(float)> ease_out_sine = [](float t)
{
return std::sin((t * math::c_pi) * 0.5f);
};
}
struct TransitionAnimationInOut
{
float transition_start_time_s = 0.f;
// Relative to transition_start_time_s.
float enter_rel_start_time_s = 0.f;
float enter_rel_end_time_s = 0.f;
float exit_rel_start_time_s = 0.f;
float exit_rel_end_time_s = 0.f;
float animate(float time_s, float value_start, float value_stationary, float value_end,
std::function<float(float)>& ease_enter_func = easings::ease_lin,
std::function<float(float)>& ease_exit_func = easings::ease_lin) const
{
auto rel_time_s = time_s - transition_start_time_s;
float t_enter = math::value_to_param(rel_time_s, enter_rel_start_time_s, enter_rel_end_time_s);
if (math::in_range<float>(t_enter, {}, 0.f, Range::FreeOpen))
return value_start;
if (math::in_range<float>(t_enter, 0.f, 1.f, Range::ClosedOpen))
return math::lerp(ease_enter_func(t_enter), value_start, value_stationary);
float t_exit = math::value_to_param(rel_time_s, exit_rel_start_time_s, exit_rel_end_time_s);
if (math::in_range<float>(t_exit, 0.f, 1.f, Range::ClosedOpen))
return math::lerp(ease_exit_func(t_exit), value_stationary, value_end);
if (math::in_range<float>(t_exit, 1.f, {}, Range::ClosedFree))
return value_end;
return value_stationary;
}
bool in_range(float time_s) const
{
auto rel_time_s = time_s - transition_start_time_s;
float t = math::value_to_param(rel_time_s, enter_rel_start_time_s, exit_rel_end_time_s);
return math::in_range<float>(t, 0.f, 1.f, Range::ClosedOpen);
}
bool begun(float time_s) const
{
return time_s - transition_start_time_s >= enter_rel_start_time_s;
}
bool done(float time_s) const
{
return time_s - transition_start_time_s >= exit_rel_end_time_s;
}
};
struct TransitionAnimationSingle
{
float transition_start_time_s = 0.f;
// Relative to transition_start_time_s.
float enter_rel_start_time_s = 0.f;
float exit_rel_end_time_s = 0.f;
float animate(float time_s, float value_start, float value_end,
std::function<float(float)>& ease_func = easings::ease_lin) const
{
auto rel_time_s = time_s - transition_start_time_s;
float t = math::value_to_param(rel_time_s, enter_rel_start_time_s, exit_rel_end_time_s);
if (math::in_range<float>(t, {}, 0.f, Range::FreeOpen))
return value_start;
if (math::in_range<float>(t, 1.f, {}, Range::ClosedFree))
return value_end;
return math::lerp(ease_func(t), value_start, value_end);
}
bool in_range(float time_s) const
{
auto rel_time_s = time_s - transition_start_time_s;
float t = math::value_to_param(rel_time_s, enter_rel_start_time_s, exit_rel_end_time_s);
return math::in_range<float>(t, 0.f, 1.f, Range::ClosedOpen);
}
bool begun(float time_s) const
{
return time_s - transition_start_time_s >= enter_rel_start_time_s;
}
bool done(float time_s) const
{
return time_s - transition_start_time_s >= exit_rel_end_time_s;
}
};