Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fade-in and Fade-out Animation Effects #6123

Closed
anzenchitai opened this issue Jan 28, 2023 · 9 comments
Closed

Fade-in and Fade-out Animation Effects #6123

anzenchitai opened this issue Jan 28, 2023 · 9 comments

Comments

@anzenchitai
Copy link

Version/Branch of Dear ImGui:

Version: 1.89.2
Branch: docking

Back-end/Renderer/Compiler/OS

Back-ends: imgui_impl_dx9.cpp + imgui_impl_win32.cpp
Compiler: MSVC
Operating System: Windows 10 Build 19045.2486

My Issue/Question:

Hello, I want to implement a fade-in and fade-out animation but I have no idea what to do.

User launches the executable and the first window appears with fade-in effect.

Window 1:
User presses a button.
Window starts to disappear with a fade-out effect.

Window 2:
Window seamlessly starts to appear with a fade-in effect.
//Do something
Window starts to disappear with a fade-out effect.

I tried some stuff with alpha but no luck. Can someone please help me do something like this? Thanks in advance.

@Levi2288
Copy link

Just change the opacity of the menu each tick until it fades away or fades in.
Simple example:

void fadein_thread(float* oppcaity)
  {
      while (*oppcaity < 1.0) {
          *oppcaity += 0.02;
          std::this_thread::sleep_for(std::chrono::milliseconds(10));
      }
  } ```

@anzenchitai
Copy link
Author

Just change the opacity of the menu each tick until it fades away or fades in. Simple example:

void fadein_thread(float* oppcaity)
  {
      while (*oppcaity < 1.0) {
          *oppcaity += 0.02;
          std::this_thread::sleep_for(std::chrono::milliseconds(10));
      }
  } ```

Thanks for your reply. What do I pass to fadein_thread as opacity?

@sonoro1234
Copy link

#1925

@anzenchitai
Copy link
Author

#1925

        auto Animator = [](float& Alpha, bool& Tick, float MaxValue = 255, float Speed = 1.0f)
        {
            if (Tick || Alpha >= MaxValue)
            {
                Tick = true;
                if (!(Alpha <= 0))
                    Alpha -= Speed;
                else if (Alpha <= 0)
                    Tick ^= 1;
            }

            else if (!Tick || Alpha != MaxValue)
            {
                Tick = false;
                if (!(Alpha >= MaxValue))
                    Alpha += Speed;
                else if (Alpha >= MaxValue)
                    Tick ^= 1;
            }
        };

I am using this lambda expression to fade in and out my buttons and texts etc. but I can't manipulate the alpha value of the whole window for some reason. I tried to implement the offered solutions in #1925 but like I said, after initally setting the alpha value to let's say 0.001f, I can't change it ever again and it just gets stuck. When I try to gradually increase the alpha using loops, my program takes around 10 seconds to launch and initialize just to crash in another 10 seconds.

@sonoro1234
Copy link

sonoro1234 commented Jan 29, 2023

May be post the whole loop?

#1925 (comment)
Did you tried this code imgui functions?

ImGui::SetNextWindowBgAlpha(opacity)?

@anzenchitai
Copy link
Author

May be post the whole loop?

#1925 (comment) Did you tried this code imgui functions?

ImGui::SetNextWindowBgAlpha(opacity)?

Okay, I got fade-in working now.

float calculateAlpha(float n)
{
    n = (n > 0.0f) * n + !(n > 0.0f) * 0.0f;
    return (n < 1.0f) * n + !(n < 1.0f) * 1.0f;
}

static float cAlpha{ 0.0f };
static float frequency{ 0.4f };

cAlpha = calculateAlpha(cAlpha + frequency * io.DeltaTime);
style.Alpha = cAlpha;

But now the problem is, I can't change the global alpha value when a button is clicked. Nothing happens.

if (ImGui::Button("", ImVec2(350, 35)))
{  
    style.Alpha = 0.001f; //Doesn't do anything.
}

Aside from that, I added a spinner to appear when some button is clicked but it disappears almost immediately.

if (ImGui::Button("", ImVec2(350, 35)))
{  
    ImGui::SetCursorPos(ImVec2(50, 50));
    ImSpinner::SpinnerMultiFadeDots("", 50, 10); //imspinner.h
}

A noob question: How do I make the spinner stay on the screen for like let's say 10 seconds? Using Win32 Sleep(); just freezes the whole GUI. I really need a proper way of using delays etc. for ImGui. Thanks for the reply.

@lukaasm
Copy link
Contributor

lukaasm commented Jan 30, 2023

Aside from that, I added a spinner to appear when some button is clicked but it disappears almost immediately.

if (ImGui::Button("", ImVec2(350, 35)))
{  
    ImGui::SetCursorPos(ImVec2(50, 50));
    ImSpinner::SpinnerMultiFadeDots("", 50, 10); //imspinner.h
}

A noob question: How do I make the spinner stay on the screen for like let's say 10 seconds? Using Win32 Sleep(); just freezes the whole GUI. I really need a proper way of using delays etc. for ImGui. Thanks for the reply.

static float s_spinnerTimer = 0.0f;
if (ImGui::Button("", ImVec2(350, 35)))
{  
   s_spinnerTimer = 10.0f;
}

if ( s_spinnerTimer  > 0.0f ) {
   s_spinnerTimer -= io.DeltaTime;
   
   ImGui::SetCursorPos(ImVec2(50, 50));
   ImSpinner::SpinnerMultiFadeDots("", 50, 10); //imspinner.h
}

You need to remember that this is intermediate mode GUI and your GUI/Layout code is executed every frame step by step.
If you wish to do animations, timed events etc then it is your job to retain a state for that action and work with it

@anzenchitai
Copy link
Author

@lukaasm

Thank you. I did some cool stuff with linear interpolation. My GUI looks beautiful now. However, I have one final problem which is ImSpinner.h spinners completely ignoring global alpha. Hopefully I can fix that.

@ocornut
Copy link
Owner

ocornut commented Jan 31, 2023

Just change the opacity of the menu each tick until it fades away or fades in. Simple example:

void fadein_thread(float* oppcaity)
  {
      while (*oppcaity < 1.0) {
          *oppcaity += 0.02;
          std::this_thread::sleep_for(std::chrono::milliseconds(10));
      }
  } ```

For other stumbling on this, I need to clarify this answer is incorrect.
Any form of sleep() and variants would be blocking calls.
Dear ImGui relies on user-code submitting UI calls for each single refresh.

Generally you'd want to store variables (for e.g. the time an action start, or the current opacity and then on each subsequent update recalculate drawing parameters based on time elapsed (io.DeltaTime).

For example, the Toggle in this comment #1537 (comment) is using g.ActiveIdTimer / g.LastActiveIdTimer which is are timer increased when g.ActiveId, provided as convenience. But you can store your own timers as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants