hotline 0.0.1

Draw lines that are on fire using SDL3
Documentation
use hotline::{FireLine, FireParams, FireRenderer};
use sdl3::event::Event;
use sdl3::mouse::MouseButton;
use sdl3::pixels::Color;
use std::time::Instant;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize SDL3
    let sdl = sdl3::init()?;
    let video = sdl.video()?;

    // Create window
    let window = video
        .window("Hotline - Interactive Example (Click and drag to draw)", 800, 600)
        .position_centered()
        .build()
        .map_err(|e| e.to_string())?;

    let canvas = window.into_canvas();
    let mut renderer = FireRenderer::new(canvas);

    let mut event_pump = sdl.event_pump()?;
    let start_time = Instant::now();

    let mut lines: Vec<FireLine> = Vec::new();
    let mut drawing = false;
    let mut current_start: Option<(f32, f32)> = None;

    let params = FireParams {
        flame_height: 70.0,
        intensity: 1.0,
        flicker_speed: 2.5,
        particle_density: 1.0,
        flame_width: 25.0,
    };

    'running: loop {
        // Handle events
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit { .. } => break 'running,
                Event::MouseButtonDown {
                    mouse_btn: MouseButton::Left,
                    x,
                    y,
                    ..
                } => {
                    drawing = true;
                    current_start = Some((x as f32, y as f32));
                }
                Event::MouseButtonUp {
                    mouse_btn: MouseButton::Left,
                    x,
                    y,
                    ..
                } => {
                    if drawing {
                        if let Some((start_x, start_y)) = current_start {
                            // Create a new fire line
                            let line = FireLine::new(
                                start_x,
                                start_y,
                                x as f32,
                                y as f32,
                                params,
                            );
                            lines.push(line);
                        }
                        drawing = false;
                        current_start = None;
                    }
                }
                Event::KeyDown { .. } => {
                    // Clear all lines on any key press
                    lines.clear();
                }
                _ => {}
            }
        }

        // Get elapsed time in seconds
        let time = start_time.elapsed().as_secs_f32();

        // Clear canvas
        renderer.canvas_mut().set_draw_color(Color::RGB(0, 0, 0));
        renderer.canvas_mut().clear();

        // Render all completed fire lines
        for line in &lines {
            renderer.render(line, time)?;
        }

        // If currently drawing, show a preview line
        if drawing {
            if let Some((start_x, start_y)) = current_start {
                let mouse_state = event_pump.mouse_state();
                let preview_line = FireLine::new(
                    start_x,
                    start_y,
                    mouse_state.x() as f32,
                    mouse_state.y() as f32,
                    params,
                );
                renderer.render(&preview_line, time)?;
            }
        }

        // Present
        renderer.present();

        // Small delay
        std::thread::sleep(std::time::Duration::from_millis(16));
    }

    Ok(())
}