Полезные сниппеты и функции

CaJlaT

07.11.2024 14:55
Модератор
2,857
2,721
Функция проверяет, есть ли прямая видимость между игроком и целью (не через стену)
Lua:
function hasLineOfSightTo(playerHandle, targetHandle)
    local x1, y1, z1 = getCharCoordinates(playerHandle)
    local x2, y2, z2 = getCharCoordinates(targetHandle)
  
    local hit, _, _, _, material = processLineOfSight(
        x1, y1, z1 + 0.9,
        x2, y2, z2 + 0.9,
        true, true, true, true, false, true, false
    )

    return not hit or material == 0
end
Класс, а просто юзать это и не заворачивать готовую функцию в новую вообще вариантов нет?
 
  • Нравится
Реакции: MLycoris

pathtohell

Участник
7
36
Описание: Современная и плавная кнопка переключения в стиле Material Design.
Код:
Lua:
local imgui = require('mimgui')

local switchAnimationStates = {}

local function interpolateValue(startValue, targetValue, time)
    return startValue + (targetValue - startValue) * math.min(time, 1.0)
end

local function interpolateColor(color1, color2, time)
    return {
        interpolateValue(color1[1], color2[1], time),
        interpolateValue(color1[2], color2[2], time),
        interpolateValue(color1[3], color2[3], time),
        interpolateValue(color1[4], color2[4], time)
    }
end

---@param label string
---@param stateReference boolean[]
---@param activeColor? table
---@param width? number
---@param height? number
function imgui.SwitchButton(label, stateReference, activeColor, width, height)
    local drawList = imgui.GetWindowDrawList()
    local inputOutput = imgui.GetIO()

    local switchWidth = width or 50
    local switchHeight = height or 28
    local padding = 3
    local thumbRadius = (switchHeight - padding * 2) / 2

    local position = imgui.GetCursorScreenPos()

    local thumbStartX = position.x + padding + thumbRadius
    local thumbEndX = position.x + switchWidth - padding - thumbRadius

    if not switchAnimationStates[label] then
        switchAnimationStates[label] = {
            animationProgress = stateReference[0] and 1.0 or 0.0
        }
    end

    local animationState = switchAnimationStates[label]
    local targetProgress = stateReference[0] and 1.0 or 0.0
    local animationSpeed = 9.0

    if animationState.animationProgress ~= targetProgress then
        animationState.animationProgress = interpolateValue(
            animationState.animationProgress,
            targetProgress,
            inputOutput.DeltaTime * animationSpeed
        )
    end

    imgui.InvisibleButton(label, imgui.ImVec2(switchWidth, switchHeight))
   
    if imgui.IsItemClicked() then
        stateReference[0] = not stateReference[0]
    end

    local isHovered = imgui.IsItemHovered()

    local colorActive = activeColor or {0.90, 0.16, 0.49, 1.0}
    local colorInactive = {0.86, 0.86, 0.86, 1.0}
    local colorThumb = {1.0, 1.0, 1.0, 1.0}
    local colorShadow = {0.0, 0.0, 0.0, 0.25}

    local backgroundColor = interpolateColor(colorInactive, colorActive, animationState.animationProgress)
    local hoverMultiplier = isHovered and 0.95 or 1.0
   
    backgroundColor = {
        backgroundColor[1] * hoverMultiplier,
        backgroundColor[2] * hoverMultiplier,
        backgroundColor[3] * hoverMultiplier,
        backgroundColor[4]
    }

    local backgroundColorU32 = imgui.ColorConvertFloat4ToU32(imgui.ImVec4(unpack(backgroundColor)))
    local halfHeight = switchHeight / 2

    local leftCircleCenter = imgui.ImVec2(position.x + halfHeight, position.y + halfHeight)
    local rightCircleCenter = imgui.ImVec2(position.x + switchWidth - halfHeight, position.y + halfHeight)
   
    drawList:AddCircleFilled(leftCircleCenter, halfHeight, backgroundColorU32, 64)
    drawList:AddCircleFilled(rightCircleCenter, halfHeight, backgroundColorU32, 64)
    drawList:AddRectFilled(
        imgui.ImVec2(position.x + halfHeight, position.y),
        imgui.ImVec2(position.x + switchWidth - halfHeight, position.y + switchHeight),
        backgroundColorU32
    )

    local thumbPositionX = interpolateValue(thumbStartX, thumbEndX, animationState.animationProgress)
    local thumbPosition = imgui.ImVec2(thumbPositionX, position.y + halfHeight)

    drawList:AddCircleFilled(
        imgui.ImVec2(thumbPosition.x, thumbPosition.y + 1.5),
        thumbRadius,
        imgui.ColorConvertFloat4ToU32(imgui.ImVec4(unpack(colorShadow))),
        64
    )

    drawList:AddCircleFilled(
        thumbPosition,
        thumbRadius,
        imgui.ColorConvertFloat4ToU32(imgui.ImVec4(unpack(colorThumb))),
        64
    )

    return stateReference[0]
