AshBurstButton

A ringed dark button that glows like an ember on click and erupts ash that collides with it via a small physics simulation, piling onto its surface.

Preview

Loading GPUI

Props

Install

cargo add evilbuttons

Usage

use evilbuttons::AshBurstButton;
use gpui::{div, prelude::*, rgb, Context, IntoElement, Render, Window};

struct ButtonDemo;

impl Render for ButtonDemo {
    fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
        div().child(
            AshBurstButton::new("incinerate")
                .label("Incinerate")
                .colors([rgb(0x171717), rgb(0x404040), rgb(0x737373), rgb(0xf97316)])
                .particle_count(120)
                .on_destroy(|_, _| println!("Burned.")),
        )
    }
}

Props

AshBurstButton is a GPUI RenderOnce builder; its simulation state is keyed by id. on_click still fires before the burst.

MethodTypeDefaultDescription
new(id)impl Into<ElementId>-Unique id for the button's state.
label(s)impl Into<SharedString>"Delete"Button label.
particle_count(n)usize80Physics particles per burst (at least 12).
spread(deg)f32110.0Explosion spread in degrees.
start_velocity(v)f3242.0Launch velocity, in Matter.js units (px per 60Hz step).
colors(iter)IntoIterator<Item = impl Into<Hsla>>charcoal/ember paletteCustom particle colors. Warm reds and oranges get a soft glow.
icon(bool)booltrueShow the leading flame icon.
on_click(f)Fn(&ClickEvent, &mut Window, &mut App)-Fired on every click, before the burst.
on_destroy(f)Fn(&mut Window, &mut App)-Fired after each ash burst.
disabled(bool)boolfalseDims the button and ignores input.

Good to know

  • No Matter.js: the ash is a small built-in rigid-body simulation with Matter's gravity, air friction, restitution and friction per particle, colliding with the button, two lips on its top corners, and each other. Pieces collide as circles, so piles settle a little rounder than Matter's boxes.
  • Ash is painted on an unclipped overlay above everything else in the window, so it flies past the button's bounds.
  • The simulation runs in real time at a fixed 60Hz step, so it looks the same on high-refresh displays.

Search docs

Jump to a button documentation page