diff --git a/include/Game/GUI/StoryboardFrame.h b/include/Game/GUI/StoryboardFrame.h new file mode 100644 index 0000000..ccf49c1 --- /dev/null +++ b/include/Game/GUI/StoryboardFrame.h @@ -0,0 +1,112 @@ +#ifndef GAME_GUI_STORYBOARDFRAME_H__ +#define GAME_GUI_STORYBOARDFRAME_H__ + +#include "GUI/TextureFrame.h" + +namespace dd +{ +namespace GUI +{ + +class StoryboardFrame : public TextureFrame +{ +public: + struct Transition + { + double Time = 0.0; + double Duration = 0.0; + Rectangle Viewport; + std::string Texture; + }; + + StoryboardFrame(Frame* parent, std::string name) + : TextureFrame(parent, name) + { + m_TextureFrame = new TextureFrame(this, "StoryboardFrameHelper"); + //m_TextureFrame->DisableScissor(); + } + + void AddTransition(Transition& transition) + { + m_Timeline.push_back(transition); + } + + void Play() + { + m_Playing = 1; + } + + void Update(double dt) + { + if (!m_Playing) { + return; + } + + m_Time += (double)m_Playing * dt; + + if (m_NextIndex < m_Timeline.size()) { + if (m_Time >= m_Timeline.at(m_NextIndex).Time) { + m_CurrentIndex = m_NextIndex; + Transition& t = m_Timeline.at(m_CurrentIndex); + + m_TextureFrame->FadeToTexture(t.Texture, t.Duration); + //m_TextureFrame->SetTexture(t.Texture); + m_TextureFrame->SizeToTexture(); + + if (m_StartRect == Rectangle()) { + m_StartRect = Rectangle(0, 0, m_TextureFrame->Width, m_TextureFrame->Height); + } else { + m_StartRect = m_TargetRect; + } + + double wScaleParent = Width / (double)m_TextureFrame->Width; + double wScale = m_TextureFrame->Width / (double)t.Viewport.Width; + LOG_DEBUG("wScale: %f", wScale); + double hScaleParent = Height / (double)m_TextureFrame->Height; + double hScale = m_TextureFrame->Height / (double)t.Viewport.Height; + LOG_DEBUG("hScale: %f", hScale); + m_TargetRect.X = -t.Viewport.X * wScale * wScaleParent; + m_TargetRect.Y = -t.Viewport.Y * hScale * hScaleParent; + m_TargetRect.Width = m_TextureFrame->Width * wScale * wScaleParent; + m_TargetRect.Height = m_TextureFrame->Height * hScale * hScaleParent; + + m_NextIndex++; + } + } + + Transition& t = m_Timeline.at(m_CurrentIndex); + double progress = glm::min((m_Time - t.Time)/t.Duration, 1.0); + m_TextureFrame->X = (int)easeSine(progress, m_StartRect.X, (m_TargetRect.X - m_StartRect.X), 1.0); + m_TextureFrame->Y = (int)easeSine(progress, m_StartRect.Y, (m_TargetRect.Y - m_StartRect.Y), 1.0); + m_TextureFrame->Width = (int)easeSine(progress, m_StartRect.Width, (m_TargetRect.Width - m_StartRect.Width), 1.0); + m_TextureFrame->Height = (int)easeSine(progress, m_StartRect.Height, (m_TargetRect.Height - m_StartRect.Height), 1.0); + } + +public: + int m_Playing = 0; + double m_Time = 0; + int m_CurrentIndex = 0; + int m_NextIndex = 0; + std::vector m_Timeline; + Rectangle m_StartRect; + Rectangle m_TargetRect; + + TextureFrame* m_TextureFrame = nullptr; + + double easeSine(double t, double b, double c, double d) + { + return -c / 2 * (glm::cos(glm::pi()*t / d) - 1) + b; + } + + float easeExpo(float t,float b , float c, float d) { + if (t == 0) return b; + if (t == d) return b + c; + if ((t /= d / 2) < 1) return c / 2 * pow(2, 10 * (t - 1)) + b; + return c / 2 * (-pow(2, -10 * --t) + 2) + b; + } +}; + +} +} + +#endif