end
Пример использования:
Lua:
local showWindow = imgui.new.bool(true)

local switch_pink = imgui.new.bool(true)
local switch_blue = imgui.new.bool(true)
local switch_green = imgui.new.bool(true)
local switch_grey = imgui.new.bool(false)

local color_pink = {0.90, 0.16, 0.49, 1.0}
local color_blue = {0.11, 0.63, 0.95, 1.0}
local color_green = {0.18, 0.80, 0.44, 1.0}

imgui.OnFrame(function()
    return showWindow[0] end, function()
  
    imgui.SetNextWindowSize(imgui.ImVec2(320, 300), imgui.Cond.FirstUseEver)
    imgui.Begin('Switch Button Examples', showWindow)

    imgui.Text('Switch Button Examples:')
    imgui.Separator()

    imgui.SwitchButton('Switch_1_Pink', switch_pink, color_pink)
    imgui.SameLine(0, 10)
    imgui.Text('Pink switch')

    imgui.SwitchButton('Switch_2_Blue', switch_blue, color_blue)
    imgui.SameLine(0, 10)
    imgui.Text('Blue switch')

    imgui.SwitchButton('Switch_3_Green', switch_green, color_green)
    imgui.SameLine(0, 10)
    imgui.Text('Green switch')

    imgui.SwitchButton('Switch_4_Grey', switch_grey, color_pink)
    imgui.SameLine(0, 10)
    imgui.Text('Disabled state')

    imgui.Separator()
    imgui.Text('Custom sizes examples:')

    imgui.SwitchButton('Switch_5_Large', switch_pink, color_pink, 70, 38)
    imgui.SameLine(0, 10)
    imgui.Text('Large size (70x38)')
  
    imgui.SwitchButton('Switch_6_Small', switch_blue, color_blue, 40, 22)
    imgui.SameLine(0, 10)
    imgui.Text('Small size (40x22)')

    imgui.Separator()
    imgui.Text('Current states:')

    imgui.TextColored(color_pink, string.format('Pink switch: %s', switch_pink[0] and 'ON' or 'OFF'))
    imgui.TextColored(color_blue, string.format('Blue switch: %s', switch_blue[0] and 'ON' or 'OFF'))
    imgui.TextColored(color_green, string.format('Green switch: %s', switch_green[0] and 'ON' or 'OFF'))
    imgui.TextColored(imgui.ImVec4(0.5, 0.5, 0.5, 1.0), string.format('Grey switch: %s', switch_grey[0] and 'ON' or 'OFF'))

    imgui.Separator()
  
    if imgui.Button('Turn All ON', imgui.ImVec2(100, 25)) then
        switch_pink[0] = true
        switch_blue[0] = true
        switch_green[0] = true
    end
  
    imgui.SameLine(0, 10)
  
    if imgui.Button('Turn All OFF', imgui.ImVec2(100, 25)) then
        switch_pink[0] = false
        switch_blue[0] = false
        switch_green[0] = false
        switch_grey[0] = false
    end

    imgui.End()
end)
Image.PNG
 
Последнее редактирование:

pathtohell

Участник
7
36
Описание: Визуальный прицел с динамическим захватом цели и индикацией траектории.
Код:
Lua:
local imgui = require('mimgui')

local sightState = {
    rotation = 0,
    lastTime = os.clock(),
    pulsePhase = 0
}

