7#include "imgui/imgui.h"
13 return a + (b - a) * t;
18 return 1.0f - (inv * inv * inv);
22 return t < 0.5f ? 4.0f * t * t * t
23 : 1.0f - std::pow(-2.0f * t + 2.0f, 3.0f) / 2.0f;
27 const float c4 = (2.0f * 3.14159265f) / 3.0f;
28 if (t <= 0.0f)
return 0.0f;
29 if (t >= 1.0f)
return 1.0f;
30 return std::pow(2.0f, -10.0f * t) * std::sin((t * 10.0f - 0.75f) * c4) + 1.0f;
34 const float c1 = 1.70158f;
35 const float c3 = c1 + 1.0f;
37 return 1.0f + c3 * tm1 * tm1 * tm1 + c1 * tm1 * tm1;
41 return ImVec4(
Lerp(a.x, b.x, t),
Lerp(a.y, b.y, t),
Lerp(a.z, b.z, t),
46 const std::string& anim_id,
float target,
48 auto& state =
GetState(panel_id, anim_id);
49 if (!state.has_value) {
51 state.has_value =
true;
60 state.value =
Lerp(state.value, target, t);
65 const std::string& anim_id, ImVec4 target,
67 auto& state =
GetState(panel_id, anim_id);
68 if (!state.has_color) {
70 state.has_color =
true;
79 state.color =
LerpColor(state.color, target, t);
93 for (
auto panel_it =
panels_.begin(); panel_it !=
panels_.end();) {
94 panel_it->second.erase(
"panel_alpha");
95 panel_it->second.erase(
"category_transition");
96 if (panel_it->second.empty()) {
97 panel_it =
panels_.erase(panel_it);
134 state.progress = 0.0f;
140 state.initial_offset_x = -50.0f;
141 state.initial_offset_y = 0.0f;
144 state.initial_offset_x = 50.0f;
145 state.initial_offset_y = 0.0f;
148 state.initial_offset_x = 0.0f;
149 state.initial_offset_y = 50.0f;
152 state.initial_offset_x = 0.0f;
153 state.initial_offset_y = -50.0f;
156 state.initial_offset_x = 0.0f;
157 state.initial_offset_y = 0.0f;
163 const std::string& panel_id,
float speed) {
175 auto& state = iter->second;
179 state.progress = std::min(state.progress + step, 1.0f);
185 switch (state.type) {
187 result.
alpha = eased;
194 result.
alpha = eased;
195 result.
offset_x = state.initial_offset_x * (1.0f - eased);
196 result.
offset_y = state.initial_offset_y * (1.0f - eased);
200 result.
alpha = eased;
201 result.
scale = 0.8f + (0.2f * eased);
205 result.
alpha = eased;
206 result.
scale = eased;
215 if (state.progress >= 1.0f) {
216 state.active =
false;
237 if (transition.is_complete) {
242 if (transition.offset_x != 0.0f || transition.offset_y != 0.0f) {
243 ImVec2 window_pos = ImGui::GetCursorScreenPos();
244 ImGui::SetNextWindowPos(
245 ImVec2(window_pos.x + transition.offset_x,
246 window_pos.y + transition.offset_y),
252 ImGui::PushStyleVar(ImGuiStyleVar_Alpha,
253 ImGui::GetStyle().Alpha * transition.alpha);
260 ImGui::PopStyleVar();
265 if (ImGui::GetCurrentContext() ==
nullptr) {
276 const std::string& anim_id) {
277 return panels_[panel_id][anim_id];
281 if (ImGui::GetCurrentContext() ==
nullptr) {
286 const float scaled_speed =
288 const float delta = ImGui::GetIO().DeltaTime;
289 const float t = 1.0f - std::exp(-scaled_speed * delta);
290 return std::clamp(t, 0.0f, 1.0f);
306 t = std::clamp(t, 0.0f, 1.0f);
311 return t * t * (3.0f - 2.0f * t);
static float EaseOutBack(float t)
void ClearAnimationsForPanel(const std::string &panel_id)
bool IsPanelTransitioning(const std::string &panel_id) const
static MotionProfile ClampMotionProfile(int raw_profile)
float ComputeStep(float speed) const
PanelTransition UpdatePanelTransition(const std::string &panel_id, float speed=8.0f)
static float EaseInOutCubic(float t)
void SetMotionPreferences(bool reduced_motion, MotionProfile profile)
void ApplyPanelTransitionPre(const std::string &panel_id)
AnimationState & GetState(const std::string &panel_id, const std::string &anim_id)
float ApplyTransitionEasing(float t) const
static float Lerp(float a, float b, float t)
ImVec4 AnimateColor(const std::string &panel_id, const std::string &anim_id, ImVec4 target, float speed=5.0f)
bool reduced_motion() const
static float EaseOutElastic(float t)
static ImVec4 LerpColor(ImVec4 a, ImVec4 b, float t)
std::unordered_set< std::string > pushed_transition_alpha_
float Animate(const std::string &panel_id, const std::string &anim_id, float target, float speed=5.0f)
MotionProfile motion_profile_
float GetProfileSpeedMultiplier() const
std::unordered_map< std::string, AnimationMap > panels_
void ClearWorkspaceTransitionState()
void ApplyPanelTransitionPost(const std::string &panel_id)
void BeginPanelTransition(const std::string &panel_id, TransitionType type)
void ClearAllAnimations()
static float EaseOutCubic(float t)
std::unordered_map< std::string, PanelTransitionState > panel_transitions_
const Theme & GetCurrentTheme() const
static ThemeManager & Get()