mimgui анимации

plalkeo

Известный
Автор темы
794
317
Версия MoonLoader
.026-beta
Если быть честным, никак не могу понять как делать вообще анимации в mimgui
Мне необходимо переместить один элемент с X1, Y1 до X2, Y2
Типо нажал кнопку и элемент начал перемещаться вниз с одинаковой скоростью вне зависимости от фпс
Мог бы кто помочь с этим и объяснить пожалуйста?
 
Решение
Lua:
local imgui = require('mimgui');
local renderWindow = imgui.new.bool(true);

local animation = {
    start = 0,
    pos = imgui.ImVec2(0, 0);
};

imgui.OnFrame(
    function() return renderWindow[0] end,
    function(this)
        if (imgui.Begin('Main Window', renderWindow)) then
            if (imgui.Button('Start')) then
                animation.start = os.clock();
            end
            animation.pos = bringVec2To(imgui.ImVec2(0, 0), imgui.ImVec2(100, 100), animation.start, 1);
            imgui.SetCursorPos(animation.pos);
            imgui.Button('Animated');

            imgui.End();
        end
    end
);

function bringVec2To(from, to, start_time, duration)
    local timer = os.clock() - start_time
    if timer >= 0.00...

Lance_Sterling

Известный
989
351
 

plalkeo

Известный
Автор темы
794
317
видел, но все еще не до конца понимаю как это реализовать нормально)
там просто кнопочка, а у меня чисто картинку двигать надо нажимая на кнопку рядом
 

Lance_Sterling

Известный
989
351
видел, но все еще не до конца понимаю как это реализовать нормально)
там просто кнопочка, а у меня чисто картинку двигать надо нажимая на кнопку рядом
Там есть пример анимации
 

chapo

чопа сребдс // TG/IG: @moujeek
Модератор
9,038
11,880
Lua:
local imgui = require('mimgui');
local renderWindow = imgui.new.bool(true);

local animation = {
    start = 0,
    pos = imgui.ImVec2(0, 0);
};

imgui.OnFrame(
    function() return renderWindow[0] end,
    function(this)
        if (imgui.Begin('Main Window', renderWindow)) then
            if (imgui.Button('Start')) then
                animation.start = os.clock();
            end
            animation.pos = bringVec2To(imgui.ImVec2(0, 0), imgui.ImVec2(100, 100), animation.start, 1);
            imgui.SetCursorPos(animation.pos);
            imgui.Button('Animated');

            imgui.End();
        end
    end
);