---@param centerX number X центр экрана
---@param centerY number Y центр экрана
---@param size number Размер в пикселях
---@param targetX number|nil X цели (опционально)
---@param targetY number|nil Y цели (опционально)
---@param isLocked boolean Цвет: true=синий(захват), false=розовый(поиск)
function imgui.TargetSight(centerX, centerY, size, targetX, targetY, isLocked)
    local now = os.clock()
    local delta = now - sightState.lastTime
    sightState.lastTime = now

    sightState.rotation = (sightState.rotation + delta * 0.85) % (math.pi * 2)
    sightState.pulsePhase = sightState.pulsePhase + delta * 7.5
 
    local DL = imgui.GetBackgroundDrawList()
    local pulse = 0.8 + 0.25 * math.sin(now * 5.5)
    local visualSize = size * pulse

    local colors = {
        primary = isLocked and {0.0, 0.85, 1.0, 1.0} or {1.0, 0.25, 0.8, 1.0},
        accent = {0.15, 1.0, 0.35, 0.9},
        glow = {0.0, 0.7, 1.0, 0.22},
        ray = {0.35, 0.75, 1.0, 0.12}
    }

    for i = 0, 5 do
        local angle = sightState.rotation + i * math.pi / 3
        local endX = centerX + math.cos(angle) * visualSize * 1.7
        local endY = centerY + math.sin(angle) * visualSize * 1.7
     
        DL:AddLine(
            imgui.ImVec2(centerX, centerY),
            imgui.ImVec2(endX, endY),
            imgui.ColorConvertFloat4ToU32(imgui.ImVec4(table.unpack(colors.ray))),
            0.65
        )
    end

    local triangle = {}
    for i = 0, 2 do
        local angle = sightState.rotation + i * math.pi * 2 / 3
        triangle[i + 1] = imgui.ImVec2(
            centerX + math.cos(angle) * visualSize,
            centerY + math.sin(angle) * visualSize
        )
    end

    for i = 1, 3 do
        local nextIndex = i % 3 + 1
        DL:AddLine(
            triangle[i],
            triangle[nextIndex],
            imgui.ColorConvertFloat4ToU32(imgui.ImVec4(table.unpack(colors.glow))),
            2.8
        )
    end

    for i = 1, 3 do
        local nextIndex = i % 3 + 1
        DL:AddLine(
            triangle[i],
            triangle[nextIndex],
            imgui.ColorConvertFloat4ToU32(imgui.ImVec4(table.unpack(colors.primary))),
            1.4
        )
    end

    local innerPulse = 0.75 + 0.35 * math.sin(now * 9.5)
    local outerPulse = 0.6 + 0.25 * math.cos(now * 14.5)
 
    DL:AddCircleFilled(
        imgui.ImVec2(centerX, centerY),
        1.8 * innerPulse,
        imgui.ColorConvertFloat4ToU32(imgui.ImVec4(table.unpack(colors.accent))),
        10
    )
 
    DL:AddCircle(
        imgui.ImVec2(centerX, centerY),
        3.5 * outerPulse,
        imgui.ColorConvertFloat4ToU32(imgui.ImVec4(table.unpack{
            colors.glow[1], colors.glow[2], colors.glow[3], 0.7
        })),
        10,
        1.1
    )

    if targetX and targetY then
        DL:AddLine(
            imgui.ImVec2(centerX, centerY),
            imgui.ImVec2(targetX, targetY),
            imgui.ColorConvertFloat4ToU32(imgui.ImVec4(table.unpack{
                colors.primary[1], colors.primary[2], colors.primary[3], 0.8
            })),
            1.1
        )

        local targetBeat = (math.sin(now * 13) + 1) * 0.45
        local innerRadius = 3.5 + targetBeat * 2.5
        local outerRadius = 7.5 + targetBeat * 4
     
        DL:AddCircle(
            imgui.ImVec2(targetX, targetY),
            innerRadius,
            imgui.ColorConvertFloat4ToU32(imgui.ImVec4(table.unpack{
                colors.primary[1], colors.primary[2], colors.primary[3], 0.85
            })),
            14,
            1.7
        )
     
        DL:AddCircle(
            imgui.ImVec2(targetX, targetY),
            outerRadius,
            imgui.ColorConvertFloat4ToU32(imgui.ImVec4(table.unpack{
                colors.glow[1], colors.glow[2], colors.glow[3], targetBeat * 0.35
            })),
            14,
            1.0
        )

        for i = 0, 3 do
            local orbitAngle = now * 4.5 + i * math.pi / 2
            local orbitDistance = 11 + math.sin(now * 7.5 + i) * 5
            local satelliteX = targetX + math.cos(orbitAngle) * orbitDistance
            local satelliteY = targetY + math.sin(orbitAngle) * orbitDistance
            local satelliteSize = 0.85 + math.sin(now * 9 + i * 1.5) * 0.35
         
            DL:AddCircleFilled(
                imgui.ImVec2(satelliteX, satelliteY),
                satelliteSize,
                imgui.ColorConvertFloat4ToU32(imgui.ImVec4(table.unpack{
                    colors.accent[1], colors.accent[2], colors.accent[3], 0.75
                })),
                6
            )
        end
    end

    for i = 0, 7 do
        local particleAngle = now * 2.5 + i * math.pi / 4
        local particleDistance = visualSize * 2.1 + math.sin(now * 3.5 + i) * 7
        local particleX = centerX + math.cos(particleAngle) * particleDistance
        local particleY = centerY + math.sin(particleAngle) * particleDistance
        local particleSize = 0.55 + math.sin(now * 6.5 + i) * 0.45
     
        DL:AddCircleFilled(
            imgui.ImVec2(particleX, particleY),
            particleSize,
            imgui.ColorConvertFloat4ToU32(imgui.ImVec4(table.unpack{
                colors.glow[1], colors.glow[2], colors.glow[3], 0.45
            })),
            5
        )
    end
