opui 0.1.0

A Rust library for stylish realtime 2D motion visuals and layered hero scenes.
Documentation
use macroquad::prelude::*;
use opui::{FrameContext, Scene, VisualApp, presets};

fn window_conf() -> Conf {
    Conf {
        window_title: "OpUI Showcase".to_string(),
        window_width: 1440,
        window_height: 900,
        high_dpi: true,
        sample_count: 4,
        ..Default::default()
    }
}

enum ShowcaseMode {
    LiquidGlass,
    AuroraBloom,
    NeonFlow,
}

struct Showcase {
    mode: ShowcaseMode,
    liquid_glass: opui::LayerScene,
    aurora_bloom: opui::LayerScene,
    neon_flow: opui::LayerScene,
    ui_font: Option<Font>,
}

impl Showcase {
    fn new(ui_font: Option<Font>) -> Self {
        Self {
            mode: ShowcaseMode::LiquidGlass,
            liquid_glass: presets::liquid_glass(),
            aurora_bloom: presets::aurora_bloom(),
            neon_flow: presets::neon_flow(),
            ui_font,
        }
    }

    fn active_scene_mut(&mut self) -> &mut opui::LayerScene {
        match self.mode {
            ShowcaseMode::LiquidGlass => &mut self.liquid_glass,
            ShowcaseMode::AuroraBloom => &mut self.aurora_bloom,
            ShowcaseMode::NeonFlow => &mut self.neon_flow,
        }
    }

    fn active_scene(&self) -> &opui::LayerScene {
        match self.mode {
            ShowcaseMode::LiquidGlass => &self.liquid_glass,
            ShowcaseMode::AuroraBloom => &self.aurora_bloom,
            ShowcaseMode::NeonFlow => &self.neon_flow,
        }
    }

    fn mode_name(&self) -> &'static str {
        match self.mode {
            ShowcaseMode::LiquidGlass => "Liquid Glass",
            ShowcaseMode::AuroraBloom => "Aurora Bloom",
            ShowcaseMode::NeonFlow => "Neon Flow",
        }
    }

    fn mode_desc(&self) -> &'static str {
        match self.mode {
            ShowcaseMode::LiquidGlass => "Glass waves, particle mist, liquid orbs",
            ShowcaseMode::AuroraBloom => "Soft aurora halo and premium ambient motion",
            ShowcaseMode::NeonFlow => "Sharper neon energy with club-like motion trails",
        }
    }

    fn draw_text_line(&self, text: &str, x: f32, y: f32, font_size: u16, color: Color) {
        draw_text_ex(
            text,
            x,
            y,
            TextParams {
                font: self.ui_font.as_ref(),
                font_size,
                color,
                ..Default::default()
            },
        );
    }

    fn draw_overlay(&self, ctx: &FrameContext) {
        draw_rectangle(
            24.0,
            24.0,
            520.0,
            148.0,
            Color::new(0.03, 0.05, 0.09, 0.58),
        );

        self.draw_text_line("OpUI Showcase", 42.0, 64.0, 40, WHITE);
        self.draw_text_line(self.mode_name(), 42.0, 102.0, 28, Color::new(0.72, 0.95, 1.0, 0.95));
        self.draw_text_line(
            self.mode_desc(),
            42.0,
            130.0,
            18,
            Color::new(1.0, 1.0, 1.0, 0.66),
        );
        self.draw_text_line(
            "Press 1 / 2 / 3 to switch scenes. Move the mouse to bend the motion field.",
            42.0,
            154.0,
            18,
            Color::new(1.0, 1.0, 1.0, 0.58),
        );

        draw_rectangle(
            24.0,
            ctx.height - 82.0,
            560.0,
            46.0,
            Color::new(0.03, 0.05, 0.09, 0.46),
        );
        self.draw_text_line(
            "These scenes are built from OpUI layers: gradients, halos, mist, waves, liquid orbs, scanlines.",
            42.0,
            ctx.height - 52.0,
            18,
            Color::new(1.0, 1.0, 1.0, 0.64),
        );
    }
}

impl Scene for Showcase {
    fn update(&mut self, ctx: &FrameContext) {
        if is_key_pressed(KeyCode::Key1) {
            self.mode = ShowcaseMode::LiquidGlass;
        }
        if is_key_pressed(KeyCode::Key2) {
            self.mode = ShowcaseMode::AuroraBloom;
        }
        if is_key_pressed(KeyCode::Key3) {
            self.mode = ShowcaseMode::NeonFlow;
        }

        self.active_scene_mut().update(ctx);
    }

    fn draw(&self, ctx: &FrameContext) {
        self.active_scene().draw(ctx);
        set_default_camera();
        self.draw_overlay(ctx);
    }
}

#[macroquad::main(window_conf)]
async fn main() {
    let ui_font = load_ttf_font("C:\\Windows\\Fonts\\segoeui.ttf").await.ok();
    let showcase = Showcase::new(ui_font);
    VisualApp::new(showcase)
        .clear_color(color_u8!(3, 5, 12, 255))
        .run()
        .await;
}