Исходник Анимация появления/исчезновения окна Imgui

Cosmo

Известный
Автор темы
Друг
646
2,596
Привет! Это мой небольшой исходник, с помощью которого вы можете создать анимацию появления/исчезновения вашего imgui-окна. Как-то давно уже была подобная тема, где использовалась данная анимация, но мягко говоря, она выполнена чересчур костыльно и при всём при этом зависила от FPS (При низком - очень медленная, при высоком - практически не заметная), а ещё она для старого, уже не актуального Dear Imgui 1.1.3. Данный исходник написан на версии 1.7.0 (mimgui)

Lua:
local vk = require "vkeys"
local imgui = require "mimgui"

local ui_meta = {
    __index = function(self, v)
        if v == "switch" then
            local switch = function()
                if self.process and self.process:status() ~= "dead" then
                    return false -- // Предыдущая анимация ещё не завершилась!
                end
                self.timer = os.clock()
                self.state = not self.state

                self.process = lua_thread.create(function()
                    local bringFloatTo = function(from, to, start_time, duration)
                        local timer = os.clock() - start_time
                        if timer >= 0.00 and timer <= duration then
                            local count = timer / (duration / 100)
                            return count * ((to - from) / 100)
                        end
                        return (timer > duration) and to or from
                    end

                    while true do wait(0)
                        local a = bringFloatTo(0.00, 1.00, self.timer, self.duration)
                        self.alpha = self.state and a or 1.00 - a
                        if a == 1.00 then break end
                    end
                end)
                return true -- // Состояние окна изменено!
            end
            return switch
        end
 
        if v == "alpha" then
            return self.state and 1.00 or 0.00
        end
    end
}

-- // Вместо imgui.new.bool создадим переменные окон таким способом:

-- // Для первого окна, в нашем случае главного меню:
local menu = { state = false, duration = 0.5 } -- // Duration - это длительность анимации (в секундах)
setmetatable(menu, ui_meta) -- // Устанавливаем выше созданную мета-таблицу в таблицу состояния первого окна

-- // И для второго окна, например, окно какой-то информации:
local info = { state = false, duration = 1.0 }
setmetatable(info, ui_meta)

function main()
    repeat wait(0) until isSampAvailable()
 
    -- // Создадим команды для включения и выключения окон
    sampRegisterChatCommand("menu", menu.switch)
    sampRegisterChatCommand("info", info.switch)

    while true do
 
        -- // Ну и для примера ещё добавим hot-key вызова основного окна:
        if isKeyJustPressed(vk.VK_F2) then
            menu.switch() -- Переключаем состояние окна
        end

        wait(0)
    end
end

local main_frame = imgui.OnFrame(
    function() return menu.alpha > 0.00 end, -- Указываем здесь данное условие, тем самым рендеря окно только в том случае, если его прозрачность больше нуля
    function(self)
        self.HideCursor = not menu.state -- // Курсор будет убираться на моменте, когда окно начинает исчезать
        imgui.PushStyleVarFloat(imgui.StyleVar.Alpha, menu.alpha)
        imgui.Begin("##My window", _, imgui.WindowFlags.NoTitleBar)
 
            -- // Code..
 
        imgui.End()
        imgui.PopStyleVar()
    end
)

-- // Аналогично для второго окна:
local info_frame = imgui.OnFrame(
    function() return info.alpha > 0.00 end,
    function(self)
        self.HideCursor = not info.state
        imgui.PushStyleVarFloat(imgui.StyleVar.Alpha, info.alpha)
        imgui.Begin("##Information", _, imgui.WindowFlags.NoTitleBar)
 
            -- // Code..
 
        imgui.End()
        imgui.PopStyleVar()
    end
)

Результат того, что получилось:
QNBMv.gif


UPD: Версия для Dear Imgui 1.1.3
Lua:
local vk = require "vkeys"
local imgui = require "imgui"

local ui_meta = {
    __index = function(self, v)
        if v == "switch" then
            local switch = function()
                if self.process and self.process:status() ~= "dead" then
                    return false
                end
                self.timer = os.clock()
                self.state = not self.state

                self.process = lua_thread.create(function()
                    local bringFloatTo = function(from, to, start_time, duration)
                        local timer = os.clock() - start_time
                        if timer >= 0.00 and timer <= duration then
                            local count = timer / (duration / 100)
                            return count * ((to - from) / 100)
                        end
                        return (timer > duration) and to or from
                    end

                    while true do wait(0)
                        local a = bringFloatTo(0.00, 1.00, self.timer, self.duration)
                        self.alpha = self.state and a or 1.00 - a
                        if a == 1.00 then break end
                    end
                end)
                return true
            end
            return switch
        end
 
        if v == "alpha" then
            return self.state and 1.00 or 0.00
        end
    end
}

local menu = { state = false, duration = 0.5 }
setmetatable(menu, ui_meta)

local info = { state = false, duration = 1.0 }
setmetatable(info, ui_meta)

function main()
    repeat wait(0) until isSampAvailable()
 
    sampRegisterChatCommand("menu", menu.switch)
    sampRegisterChatCommand("info", info.switch)

    while true do
     
        imgui.Process = (menu.alpha > 0.00) or (info.alpha > 0.00)
        imgui.ShowCursor = menu.state or info.state

        if isKeyJustPressed(vk.VK_F2) then
            menu.switch()
        end

        wait(0)
    end
end

function imgui.OnDrawFrame()
    if menu.alpha > 0.00 then
        imgui.PushStyleVar(imgui.StyleVar.Alpha, menu.alpha)
        imgui.Begin("##My window", _, imgui.WindowFlags.NoTitleBar)

            -- // Code..

        imgui.End()
        imgui.PopStyleVar()
    end

    if info.alpha > 0.00 then
        imgui.PushStyleVar(imgui.StyleVar.Alpha, info.alpha)
        imgui.Begin("##Information", _, imgui.WindowFlags.NoTitleBar)
 
            -- // Code..
 
        imgui.End()
        imgui.PopStyleVar()
    end
end

* Прозрачность окна было бы разумнее менять через функцию imgui.SetNextWindowBgAlpha(), но по какой-то причине, окно с ней «моргает» при определённом значении (возможно, когда альфа становится равной 1.00), потратил час что бы понять в чём проблема, но так и не понял, однако если пушить стиль, то такой проблемы нет, поэтому оставил второй вариант
 
Последнее редактирование:

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Друг
8,765
11,213
это ахуенно, будет для библиотеки имгур?! (я слишком туп что бы перевести)
космо я твой фан
космо я хочу от тебя детей
 

Cosmo

Известный
Автор темы
Друг
646
2,596
это ахуенно, будет для библиотеки имгур?! (я слишком туп что бы перевести)
космо я твой фан
космо я хочу от тебя детей
ретард, перейди на мимгуи, всем бластхаком ждём
 

etereon

MQ-Team
Проверенный
323
837

Shishkin

Известный
491
250
это ахуенно, будет для библиотеки имгур?! (я слишком туп что бы перевести)
космо я твой фан
космо я хочу от тебя детей
 

askfmaskfaosflas

Потрачен
1,089
513
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
как добавить крестик в окно? не выходит через переменную
 

askfmaskfaosflas

Потрачен
1,089
513
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.