end
Пример использования:
Lua:
local size = 28.0
local enabled = imgui.new.bool(true)

imgui.OnFrame(function()
    return enabled end, function(self)
        self.HideCursor = true
        local screenWidth, screenHeight = getScreenResolution()
        local centerX, centerY = screenWidth / 2, screenHeight / 2
 
        local targetX, targetY, isLocked = получитьБлижайшегоИгрока()
 
        imgui.TargetSight(centerX, centerY, size, targetX, targetY, isLocked)
    end
)
Image number 2.PNG

Описание: Плавненький градиентный слайдер.
Код:
Lua:
local imgui = require('mimgui')

local sliderStates = {}

---@param label string Надпись слайдера
---@param valueReference number[] Ссылка на значение (массив из одного числа)
---@param minimumValue number Минимальное значение
---@param maximumValue number Максимальное значение
---@param width number|nil Ширина слайдера (опционально)
---@param height number|nil Высота трека (опционально)
---@param accentColor table|nil Цвет акцента {r,g,b,a} (опционально)
---@return number Текущее значение слайдера
function imgui.MaterialSlider(label, valueReference, minimumValue, maximumValue, width, height, accentColor)
    local DL = imgui.GetWindowDrawList()
    local IO = imgui.GetIO()
 
    local sliderWidth = width or 250
    local trackHeight = height or 6
    local thumbSize = 18
    local thumbRadius = thumbSize / 2
    local deltaTime = IO.DeltaTime

    local accent = accentColor or {0.00, 0.78, 1.00, 1.0}
    local trackColor = {0.20, 0.20, 0.25, 1.0}
    local trackFillStart = {0.10, 0.10, 0.15, 1.0}
    local shadowColor = {0.0, 0.0, 0.0, 0.15}

    if not sliderStates[label] then
        sliderStates[label] = {
            isActive = false,
            isHovered = false,
            thumbScale = 1.0,
            dragStartValue = valueReference[0],
            dragStartX = 0,
            visualValue = valueReference[0],
            wasActive = false
        }
    end
 
    local state = sliderStates[label]
    local cursorPosition = imgui.GetCursorScreenPos()
    local trackY = cursorPosition.y + thumbRadius

    state.visualValue = state.visualValue + (valueReference[0] - state.visualValue) * math.min(deltaTime * 12.0, 1.0)
 
    local normalizedValue = (state.visualValue - minimumValue) / (maximumValue - minimumValue)
    normalizedValue = math.max(0, math.min(1, normalizedValue))
    local thumbX = cursorPosition.x + normalizedValue * sliderWidth

    local hitboxHeight = thumbSize * 2
    imgui.SetCursorScreenPos(imgui.ImVec2(cursorPosition.x, cursorPosition.y - thumbRadius))
    imgui.InvisibleButton(label, imgui.ImVec2(sliderWidth, hitboxHeight))
 
    state.isHovered = imgui.IsItemHovered()
    state.isActive = imgui.IsItemActive()
 
    if state.isActive then
        if not state.wasActive then
            state.dragStartValue = valueReference[0]
            state.dragStartX = IO.MousePos.x
            state.wasActive = true
        end
    
        local mouseDeltaX = IO.MousePos.x - state.dragStartX
        local valueDelta = (mouseDeltaX / sliderWidth) * (maximumValue - minimumValue)
        valueReference[0] = math.max(minimumValue, math.min(maximumValue, state.dragStartValue + valueDelta))
    else
        state.wasActive = false
        if imgui.IsItemClicked() then
            local clickX = math.max(0, math.min(sliderWidth, IO.MousePos.x - cursorPosition.x))
            valueReference[0] = minimumValue + (clickX / sliderWidth) * (maximumValue - minimumValue)
        end
    end

    local targetThumbScale = state.isActive and 1.25 or (state.isHovered and 1.1 or 1.0)
    state.thumbScale = state.thumbScale + (targetThumbScale - state.thumbScale) * math.min(deltaTime * 10.0, 1.0)

    DL:AddRectFilled(
        imgui.ImVec2(cursorPosition.x, trackY - trackHeight / 2),
        imgui.ImVec2(cursorPosition.x + sliderWidth, trackY + trackHeight / 2),
        imgui.ColorConvertFloat4ToU32(imgui.ImVec4(unpack(trackColor))),
        0.0
    )

    if thumbX > cursorPosition.x then
        local endR = trackFillStart[1] + (accent[1] - trackFillStart[1]) * 0.7
        local endG = trackFillStart[2] + (accent[2] - trackFillStart[2]) * 0.7
        local endB = trackFillStart[3] + (accent[3] - trackFillStart[3]) * 0.7
        local endA = trackFillStart[4] + (accent[4] - trackFillStart[4]) * 0.7
    
        local colStart = imgui.ColorConvertFloat4ToU32(imgui.ImVec4(unpack(trackFillStart)))
        local colEnd = imgui.ColorConvertFloat4ToU32(imgui.ImVec4(unpack({endR, endG, endB, endA})))

        DL:AddRectFilledMultiColor(
            imgui.ImVec2(cursorPosition.x, trackY - trackHeight / 2),
            imgui.ImVec2(thumbX, trackY + trackHeight / 2),
            colStart, colEnd, colEnd, colStart
        )
    end

    DL:AddCircleFilled(
        imgui.ImVec2(thumbX, trackY + 0.5),
        thumbRadius * state.thumbScale * 0.9,
        imgui.ColorConvertFloat4ToU32(imgui.ImVec4(unpack(shadowColor))),
        24
    )

    DL:AddCircleFilled(
        imgui.ImVec2(thumbX, trackY),
        thumbRadius * state.thumbScale,
        imgui.ColorConvertFloat4ToU32(imgui.ImVec4(unpack({1.0, 1.0, 1.0, 1.0}))),
        24
    )

    local dotAlpha = state.isActive and 1.0 or 0.8
    DL:AddCircleFilled(
        imgui.ImVec2(thumbX, trackY),
        (thumbRadius * state.thumbScale) * 0.4,
        imgui.ColorConvertFloat4ToU32(imgui.ImVec4(unpack({accent[1], accent[2], accent[3], dotAlpha}))),
        12
    )

    imgui.SetCursorScreenPos(imgui.ImVec2(cursorPosition.x, cursorPosition.y + thumbSize + 8))
 
    return valueReference[0]
