• Ищем качественного (не новичок) разработчиков Xenforo для этого форума! В идеале, чтобы ты был фулл стек программистом. Если у тебя есть что показать, то свяжись с нами по контактным данным: https://t.me/DREDD

Исходник Animated button // supremacy c+p ready

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
15 Окт 2019
Сообщения
45
Реакции
8
complete overhaul soon...

button.h:
Expand Collapse Copy
#pragma once

#define BUTTON_X_OFFSET      20
#define BUTTON_BOX_HEIGHT    20
#define BUTTON_ITEM_X_OFFSET 10

class Button : public Element {
    friend class GUI;

public:
    __forceinline Button() : m_label{} {
        m_flags = DRAW | CLICK;
        m_type = BUTTON;
        m_base_h = m_h = BUTTON_BOX_HEIGHT;
        m_use_label = false;
    }

    __forceinline void setup(const std::string& label) {
        m_label = label;
    }

protected:
    std::string m_label;

    void draw() override;
    void click() override;
};

button.cpp:
Expand Collapse Copy
#include "../../../includes.h"

// button animation state.
struct ButtonAnimState {
    float bg_lerp;      // background color lerp [0..1].
    float border_lerp;  // border color lerp [0..1].
    float scale_lerp;   // scale lerp [0..1].
    bool hovered;
    bool pressed;
    bool initialized;

    ButtonAnimState() : bg_lerp(0.f), border_lerp(0.f), scale_lerp(0.f), hovered(false), pressed(false), initialized(false) {}
};

void Button::draw() {
    Rect area{ m_parent->GetElementsRect() };
    Point p{ area.x + m_pos.x, area.y + m_pos.y };

    // static anim state per button.
    static std::unordered_map<Button*, ButtonAnimState> anims;
    ButtonAnimState& anim = anims[this];

    // button area.
    Rect btn_rect = { p.x + BUTTON_X_OFFSET, p.y, m_w - BUTTON_X_OFFSET, BUTTON_BOX_HEIGHT };

    // check hover and pressed state.
    bool is_hovered = g_input.IsCursorInRect(btn_rect);
    bool is_pressed = is_hovered && g_input.GetKeyState(VK_LBUTTON);

    // update anim state.
    float speed = 10.0f * g_csgo.m_globals->m_frametime;
    if (!anim.initialized) {
        anim.bg_lerp = anim.border_lerp = anim.scale_lerp = 0.f;
        anim.hovered = is_hovered;
        anim.pressed = is_pressed;
        anim.initialized = true;
    }

    // lerp background color.
    float target_bg = is_hovered ? 1.f : 0.f;
    anim.bg_lerp += (target_bg - anim.bg_lerp) * speed;

    // lerp border color.
    float target_border = is_pressed ? 1.f : (is_hovered ? 1.f : 0.f);
    anim.border_lerp += (target_border - anim.border_lerp) * speed;

    // lerp scale.
    float target_scale = is_pressed ? 1.04f : (is_hovered ? 1.02f : 1.f);
    anim.scale_lerp += (target_scale - anim.scale_lerp) * speed;

    // compute colors.
    Color base_bg = { 41, 41, 41, m_parent->m_alpha };
    Color hover_bg = { 60, 60, 60, m_parent->m_alpha };
    Color bg_col = Color(
        (int)(base_bg.r() + (hover_bg.r() - base_bg.r()) * anim.bg_lerp),
        (int)(base_bg.g() + (hover_bg.g() - base_bg.g()) * anim.bg_lerp),
        (int)(base_bg.b() + (hover_bg.b() - base_bg.b()) * anim.bg_lerp),
        m_parent->m_alpha
    );

    Color base_border = { 0, 0, 0, m_parent->m_alpha };
    Color hover_border = g_gui.m_color;
    hover_border.a() = m_parent->m_alpha;
    Color press_border = g_gui.m_color;
    press_border.a() = m_parent->m_alpha;

    // border color interpolation.
    Color border_col = base_border;
    if (anim.border_lerp > 0.f) {
        border_col = Color(
            (int)(base_border.r() + (hover_border.r() - base_border.r()) * anim.border_lerp),
            (int)(base_border.g() + (hover_border.g() - base_border.g()) * anim.border_lerp),
            (int)(base_border.b() + (hover_border.b() - base_border.b()) * anim.border_lerp),
            m_parent->m_alpha
        );
    }

    // scale effect.
    float scale = anim.scale_lerp;
    int cx = p.x + BUTTON_X_OFFSET + (m_w - BUTTON_X_OFFSET) / 2;
    int cy = p.y + BUTTON_BOX_HEIGHT / 2;
    int w = int((m_w - BUTTON_X_OFFSET) * scale);
    int h = int(BUTTON_BOX_HEIGHT * scale);
    int x = cx - w / 2;
    int y = cy - h / 2;

    // box outline.
    render::rect(x, y, w, h, border_col);

    // inner blob.
    render::rect_filled(x + 1, y + 1, w - 2, h - 2, bg_col);

    // button name.
    render::menu.string(cx, y + 4, { 205, 205, 205, m_parent->m_alpha }, m_label, render::ALIGN_CENTER);
}

void Button::click() {
    Rect area{ m_parent->GetElementsRect() };
    Point p{ area.x + m_pos.x, area.y + m_pos.y };

    // area where user has to click.
    Rect btn = { p.x + BUTTON_X_OFFSET, p.y, m_w - BUTTON_X_OFFSET, BUTTON_BOX_HEIGHT };

    if (g_input.IsCursorInRect(btn) && m_callback)
        m_callback();
}
 
Назад
Сверху Снизу