Metal FX
Wraps a button or icon in an animated liquid-metal ring. One shared WebGL renderer drives every instance on the page. Vue port of metal-fx by Jakub Antalik, MIT licensed.
Default
Wrap a single element. MetalFx measures it every frame, becomes the visible surface, and strips the child's own border, background and shadow so the ring is the only edge.
In a composer
The send button as a gold circle, with the neighbouring chip picking up a soft reflection of the metal. Reflections only render on dark surfaces.
Build anything...
In a toolbar
A chromatic pill between a search field and an icon button, both of which are passed as reflection targets.
Variants
button is the pill baseline (1px ring, shader scale 1.6); circle is tuned for compact icon buttons (2px ring, scale 1.3) and always resolves a true circle.
Color presets
Three palettes, each with its own dark and light tuning. Because one WebGL renderer feeds every instance, the preset is page-global: the most recently applied value wins, so switch it rather than rendering several at once.
Strength
strength scales the composited alpha of the shader and glow between 0 and 1. It is per instance and never touches the wrapped content.
Theme
auto follows the nearest data-theme attribute or dark/light class and updates live when the page theme flips. Pin it with light or dark for a fixed surface. Like preset, the resolved theme feeds the shared shader.
Paused
paused freezes this instance on its last painted frame, so the metal silhouette stays on screen. The shared loop keeps running for any other instance.
Playground
Every knob on one panel. Type and color use Toggle Group, strength uses Slider Ruler, and the button freezes the animation.
API Reference
MetalFx
Accessibility
Keyboard shortcuts and ARIA behavior.
- The canvas, inner spacer and glow layers are decorative, marked aria-hidden and non-interactive, so focus and screen readers reach the wrapped control unchanged.
- Pointer events pass through the effect layers to the child, so the wrapped button stays clickable and keyboard focusable.
- Each instance stops compositing when scrolled offscreen (IntersectionObserver with a 64px margin) and resumes on the way back in.
- One shared WebGL canvas serves every instance on the page, and the wrapper stays hidden until its first frame is painted, so there is no flash of an unsized canvas.