end
Пример использования:
Lua:
local showWindow = imgui.new.bool(true)

local volume = imgui.new.float(0.75)
local brightness = imgui.new.float(0.5)
local contrast = imgui.new.float(0.3)
local saturation = imgui.new.float(0.8)
local temperature = imgui.new.float(0.6)

local colorBlue = {0.00, 0.78, 1.00, 1.0}
local colorPink = {0.98, 0.16, 0.65, 1.0}
local colorGreen = {0.00, 1.00, 0.53, 1.0}
local colorPurple = {0.68, 0.32, 1.00, 1.0}
local colorOrange = {1.00, 0.65, 0.00, 1.0}

imgui.OnFrame(function()
    return showWindow[0] end, function()
    imgui.SetNextWindowSize(imgui.ImVec2(400, 500), imgui.Cond.FirstUseEver)
    imgui.Begin('Material Sliders - Classic', showWindow)

    imgui.TextColored(imgui.ImVec4(0.0, 0.78, 1.0, 1), 'Classic Material Sliders')
    imgui.Separator()
    imgui.Spacing()

    imgui.Text('Audio Settings:')
    imgui.MaterialSlider('Volume', volume, 0.0, 1.0, 280, 6, colorBlue)
    imgui.SameLine(0, 10)
    imgui.Text(string.format('Value: %.0f%%', volume[0] * 100))

    imgui.Spacing()
    imgui.Text('Display Settings:')
    imgui.MaterialSlider('Brightness', brightness, 0.0, 100.0, 280, 6, colorOrange)
    imgui.SameLine(0, 10)
    imgui.Text(string.format('Value: %.0f', brightness[0]))

    imgui.Spacing()
    imgui.MaterialSlider('Contrast', contrast, 0.0, 2.0, 280, 6, colorPink)
    imgui.SameLine(0, 10)
    imgui.Text(string.format('Value: %.2f', contrast[0]))

    imgui.Spacing()
    imgui.Text('Color Settings:')
    imgui.MaterialSlider('Saturation', saturation, 0.0, 2.0, 280, 6, colorGreen)
    imgui.SameLine(0, 10)
    imgui.Text(string.format('Value: %.2f', saturation[0]))

    imgui.Spacing()
    imgui.MaterialSlider('Temperature', temperature, 0.0, 1.0, 280, 6, colorPurple)
    imgui.SameLine(0, 10)
    imgui.Text(string.format('Value: %.2f', temperature[0]))

    imgui.Spacing()
    imgui.Separator()
    imgui.Spacing()

    imgui.Text('Features:')
    imgui.BulletText('Clean white thumb with accent dot')
    imgui.BulletText('No neon effects or glows')
    imgui.BulletText('Smooth value interpolation')
    imgui.BulletText('Subtle scaling on interaction')
    imgui.BulletText('Professional minimal design')

    imgui.Spacing()
    imgui.Separator()

    if imgui.Button('Test Animation', imgui.ImVec2(140, 30)) then
        volume[0] = volume[0] > 0.5 and 0.2 or 0.9
        brightness[0] = brightness[0] > 50 and 20 or 80
        contrast[0] = contrast[0] > 1.0 and 0.3 or 1.7
    end

    imgui.SameLine(0, 10)

    if imgui.Button('Reset All', imgui.ImVec2(120, 30)) then
        volume[0] = 0.75
        brightness[0] = 50.0
        contrast[0] = 1.0
        saturation[0] = 1.0
        temperature[0] = 0.5
    end

    imgui.SameLine(0, 10)

    if imgui.Button('Close', imgui.ImVec2(120, 30)) then
        showWindow[0] = false
    end

    imgui.End()
end)
Image number 3.PNG
 
