Привет! Это мой небольшой исходник, с помощью которого вы можете создать анимацию появления/исчезновения вашего imgui-окна. Как-то давно уже была подобная тема, где использовалась данная анимация, но мягко говоря, она выполнена чересчур костыльно и при всём при этом зависила от FPS (При низком - очень медленная, при высоком - практически не заметная), а ещё она для старого, уже не актуального Dear Imgui 1.1.3. Данный исходник написан на версии 1.7.0 (mimgui)
Результат того, что получилось:
UPD: Версия для Dear Imgui 1.1.3
* Прозрачность окна было бы разумнее менять через функцию
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
)
Результат того, что получилось:
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), потратил час что бы понять в чём проблема, но так и не понял, однако если пушить стиль, то такой проблемы нет, поэтому оставил второй вариант
Последнее редактирование: