DitherButton

A button with an animated 4x4 ordered-dither wave background and a knockout label.

Preview

Loading GPUI

Variants

Rounded pill

Loading GPUI
DitherButton::new("press-start", "Press Start")
    .colors(rgb(0x10b981), background)
    .radius(9999.0)
    .padding(40.0, 12.0)
    .letter_spacing(0.1)
    .dither_color(rgb(0x10b981))
    .dither_opacity(0.5)

Hot pink

Loading GPUI
DitherButton::new("synthwave", "Synthwave")
    .colors(rgb(0xf472b6), rgb(0x1e1b4b))
    .radius(0.0)
    .dither_color(rgb(0xf472b6))
    .dither_opacity(0.5)

Tiny chip

Loading GPUI
DitherButton::new("version", "v0.1.0")
    .border_width(1.0)
    .padding(12.0, 4.0)
    .text_size(12.0, 16.0)

Chunky dither

Loading GPUI
DitherButton::new("boss", "Boss Mode").dither_size(10.0)

Fine dither

Loading GPUI
DitherButton::new("hi-res", "Hi-Res")
    .dither_size(2.0)
    .dither_opacity(0.7)

Install

cargo add evilbuttons

Usage

use evilbuttons::DitherButton;
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(
            DitherButton::new("launch", "Launch")
                .colors(rgb(0xfafafa), rgb(0x0a0a0a))
                .font_family("Geist Mono"),
        )
    }
}

Props

DitherButton is a GPUI RenderOnce builder; its animation clock is keyed by id.

MethodTypeDefaultDescription
new(id, label)impl Into<ElementId>, impl Into<SharedString>-Unique id and the label (shown uppercase).
dither_color(c)impl Into<Hsla>#999999Color of the dither's "on" pixels.
dither_background(c)impl Into<Hsla>#000000Color of the dither's "off" pixels.
dither_opacity(o)f32 (0–1)1.0Opacity of the whole dither layer.
dither_size(px)f32 (1–32)4.0Pixel scale of the dither particles. Higher = chunkier blocks.
colors(fg, bg)impl Into<Hsla>, impl Into<Hsla>#fafafa, #0a0a0aText/border color and button background. Pass your page's foreground and background.
knockout(c)impl Into<Hsla>button backgroundColor of the outline that knocks the label out of the dither (the page background in the original).
border_width(px)f322.0Border width.
radius(px)f326.0Corner radius; a large value makes a pill.
padding(x, y)f32, f3228.0, 12.0Horizontal and vertical padding.
text_size(size, line_height)f32, f3214.0, 20.0Font size and line height.
letter_spacing(em)f320.05Letter spacing in em.
font_family(name)impl Into<SharedString>inheritedLabel font, e.g. your monospace font.
on_click(f)Fn(&ClickEvent, &mut Window, &mut App)-Fired on click, and on Space/Enter while focused.
disabled(bool)boolfalseDims the button and ignores input.

Good to know

  • The dither is painted as merged runs of quads every frame, with the same 4×4 Bayer thresholds and wave as the original canvas.
  • The original canvas resolves its transparent background-color to black, so "off" pixels are black in both themes; dither_background changes that.
  • GPUI has no theme-aware CSS colors, so pass your foreground and background with colors and knockout.

Search docs

Jump to a button documentation page