Ember UI / Fire Button v1.0 · Canvas
Interactive component

Buttons that feel alive.

A toggle with a real flame inside. It is drawn live on canvas from its own state and dressed in embers, heat and a little bit of chaos.

Tap to ignite Hold to supercharge Space Enter work too
0Ignitions
0Supercharges
Heat 0%
FLAME STATE
Size
Label
Surface
Effects
Variants

One flame, many moods.

Every variant is the same element configured with data attributes, from a primary call to action to a habit tracker that earns its fire.

Primary

The hero toggle, with label swap and heat ring.

data-size="lg"

Icon only

Round socket for toolbars and dense UI.

data-variant="icon"

Light surface

A cream body; the socket stays dark so the flame still glows.

data-surface="light"
Daily writing 6-day streak

In context

Listens for firebutton:change to keep a streak.

addEventListener
Anatomy

What's burning inside.

Three layers work together: the canvas flame, the interaction model and a shared ember engine.

01

Living flame

Layered teardrops, licking tongues and additive particles, redrawn every frame from four inputs. ON mirrors aria-pressed; Hover follows the pointer and keyboard focus.

02

Tap vs. hold

A quick press toggles. Hold past 250ms and a ring charges around the socket; complete it in 900ms to supercharge.

03

Ember engine

One fixed canvas serves every button: additive-blended embers, smoke on extinguish, and an ambient trickle while lit.

Usage

Drop it in. Light it up.

Write a plain button with data attributes. FireButton.upgradeAll() builds the socket, label and flame canvas for you.

index.html
<!-- Declarative: the script builds the inside -->
<button class="fb" type="button"
        data-size="lg"
        data-off="Ignite" data-on="On fire"></button>

<script src="fire-button.js"></script>
<script>
  const [button] = FireButton.upgradeAll();

  button.el.addEventListener("firebutton:change", (e) => {
    console.log("lit?", e.detail.on);
  });

  button.set(true);      // ignite from code
  button.supercharge();  // or go all in
</script>

Attributes

data-sizesm · md · lg · xl
data-off / data-onLabel for each state
data-varianticon
data-surfacelight
aria-pressedInitial state

Methods & events

set(on)Ignite or extinguish
toggle()Flip state
supercharge()Big burst, lights if off
firebutton:changedetail: { on }
firebutton:superchargeFires after a full charge
Your turn

Go on, set it off.

Hold the button until the ring closes. We promise nothing actually catches fire.