StickyButton

A magnetic button whose body and label are pulled toward the cursor from a wide field, with parallax depth and tilt.

Preview

Loading GPUI

Props

Install

cargo add evilbuttons

Usage

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

struct ButtonDemo;

impl Render for ButtonDemo {
    fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
        div().child(StickyButton::new("launch", "Launch"))
    }
}

Variants

Clingy

A wider field and a stronger pull make the button chase the cursor from far away.

Loading GPUI
StickyButton::new("clingy", "Can't Escape")
    .radius(220.0)
    .strength(0.7)
    .parallax(0.6)

Subtle

A tight field with no tilt, for a gentle magnetic nudge.

Loading GPUI
StickyButton::new("subtle", "Barely Sticky")
    .radius(60.0)
    .strength(0.25)
    .parallax(0.2)
    .tilt(0.0)

Props

StickyButton is a GPUI RenderOnce builder; its springs are keyed by id.

MethodTypeDefaultDescription
new(id, label)impl Into<ElementId>, impl Into<SharedString>-Unique id and the button label.
radius(px)f32120.0Distance in px beyond the button's edge where the pull starts.
strength(f)f320.45How far the body follows the cursor, as a fraction of the cursor offset.
parallax(f)f320.35How far the label drifts inside the body, from 0 (fixed to the body) to 1 (the edge of its padding).
tilt(deg)f328.0Maximum tilt in degrees while the body is pulled.
background(c)impl Into<Hsla>theme backgroundFace color. Defaults to shadcn's --background for the window's appearance.
foreground(c)impl Into<Hsla>theme foregroundLabel and spotlight color.
border_color(c)impl Into<Hsla>theme borderDashed border color.
on_click(f)Fn(&ClickEvent, &mut Window, &mut App)-Fired on click, and on Space/Enter while focused.
disabled(bool)boolfalseDims the button and turns the pull off.

Good to know

  • The pull fades smoothly to zero at the field's edge, and releases when the pointer leaves the window.
  • GPUI has no 3D transforms, so the body's outline is tilted and projected in perspective by hand; the label moves with it but stays flat.

Search docs

Jump to a button documentation page