function bringVec2To(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 imgui.ImVec2(
            from.x + (count * (to.x - from.x) / 100),
            from.y + (count * (to.y - from.y) / 100)
        ), true
    end
    return (timer > duration) and to or from, false
end
 

chapo

чопа сребдс // TG/IG: @moujeek
Модератор
9,038
11,880
Вот еще один примерчик
создает примерно такую анимацию:

на самом деле все довольно просто если 1 раз понять как примерно это работает, но объяснить на словах принцип работы я вряд ли смогу, могу помочь только кодом. Если будут вопросы - пиши

Lua:
local imgui = require('mimgui');
local renderWindow = imgui.new.bool(true);

local state = false;
local animation = {
    state = state,
    start = 0,
    radius = 0,
    alpha = 0
};

imgui.OnInitialize(function()
    imgui.GetStyle().WindowPadding = imgui.ImVec2(0, 0);
end)

imgui.OnFrame(
    function() return renderWindow[0] end,
    function(this)
        if (imgui.Begin('Main Window', renderWindow)) then
            local pos, size = imgui.GetWindowPos(), imgui.GetWindowSize();
            local DL = imgui.GetWindowDrawList();

            animation.radius = bringFloatTo(animation.state and 500 or 0, animation.state and 0 or 500, animation.start, 1);
            animation.alpha = bringFloatTo(animation.state and 1 or 0, animation.state and 0 or 1, animation.start, 1);
            DL:AddCircleFilled(
                pos + imgui.ImVec2(size.x / 2, size.y / 2),
                animation.radius,
                imgui.GetColorU32Vec4(imgui.ImVec4(0.5, 0.5, 0.5, animation.alpha)),
                100
            );

            if (imgui.Button('Switch')) then
                state = not state;
                if (animation.state ~= state) then
                    animation.state = state;
                    animation.start = os.clock();
                end
            end

           

            imgui.End();
        end
    end
);

function bringFloatTo(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 from + (count * (to - from) / 100), true
    end
    return (timer > duration) and to or from, false
end
 
  • Нравится
Реакции: chromiusj и Rice.

plalkeo

Известный
Автор темы
794
317
Lua:
local imgui = require('mimgui');
local renderWindow = imgui.new.bool(true);

local animation = {
    start = 0,
    pos = imgui.ImVec2(0, 0);
};

imgui.OnFrame(
    function() return renderWindow[0] end,
    function(this)
        if (imgui.Begin('Main Window', renderWindow)) then
            if (imgui.Button('Start')) then
                animation.start = os.clock();
            end
            animation.pos = bringVec2To(imgui.ImVec2(0, 0), imgui.ImVec2(100, 100), animation.start, 1);
            imgui.SetCursorPos(animation.pos);
            imgui.Button('Animated');

            imgui.End();
        end
    end
);

function bringVec2To(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 imgui.ImVec2(
            from.x + (count * (to.x - from.x) / 100),
            from.y + (count * (to.y - from.y) / 100)
        ), true
    end
    return (timer > duration) and to or from, false
end
До нажатия выглядит так:

1692221766717.png

Белый кубик должен быть ровно под белым прямоугольником
Но он туда перемещается только после нажатия и спускается вниз туда где был до нажатия
1692221783620.png

Вкратце: Первая его позиция не та которая нужна
 
  • Bug
Реакции: Lance_Sterling

chapo

чопа сребдс // TG/IG: @moujeek
Модератор
9,038
11,880
До нажатия выглядит так:

Посмотреть вложение 212054
Белый кубик должен быть ровно под белым прямоугольником
Но он туда перемещается только после нажатия и спускается вниз туда где был до нажатия
Посмотреть вложение 212055
Вкратце: Первая его позиция не та которая нужна
это происходит из-за того что по умолчанию start установлен на 0, могу предложить одно решение, но скорее всего это колхозный костыль:
Lua:
local imgui = require('mimgui');
local renderWindow = imgui.new.bool(true);

local state = false;
local animation = {
    state = state,
    start = 0,
    radius = 0,
    alpha = 0
};

imgui.OnInitialize(function()
    imgui.GetStyle().WindowPadding = imgui.ImVec2(0, 0);
end)

local anim = {
    current = imgui.ImVec2(150, 150),
    next = imgui.ImVec2(150, 150),
    start = os.clock();
}

require('lib.moonloader');

addEventHandler('onWindowMessage', function(msg, param)
    if (msg == 0x0100) then
        if (param == VK_A or param == VK_D) then
            anim.start = os.clock();
            anim.next.x = anim.current.x + (param == VK_A and -100 or 100);
        elseif (param == VK_W or param == VK_S) then
            anim.start = os.clock();
            anim.next.y = anim.current.y + (param == VK_S and 100 or -100);
        end
    end
end);

imgui.OnFrame(
    function() return renderWindow[0] end,
    function(this)
        if (imgui.Begin('Main Window', renderWindow)) then
            local pos, size = imgui.GetWindowPos(), imgui.GetWindowSize();
            local DL = imgui.GetWindowDrawList();
            imgui.Text(('%s %s\n%s'):format(anim.current.x, anim.current.y, anim.start));
            anim.current = bringVec2To(anim.current, anim.next, anim.start, 5);
            imgui.SetCursorPos(anim.current);
            imgui.Button('test', imgui.ImVec2(100, 20));
            imgui.End();
        end
    end
);

function bringFloatTo(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 from + (count * (to - from) / 100), true
    end
    return (timer > duration) and to or from, false
end

function bringVec2To(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 imgui.ImVec2(
            from.x + (count * (to.x - from.x) / 100),
            from.y + (count * (to.y - from.y) / 100)
        ), true
    end
    return (timer > duration) and to or from, false
end

ну а в теории можешь просто хранить статус анимации (true/false) при изменениях менять начальное и конечное значение
 
  • Нравится
  • Bug
Реакции: chromiusj и Lance_Sterling

plalkeo

Известный
Автор темы
794
317
ну а в теории можешь просто хранить статус анимации (true/false) при изменениях менять начальное и конечное значение
вот это вот у меня сработало)
А код выше не особо работал как надо, анимка воспроизводилась при открытии окна
А если поставить в anim.start = 0 до мимгуи, а в кнопку anim.start = os.clock() то вообще не работала
Спасибо что помог)