Последнее редактирование:

pathtohell

Участник
7
36
Описание: Бесконечный загрузочный индикатор
Код:
Lua:
local infinityStates = {}

---@param label string Уникальный идентификатор для хранения состояния анимации
---@param size number Общая ширина элемента
---@param thickness number Толщина линии
---@param activeColor table {r, g, b, a} от 0.0 до 1.0
---@param backgroundColor table {r, g, b, a} от 0.0 до 1.0
function imgui.InfinitySpinner(label, size, thickness, activeColor, backgroundColor)
    local draw_list = imgui.GetWindowDrawList()
    local pos = imgui.GetCursorScreenPos()
    local time = imgui.GetTime()
    
    local width = size or 100
    local height = width / 2.2
    local thickness = thickness or 4
    local num_segments = 100

    if not infinityStates[label] then
        infinityStates[label] = { last_time = time }
    end

    local col_bg = imgui.ColorConvertFloat4ToU32(imgui.ImVec4(unpack(backgroundColor or {0.2, 0.2, 0.2, 0.3})))
    local col_active = imgui.ColorConvertFloat4ToU32(imgui.ImVec4(unpack(activeColor or {0.0, 0.0, 0.0, 1.0})))

    local function getInfinityPoint(t, center, a)
        local sin_t = math.sin(t)
        local cos_t = math.cos(t)
        local denom = 1 + sin_t * sin_t
        local x = (a * cos_t) / denom
        local y = (a * sin_t * cos_t) / denom
        return imgui.ImVec2(center.x + x, center.y + y)
    end

    local center = imgui.ImVec2(pos.x + width / 2, pos.y + height / 2)
    local a = width / 2

    draw_list:PathClear()
    for i = 0, num_segments do
        local t = (i / num_segments) * math.pi * 2
        draw_list:PathLineTo(getInfinityPoint(t, center, a))
    end
    draw_list:PathStroke(col_bg, true, thickness)

    local speed = 3.0
    local segment_length = 1.2
    local start_t = time * speed
    local end_t = start_t + segment_length

    draw_list:PathClear()
    for i = 0, 30 do
        local t = start_t + (i / 30) * (end_t - start_t)
        draw_list:PathLineTo(getInfinityPoint(t, center, a))
    end
    draw_list:PathStroke(col_active, false, thickness)

    imgui.Dummy(imgui.ImVec2(width, height))
end
Пример использования:
Lua:
imgui.InfinitySpinner('loader', 120, 5, {1, 1, 1, 1}, {5, 5, 5, 0.1})

what.gif
 
  • Вау
  • Нравится
Реакции: Willy4ka, Winstаl и XRLM