### Install metal-fx with npm
Source: https://github.com/jakubantalik/metal-fx/blob/main/README.md
Use npm to install the metal-fx package.
```bash
npm install metal-fx
```
--------------------------------
### Example Preset Object
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-presets.md
Illustrates how to construct a Preset object, specifying the name and providing configurations for both dark and light modes.
```typescript
const preset: Preset = {
name: 'chromatic',
modes: {
dark: { /* dark-mode settings */ },
light: { /* light-mode settings */ },
},
};
```
--------------------------------
### Install and Import Metal-FX
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/quick-reference.md
Install the metal-fx package using npm and import the MetalFx component.
```typescript
npm install metal-fx
import { MetalFx } from 'metal-fx';
```
--------------------------------
### Non-React Integration Example
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-renderer.md
Demonstrates how to create, update, and destroy Metal-FX instances in a vanilla JavaScript environment. Includes setting shared presets and handling window resize and unload events.
```typescript
import {
createInstance,
updateInstance,
destroyInstance,
setSharedPreset,
registerGlowInstance,
setGlowCallback,
} from 'metal-fx';
// Create a wrapper div and canvas
const wrapper = document.createElement('div');
const canvas = document.createElement('canvas');
wrapper.appendChild(canvas);
document.body.appendChild(wrapper);
// Create instance
const inst = createInstance({
hostCanvas: canvas,
cssWidth: 140,
cssHeight: 40,
cornerRadius: 20,
kind: 'pill',
});
// Respond to resize
window.addEventListener('resize', () => {
const rect = wrapper.getBoundingClientRect();
updateInstance(inst, {
cssWidth: rect.width,
cssHeight: rect.height,
});
});
// Set preset
setSharedPreset('gold', 'dark');
// Cleanup on unmount
window.addEventListener('beforeunload', () => {
destroyInstance(inst);
});
```
--------------------------------
### Basic MetalFX Button Usage
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-metalfx.md
Demonstrates the basic integration of MetalFX with a button element. Ensure 'metal-fx' is installed and imported.
```typescript
import { MetalFx } from 'metal-fx';
export function App() {
return (
);
}
```
--------------------------------
### Manual Metal-FX Renderer Setup
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/index.md
Shows how to manually create and manage a Metal-FX instance outside of a React environment. This includes importing necessary functions, creating a canvas element, and initializing the instance with specific properties. Remember to destroy the instance when it's no longer needed.
```typescript
import { createInstance, destroyInstance } from 'metal-fx';
const canvas = document.createElement('canvas');
const inst = createInstance({
hostCanvas: canvas,
cssWidth: 140,
cssHeight: 40,
cornerRadius: 20,
kind: 'pill',
});
// Later:
destroyInstance(inst);
```
--------------------------------
### hexToRgb Examples
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-presets.md
Demonstrates the usage of the hexToRgb function with different hex color string formats, including 6-digit and 3-digit hex codes.
```typescript
hexToRgb('#ff0000'); // [1, 0, 0]
hexToRgb('#f0f'); // [1, 0, 1]
hexToRgb('#00ff00'); // [0, 1, 0]
```
--------------------------------
### createInstance
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-renderer.md
Creates a new renderer instance and registers it with the shared WebGL renderer. It ensures the shared renderer exists, resizes the host canvas, adds the instance to the active set, and starts the animation loop if necessary.
```APIDOC
## createInstance
### Description
Creates a new renderer instance and registers it with the shared WebGL renderer.
### Method
```typescript
function createInstance(opts: CreateInstanceOptions): MetalFxInstance
```
### Parameters
#### Path Parameters
- **opts.hostCanvas** (HTMLCanvasElement) - Required - The 2D canvas to composite onto.
- **opts.cssWidth** (number) - Required - CSS width in pixels.
- **opts.cssHeight** (number) - Required - CSS height in pixels.
- **opts.cornerRadius** (number) - Required - Rounded corner radius in pixels.
- **opts.kind** ('pill' | 'circle') - Required - Shape hint for shader sampling.
- **opts.shaderScale** (number) - Optional - Shader sampling zoom.
- **opts.ringCssPx** (number) - Optional - Ring stroke width in CSS px.
- **opts.opacityMul** (number) - Optional - Effect opacity multiplier (0..1).
- **opts.paused** (boolean) - Optional - Start in paused state.
- **opts.scale** (number) - Optional - Master scale multiplier for internals.
- **opts.onAfterFrame** (() => void) - Optional - Callback fired after each frame's compositing.
- **opts.onFirstCopy** (() => void) - Optional - One-shot callback after first successful paint.
### Response
#### Success Response (MetalFxInstance)
Returns a MetalFxInstance object.
### Example
```typescript
const canvas = document.createElement('canvas');
const inst = createInstance({
hostCanvas: canvas,
cssWidth: 140,
cssHeight: 40,
cornerRadius: 20,
kind: 'pill',
shaderScale: 1.6,
onFirstCopy: () => console.log('First frame painted'),
});
```
```
--------------------------------
### Manual Reflection Control Example
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-reflection.md
Demonstrates how to manually add and remove reflection targets using the Metal-FX API. Ensure the necessary elements exist in the DOM and you have a MetalFxInstance.
```typescript
import { addReflectionTarget, removeReflectionTarget } from 'metal-fx';
const chipEl = document.getElementById('chip');
const inst = /* MetalFxInstance from createInstance() */;
const anchorEl = document.getElementById('anchor');
// Add reflection
const target = addReflectionTarget(chipEl, inst, anchorEl);
if (!target) console.error('Could not add reflection (blocked tag?)');
// Later: remove reflection
removeReflectionTarget(chipEl);
```
--------------------------------
### Metal-FX Component Mount Flow
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/architecture.md
Illustrates the sequence of operations when the Metal-FX component is mounted, including style injection, theme resolution, instance creation, and observer setup.
```markdown
render
↓
ensureStylesInjected() [module scope, once]
↓
useResolvedTheme() [determine initial theme]
↓
useLayoutEffect() [synchronous, before paint]
├→ createInstance()
│ ├→ ensureSharedRenderer() [creates if needed]
│ ├→ resizeInstanceCanvas()
│ └→ Adds to renderer.instances
├→ injectGlow() [if glow enabled]
│ └→ Builds perimeter table
├→ registerGlowInstance() [adds to queue]
├→ ResizeObserver [watches wrapper size]
└→ IntersectionObserver [watches visibility]
↓
onFirstCopy callback [fires after first frame]
↓
setState(ready) [opacity 0→1 transition]
```
--------------------------------
### Custom Color Adjustment for Light Mode
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-color.md
Example demonstrating how to adjust a color from dark mode for use in light mode by boosting saturation and modifying brightness using RGB to HSV conversions. Requires importing `rgbToHsv` and `hsvToRgb`.
```typescript
import { rgbToHsv, hsvToRgb } from 'metal-fx';
// Glow color from dark mode
const darkModeColor = sampleShaderRGBAt(instance, x, y);
// Boost saturation and brightness for light mode
const [h, s, v] = rgbToHsv(darkModeColor.r, darkModeColor.g, darkModeColor.b);
const lightModeColor = hsvToRgb(
h,
Math.min(1, s * 2.625), // LT_SAT_BOOST
Math.max(0.31, v * 1.008) // LT_MIN_VAL, LT_VAL_MULT
);
console.log(`Light mode color: rgb(${lightModeColor[0]}, ${lightModeColor[1]}, ${lightModeColor[2]})`);
```
--------------------------------
### Create Renderer Instance
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-renderer.md
Use this function to create a new renderer instance and register it with the shared WebGL renderer. It ensures the shared renderer exists, resizes the host canvas, and starts the animation loop if necessary.
```typescript
function createInstance(opts: CreateInstanceOptions): MetalFxInstance
```
```typescript
const canvas = document.createElement('canvas');
const inst = createInstance({
hostCanvas: canvas,
cssWidth: 140,
cssHeight: 40,
cornerRadius: 20,
kind: 'pill',
shaderScale: 1.6,
onFirstCopy: () => console.log('First frame painted'),
});
```
--------------------------------
### Adjust Glow Animation Parameters
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/configuration.md
Modify constants in `src/engine/glow/glow.ts` to control the glow animation's behavior. This example makes the halo stickier to a point by increasing dwell time and relocation threshold.
```typescript
const MIN_DWELL_MS = 5000; // Was 3000: now halo stays put longer
const RELOCATE_DELTA = 0.08; // Was 0.05: harder to trigger relocation
```
--------------------------------
### Create Instance
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/quick-reference.md
Creates a new Metal-FX renderer instance with specified properties.
```APIDOC
## createInstance
### Description
Creates a new Metal-FX renderer instance.
### Method
`createInstance(props: MetalFxProps)`
### Parameters
- **props** (MetalFxProps) - Required - Configuration object for the instance.
- **hostCanvas** (HTMLCanvasElement) - Required - The canvas element to render on.
- **cssWidth** (number) - Required - The CSS width of the canvas.
- **cssHeight** (number) - Required - The CSS height of the canvas.
- **cornerRadius** (number) - Optional - The corner radius for pill-shaped instances.
- **kind** ('pill' | 'circle') - Optional - The shape kind of the instance.
### Request Example
```typescript
import { createInstance } from 'metal-fx';
const inst = createInstance({
hostCanvas,
cssWidth: 140,
cssHeight: 40,
cornerRadius: 20,
kind: 'pill',
});
```
### Response
- **MetalFxInstance** - The created renderer instance.
```
--------------------------------
### Get Shared Frame Count
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-renderer.md
Retrieves the total number of frames rendered since the shared renderer was initialized. Useful for performance monitoring.
```typescript
function getSharedFrameCount(): number
```
```typescript
const frameNum = getSharedFrameCount();
console.log(`Rendered ${frameNum} frames`);
```
--------------------------------
### Initial Render (SSR) and Client Hydration
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/architecture.md
Illustrates the server-side rendering approach with hidden canvas elements and the client-side hydration process using useLayoutEffect to initialize WebGL, SVG, and readiness state.
```html
Server:
Client hydration:
useLayoutEffect runs
├→ createInstance() [WebGL pipeline]
├→ injectGlow() [SVG markup]
└→ setReady(true) [opacity: 1]
```
--------------------------------
### Using CSS Variables for Styling
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/configuration.md
Demonstrates how to use the CSS custom properties exposed by Metal-FX to control opacity and border-radius.
```css
.metal-fx-root {
opacity: calc(0.5 + var(--mfx-strength) * 0.5);
border-radius: var(--mfx-radius);
}
```
--------------------------------
### Define Reflection Targets with `useRef`
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-reflection.md
Pass refs to sibling DOM elements that should receive reflections using the `reflectionTargets` prop. This example shows how to use `useRef` to capture references to button elements.
```typescript
const sendRef = useRef(null);
const chipRef = useRef(null);
<>
>
```
--------------------------------
### Mutating Presets at Runtime
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/configuration.md
Demonstrates how to modify preset configurations at runtime. This approach is not recommended for production environments.
```typescript
import { PRESETS } from 'metal-fx';
// Not recommended: mutating presets at runtime
PRESETS.chromatic.modes.dark.speed = 2.0;
```
--------------------------------
### Create Metal-FX Instance
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/quick-reference.md
Use `createInstance` to initialize a new Metal-FX renderer instance. Configure properties like canvas, dimensions, corner radius, and kind.
```typescript
import { createInstance } from 'metal-fx';
const inst = createInstance({
hostCanvas,
cssWidth: 140,
cssHeight: 40,
cornerRadius: 20,
kind: 'pill',
});
```
--------------------------------
### Basic Metal-FX Usage
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/README.md
Demonstrates basic usage of the MetalFx component with a button variant and a chromatic preset. Ensure 'metal-fx' is imported.
```typescript
import { MetalFx } from 'metal-fx';
```
--------------------------------
### Module Structure Overview
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/README.md
This diagram outlines the directory and file structure of the Metal-FX project, indicating the purpose of key files and modules.
```tree
src/
index.ts ← Entry point
MetalFx.tsx ← React component
types.ts ← Types
engine/
renderer/
core.ts ← WebGL setup
loop.ts ← Animation loop
sampling.ts ← Pixel readback
glow/
glow.ts ← SVG glow
reflection/
paint.ts ← Reflections
presets.ts ← Color presets
color.ts ← Color utilities
```
--------------------------------
### Metal-FX Instance Management Layer
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/architecture.md
Details the responsibilities of the instance management layer, including creation, destruction, updates, and observation of DOM elements for prop changes and layout.
```plaintext
┌─────────────────────────────────────────────────────────┐
│ Instance Management Layer │
│ • createInstance() / destroyInstance()
│ • updateInstance() for prop changes
│ • ResizeObserver / IntersectionObserver
│ • Ref forwarding
└──────┬────────────────────────────────────────┬─────────┘
```
--------------------------------
### Metal-FX Instance 2D Compositing
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/architecture.md
Describes the 2D compositing process for instances, including copying shaders to instances, hole-punching with canvas operations, and opacity scaling.
```plaintext
┌────────────────────────────────────┐
│ Instance 2D Compositing │
│ • copyShaderToInstance() │
│ • Hole-punch via canvas op │
│ • Opacity scaling │
└────────────────────────────────────┘
```
--------------------------------
### Preset and Color Utility Functions
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/README.md
Utilities for accessing presets and converting colors.
```APIDOC
## Presets & Colors Utility Functions
### Description
Provides access to predefined presets and utility functions for color manipulation.
### Constants & Functions
#### `PRESETS`
- **Description**: An object containing predefined Metal-FX presets.
- **Values**: `{ chromatic, silver, gold }`
#### `hexToRgb(hex)`
- **Description**: Converts a hexadecimal color string to an RGB array.
- **Parameters**:
- `hex` (string) - The hexadecimal color string (e.g., '#FFFFFF').
- **Returns**: `[r, g, b]` (array) - An array containing the red, green, and blue values.
```
--------------------------------
### Glow System Architecture: Color Tinting Process
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/architecture.md
Explains the color tinting process for the glow system, including sampling shader RGB, adjusting for dark/light modes, and tweening the color for application.
```plaintext
Sample shader RGB at hotspot (halfWin=2 pixel window)
↓
Dark mode: Use RGB as-is
Light mode: Convert to HSV, boost saturation & brightness, convert back
↓
Tween color over TINT_FADE_MS (dark) or per-sample (light)
↓
Apply to haloInner.style.stroke and (light-mode adjusted) extraInner.style.stroke
```
--------------------------------
### Per-Frame Reflection Painting Logic
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/architecture.md
This outlines the process for painting reflections on each frame. It involves calculating target positions, checking visibility and overlap, computing intensity, and compositing fill and stroke passes.
```javascript
paintReflections()
├→ Get DOMRects for all targets + their anchor
│
├→ For each target:
│ ├→ Check proximity (within ATTACH_RANGE_PX)
│ ├→ Check overlap (OVERLAP_MIN_PX)
│ ├→ Detect orientation (horizontal vs vertical)
│ │
│ ├→ Compute intensity:
│ │ proximity = 1 - min(1, dist / RANGE_PX)
│ │ intensity = BASE_ALPHA + (BOOST_ALPHA - BASE_ALPHA) × proximity³
│ │
│ ├→ Size canvases to target rect + 2px overscan
│ │
│ ├→ Composite fill pass:
│ │ - drawImage from anchor canvas (mirrored/rotated)
│ │ - Opacity: intensity × FILL_OPACITY_MUL
│ │
│ ├→ Composite stroke pass:
│ │ - Draw band around perimeter
│ │ - Stroke width: STROKE_CSS_PX × anchor.scale
│ │ - Opacity: intensity × STROKE_EXTRA_ALPHA
│ │
│ └→ Draw border highlight:
│ - Bright edge for 3D depth
│ - Thickness: BORDER_HILITE_PX × anchor.scale
│
└─ [Loop until all targets processed]
```
--------------------------------
### Import Renderer API Functions
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-renderer.md
Import necessary functions from the metal-fx library for interacting with the renderer.
```typescript
import {
createInstance,
destroyInstance,
updateInstance,
setSharedPreset,
pauseShared,
resumeShared,
getSharedFrameCount,
registerGlowInstance,
unregisterGlowInstance,
setGlowCallback,
} from 'metal-fx';
```
--------------------------------
### MetalFx Component Usage
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-metalfx.md
Demonstrates how to import and use the MetalFx component in a React application. It shows basic usage with a child element and highlights the import statement.
```APIDOC
## MetalFx Component
### Description
The main React component that wraps any element with an animated metallic ring effect driven by a shared WebGL renderer.
### Module Export
```typescript
import { MetalFx } from 'metal-fx'
```
### Component Signature
```typescript
const MetalFx = forwardRef(
function MetalFx(props, forwardedRef): ReactElement
)
```
### Props Interface
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| `children` | `ReactNode` | ✓ | — | Single host element to wrap. |
| `variant` | `'button' | 'circle'` | ✗ | `'button'` | Controls shader scale and ring thickness. |
| `preset` | `'chromatic' | 'silver' | 'gold'` | ✗ | `'chromatic'` | Color preset (all have dark/light modes). |
| `theme` | `'dark' | 'light' | 'auto'` | ✗ | `'auto'` | Theme mode; `'auto'` follows system preference. |
| `strength` | `number` | ✗ | `1` | Effect intensity (0..1). Scales opacity only. |
| `paused` | `boolean` | ✗ | `false` | Freeze the shader on current frame. |
| `borderRadius` | `number` | ✗ | — | Explicit CSS px override; reads child's computed value if omitted. |
| `normalizeHostStyles` | `boolean` | ✗ | `true` | Normalize child's border/outline/box-shadow. |
| `reflectionTargets` | `ReadonlyArray>` | ✗ | — | DOM refs to neighbouring elements for proximity reflection. |
| `disableGlow` | `boolean` | ✗ | `false` | Disable the wandering halo overlay. |
| `shaderScale` | `number` | ✗ | — | Override shader sampling scale. |
| `ringCssPx` | `number` | ✗ | — | Override ring thickness in CSS pixels. |
| `scale` | `number` | ✗ | `1` | Master scale multiplier for absolute-pixel internals. |
| `className` | `string` | ✗ | — | Forwarded class name for wrapper. |
| `style` | `CSSProperties` | ✗ | — | Forwarded inline styles for wrapper. |
| `...rest` | `HTMLAttributes` | ✗ | — | All other HTML div attributes. |
```
--------------------------------
### MetalFX with Theme and Preset Configuration
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-metalfx.md
Shows how to apply a specific visual preset and control the theme ('dark' or 'light') for MetalFX. The theme state is managed using React's useState hook.
```typescript
const [theme, setTheme] = useState<'dark' | 'light'>('dark');
return (
);
```
--------------------------------
### Metal-FX Component with Options
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/quick-reference.md
Configure MetalFx with various options like variant, preset, theme, and strength.
```typescript
```
--------------------------------
### registerGlowInstance
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-renderer.md
Adds an instance to the glow sampling queue for processing.
```APIDOC
## registerGlowInstance
### Description
Add an instance to the glow sampling queue.
### Signature
```typescript
function registerGlowInstance(inst: MetalFxInstance): void
```
### Behavior
- Appends instance to `SHARED.glowQueue` if not already present
- Glow callback will receive this instance (round-robin schedule)
```
--------------------------------
### Importing Presets API
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-presets.md
Imports necessary types and constants from the metal-fx presets module.
```typescript
import {
PRESETS,
hexToRgb,
type Preset,
type PresetMode,
type PresetName,
type PresetTheme,
} from 'metal-fx';
```
--------------------------------
### Glow Sampling Configuration
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/configuration.md
Configures parameters for sampling glow luminance and defining segments for the halo effect. It reduces per-frame GPU readback, as intervals of around 5 frames are imperceptible.
```typescript
const GLOW_SKIP_FRAMES = 6;
const HALO_SEGMENTS = 24;
const EXTRA_SEGMENTS = 32;
```
--------------------------------
### Pause/Resume All
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/quick-reference.md
Controls the animation state for all Metal-FX instances globally.
```APIDOC
## pauseShared / resumeShared
### Description
Globally pauses or resumes all Metal-FX animations.
### Methods
`pauseShared()`
`resumeShared()`
### Parameters
None
### Request Example
```typescript
import { pauseShared, resumeShared } from 'metal-fx';
pauseShared(); // Stop all animations
resumeShared(); // Resume
```
### Response
None
```
--------------------------------
### resizeGlow
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-glow.md
Destroys the existing glow overlay and recreates it with new dimensions and shape configuration.
```APIDOC
## resizeGlow
### Description
Destroys and recreates the glow overlay for a resized element.
### Signature
```typescript
function resizeGlow(
handles: GlowHandles,
container: HTMLElement,
opts: GlowOptions
): GlowHandles
```
### Parameters
#### Parameters
- **handles** (`GlowHandles`) - Old handles to destroy.
- **container** (`HTMLElement`) - Container holding the old SVG.
- **opts** (`GlowOptions`) - New size/shape configuration.
### Returns
- `GlowHandles` - New handles for `updateGlow()`.
### Behavior
- Removes old SVG from container
- Calls `injectGlow()` with new options
- Recomputes perimeter sample table
Used internally when `ResizeObserver` detects a dimension change.
```
--------------------------------
### Control Global Preset
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/quick-reference.md
Sets a shared preset for all Metal-FX instances.
```APIDOC
## setSharedPreset
### Description
Sets a shared preset that will be applied to all Metal-FX instances.
### Method
`setSharedPreset(presetName: string, mode: 'dark' | 'light')`
### Parameters
- **presetName** (string) - Required - The name of the preset to set.
- **mode** ('dark' | 'light') - Required - The mode of the preset to apply.
### Request Example
```typescript
import { setSharedPreset } from 'metal-fx';
setSharedPreset('gold', 'dark');
```
### Response
None
```
--------------------------------
### Preset and Color Utility Functions
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/index.md
Exposes preset data and utility functions for color space conversions. `PRESETS` provides access to predefined configurations, while `hexToRgb`, `rgbToHsv`, and `hsvToRgb` facilitate color transformations.
```typescript
const PRESETS: Record
hexToRgb(hex: string): [number, number, number]
rgbToHsv(r: number, g: number, b: number): [number, number, number]
hsvToRgb(h: number, s: number, v: number): [number, number, number]
```
--------------------------------
### Metal-FX Instance and Renderer Interfaces
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/index.md
Defines the structure of a Metal-FX runtime instance, including canvas context, rendering properties, and state. Also defines the structure for preset configurations.
```typescript
interface MetalFxInstance {
canvas: HTMLCanvasElement;
ctx: CanvasRenderingContext2D;
cssWidth: number;
cssHeight: number;
cornerRadius: number;
kind: 'pill' | 'circle';
ringCssPx: number;
shaderScale: number;
opacityMul: number;
visible: boolean;
paused: boolean;
everCopied: boolean;
dpr: number;
scale: number;
onAfterFrame?: () => void;
onFirstCopy?: () => void;
}
interface Preset {
name: PresetName;
modes: Record;
}
interface PresetMode {
colors: [string, string, string, string, string, string, string];
alphas: [number, number, number, number, number, number, number];
direction: number;
speed: number;
intensity: number;
scale: number;
softness: number;
distortion: number;
complexity: number;
shape: number;
blur: number;
vignette: number;
vigOpacity: number;
shaderOpacity: number;
}
```
--------------------------------
### Register Glow Instance
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-renderer.md
Adds an instance to the glow sampling queue. This instance will be included in the glow callback's round-robin schedule.
```typescript
function registerGlowInstance(inst: MetalFxInstance): void
```
--------------------------------
### Metal-FX Reflection Layer
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/architecture.md
Outlines the reflection layer's capabilities, such as adding reflection targets, painting reflections, calculating proximity, and compositing with canvas.
```plaintext
┌──────────────────────────────┐
│ Reflection Layer │
│ • addReflectionTarget() │
│ • paintReflections() 1/f │
│ • Proximity calculation │
│ • Canvas compositing │
└──────────────┬────────────────┘
```
--------------------------------
### Dynamic Inline Styles for Metal-FX Instances
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/architecture.md
Per-instance styles applied dynamically using the `.style` property in TypeScript. This includes setting CSS variables for radius and strength, and controlling opacity.
```typescript
root.style.borderRadius = `${cornerRadius}px`;
root.style.setProperty('--mfx-radius', `${cornerRadius}px`);
root.style.setProperty('--mfx-strength', String(strength));
root.style.opacity = ready ? '1' : '0';
```
--------------------------------
### Inject Glow Overlay
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-glow.md
Creates and injects the glow SVG overlay into a specified container. Requires configuration options for size, shape, and scale.
```typescript
function injectGlow(container: HTMLElement, opts: GlowOptions): GlowHandles
```
```typescript
const container = document.getElementById('glow-host');
const handles = injectGlow(container, {
width: 140,
height: 40,
cornerRadius: 20,
kind: 'pill',
scale: 1,
});
```
--------------------------------
### Metal-FX React Component Structure
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/architecture.md
Illustrates the basic structure of a Metal-FX component within a React application, showing how props are passed down to control its appearance and behavior.
```jsx
┌─────────────────────────────────────────────────────────┐
│ React Component Layer │
│
│
│
└──────┬──────────────────────────────────────────────────┘
```
--------------------------------
### Forwarding Ref to Root Wrapper
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-metalfx.md
Demonstrates how to forward a ref to the root div element of the MetalFX component. This allows direct DOM manipulation or measurement.
```typescript
const rootRef = useRef(null);
return ...;
```
--------------------------------
### Using MetalFxComponent with TypeScript
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/types.md
Demonstrates how to use the MetalFx component with typed props in a React application. Ensure 'MetalFxProps' and 'MetalFxVariant' types are imported.
```typescript
import type { MetalFxProps, MetalFxVariant } from 'metal-fx';
const MyComponent: React.FC<{ variant?: MetalFxVariant }> = ({ variant = 'button' }) => {
const props: MetalFxProps = {
children: ,
variant,
preset: 'gold',
theme: 'dark',
strength: 0.9,
};
return ;
};
```
--------------------------------
### Use Preset Values for Custom Shader Sampling
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-presets.md
Integrate preset configurations, such as scale and blur, into custom WebGL shader uniforms. This allows for consistent styling across custom and default shaders.
```typescript
const preset = PRESETS.silver.modes.light;
// Use preset configuration for custom renderer
const gl = createGLContext();
gl.uniform1f(uniformLocation('u_scale'), preset.scale);
gl.uniform1f(uniformLocation('u_blur'), preset.blur);
```
--------------------------------
### React Component with Metal-FX
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/index.md
Demonstrates how to integrate Metal-FX into a React component using the `useState` and `useRef` hooks. This snippet shows basic theme and strength configuration.
```typescript
const [theme, setTheme] = useState('auto');
const [strength, setStrength] = useState(1);
const ref = useRef(null);
return (
);
```
--------------------------------
### Preset and Color Utility Functions
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/README.md
Access to predefined presets and a utility function for converting hex color codes to RGB.
```typescript
const PRESETS: { chromatic, silver, gold }
hexToRgb(hex): [r, g, b]
```
--------------------------------
### Destroy Instance
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/quick-reference.md
Cleans up and destroys a Metal-FX renderer instance.
```APIDOC
## destroyInstance
### Description
Cleans up and destroys a Metal-FX renderer instance, releasing resources.
### Method
`destroyInstance(instance: MetalFxInstance)`
### Parameters
- **instance** (MetalFxInstance) - Required - The instance to destroy.
### Request Example
```typescript
import { destroyInstance } from 'metal-fx';
destroyInstance(inst);
```
### Response
None
```
--------------------------------
### Access Preset Colors and Properties
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-presets.md
Import and access predefined color palettes and shader properties from the PRESETS object. Useful for inspecting or using default values.
```typescript
import { PRESETS } from 'metal-fx';
const darkChromatic = PRESETS.chromatic.modes.dark;
console.log(darkChromatic.colors[0]); // '#000000'
console.log(darkChromatic.speed); // 1.2
```
--------------------------------
### injectGlow
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-glow.md
Creates and injects the glow SVG overlay into a specified container element with given configuration options.
```APIDOC
## injectGlow
### Description
Creates and injects the glow SVG overlay into a container.
### Signature
```typescript
function injectGlow(container: HTMLElement, opts: GlowOptions): GlowHandles
```
### Parameters
#### Parameters
- **container** (`HTMLElement`) - DOM element to append the SVG into.
- **opts** (`GlowOptions`) - Configuration object.
#### Options (GlowOptions)
- **width** (`number`) - Required - CSS width of the wrapped element.
- **height** (`number`) - Required - CSS height of the wrapped element.
- **cornerRadius** (`number`) - Required - Corner radius in pixels.
- **kind** (`'pill' | 'circle'`) - Required - Shape hint.
- **scale** (`number`) - Optional - Default: `1` - Master scale multiplier for stroke widths/blur.
### Returns
- `GlowHandles` - Opaque state object for `updateGlow()`.
### Behavior
- Generates a unique ID prefix for this glow instance
- Creates SVG with multiple blurred path elements (halo + extra highlights)
- Calculates perimeter sample points based on shape and dimensions
- Sets up transform origins and CSS transitions
- Initializes internal state (tween, wander, tint)
### Example
```typescript
const container = document.getElementById('glow-host');
const handles = injectGlow(container, {
width: 140,
height: 40,
cornerRadius: 20,
kind: 'pill',
scale: 1,
});
```
```
--------------------------------
### MetalFX Component Usage
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/README.md
Illustrates how to use the main MetalFX React component with its props and children.
```typescript
{children}
```
--------------------------------
### Update Instance
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/quick-reference.md
Updates an existing Metal-FX instance with new properties.
```APIDOC
## updateInstance
### Description
Updates an existing Metal-FX renderer instance with new properties.
### Method
`updateInstance(instance: MetalFxInstance, props: Partial)`
### Parameters
- **instance** (MetalFxInstance) - Required - The instance to update.
- **props** (Partial) - Required - An object containing the properties to update.
- **cssWidth** (number) - Optional - New CSS width.
- **opacityMul** (number) - Optional - New opacity multiplier.
- **paused** (boolean) - Optional - Whether to pause or resume animations.
### Request Example
```typescript
import { updateInstance } from 'metal-fx';
updateInstance(inst, {
cssWidth: 200,
opacityMul: 0.8,
paused: true,
});
```
### Response
None
```
--------------------------------
### Glow System Architecture: Perimeter Sampling
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/architecture.md
Details the steps involved in parameterizing a shape's perimeter and sampling points for luminance checks. These sample points are reused each frame.
```plaintext
Rounded rectangle or circle → perimeter parameterization
↓
Divide [0, 2π) into N evenly-spaced arcs
↓
For each arc, compute (x, y) point on perimeter
↓
Store as PerimSample { x, y, arc, ... }
↓
Sample points reused every frame for luminance checks
```
--------------------------------
### Define Preset Interface
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/types.md
Represents a complete preset, including configurations for both dark and light modes.
```typescript
interface Preset {
name: PresetName;
modes: Record;
}
```
--------------------------------
### Customizing MetalFX Border Radius and Scale
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-metalfx.md
Shows how to apply custom border radius and scaling factors to the MetalFX effect for fine-grained visual control. Includes `borderRadius`, `scale`, `shaderScale`, and `ringCssPx` props.
```typescript
return (
);
```
--------------------------------
### Renderer Lifecycle Functions
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/README.md
Functions to manage the lifecycle of Metal-FX instances.
```APIDOC
## Renderer Lifecycle Functions
### Description
These functions control the creation, destruction, and updating of Metal-FX instances, managing the underlying rendering resources.
### Functions
#### `createInstance(opts)`
- **Description**: Creates a new Metal-FX instance with the provided options.
- **Parameters**:
- `opts` (object) - Options for creating the instance.
- **Returns**: `MetalFxInstance` - The newly created instance.
#### `destroyInstance(inst)`
- **Description**: Destroys a Metal-FX instance, releasing its resources.
- **Parameters**:
- `inst` (`MetalFxInstance`) - The instance to destroy.
- **Returns**: `void`
#### `updateInstance(inst, patch)`
- **Description**: Updates an existing Metal-FX instance with a patch of new properties.
- **Parameters**:
- `inst` (`MetalFxInstance`) - The instance to update.
- `patch` (object) - An object containing the properties to update.
- **Returns**: `void`
```
--------------------------------
### Glow System Architecture: Hotspot Tracking State Machine
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/architecture.md
Outlines the state machine and per-frame logic for tracking the brightest point (hotspot) in the glow system. It includes logic for detecting rival hotspots and managing transitions.
```plaintext
State machine:
- currentIdx: current brightest point
- appearedAt: timestamp when current point became active
- relocTween: fade transition object
- dwellActive: within MIN_DWELL_MS?
Per frame:
1. Sample luminance at all perimeter points
2. Find maxIdx (brightest)
3. Check dwell timer
4. If rival dominates (maxLum - curLum > RELOCATE_DELTA):
- Trigger relocTween (fade out over RELOC_FADE_MS)
- On completion, jump to maxIdx
- Fade back in over RELOC_FADE_MS
5. Else:
- Lerp opacity toward targetOp via FADE_RATE
```
--------------------------------
### Document Visibility Handling
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/architecture.md
Details how the shared rendering loop is stopped when the page is hidden to conserve resources and restarted when the page returns to the foreground, provided instances are visible and unpaused.
```javascript
Page goes to background (document.hidden):
└→ stopSharedLoop() [saves CPU/GPU]
Page returns to foreground:
└→ startSharedLoop() [if instances visible & unpaused]
```
--------------------------------
### Glow Functions
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/index.md
Functions for managing glow effects associated with MetalFX instances.
```APIDOC
## Glow Functions
### Description
API for registering and unregistering glow instances and setting glow callbacks.
### `registerGlowInstance(inst: MetalFxInstance): void`
Registers a MetalFX instance to participate in glow effects.
### `unregisterGlowInstance(inst: MetalFxInstance): void`
Unregisters a MetalFX instance from glow effects.
### `setGlowCallback(cb: GlowCallback | null): void`
Sets or clears a callback function to be invoked for glow events.
```
--------------------------------
### Registering a Reflection Target
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/architecture.md
This function registers an element as a target for reflection rendering. It sets up necessary DOM elements and observers, and adds the target to a global collection.
```javascript
addReflectionTarget(el, anchor, anchorEl)
├→ Check if blocked tag → return null
├→ Create wrapper div + two canvases (fill, stroke)
├→ Insert as first child of el
├→ Apply position: relative, isolation: isolate
├→ Read hairline spec (border-radius, border-width)
├→ Attach ResizeObserver & MutationObserver
└→ Add to global targets Set
```
--------------------------------
### Metal-FX Per-Frame Animation Flow
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/architecture.md
Details the process for rendering each frame of the Metal-FX animation, including visibility checks, GL rendering, instance copying, and glow/reflection updates.
```markdown
requestAnimationFrame(tick)
↓
Check visibility / pause state
↓
renderSharedFrame(now)
├→ gl.clearColor / gl.clear
├→ uploadPresetUniforms() [if preset dirty]
├→ gl.uniform1f(u_time, elapsed)
└→ gl.drawArrays(TRIANGLES, 0, 6)
↓
[If OffscreenCanvas] transferToImageBitmap() → frameBitmap
↓
For each visible unpaused instance:
├→ copyShaderToInstance()
│ ├→ ctx.drawImage() [composite from GL]
│ ├→ punchInnerHole() [destination-out]
│ └→ Call onAfterFrame callback
└→ everCopied = true
↓
Glow callback [round-robin, one instance]
└→ updateGlow()
├→ Sample luminance at perimeter
├→ Track hotspot & transitions
├→ Update SVG transforms
└→ Tint stroke colors
↓
[Scheduled] Reflection paint [if targets registered]
└→ paintReflections()
├→ Check proximity
├→ Composite onto target canvases
└→ Apply strokes/highlights
↓
Loop continues if any visible unpaused instance
```
--------------------------------
### Access Presets
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/quick-reference.md
Access predefined color presets for dark and light modes. These presets are available under the `PRESETS` object.
```typescript
import { PRESETS } from 'metal-fx';
PRESETS.chromatic.modes.dark;
PRESETS.silver.modes.light;
PRESETS.gold.modes.dark;
```
--------------------------------
### Convert RGB to HSV and Adjust
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-color.md
Converts RGB color values to HSV for perceptual adjustments like saturation and brightness. The resulting HSV values can then be converted back to RGB.
```typescript
const rgbColor = [200, 100, 50];
const [h, s, v] = rgbToHsv(...rgbColor);
// Adjust
const newS = Math.min(1, s * 1.5); // Boost saturation
const newV = v * 0.9; // Darken slightly
const adjusted = hsvToRgb(h, newS, newV);
```
--------------------------------
### Perimeter Sampling Configuration
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/configuration.md
Sets the maximum number of sample points to pre-compute for the perimeter. Larger elements will utilize more points, while smaller elements will use fewer.
```typescript
const PERIM_SAMPLES = 1024;
```
--------------------------------
### Apply a Preset at Runtime
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-presets.md
Dynamically change the active preset for all instances using the setSharedPreset function. This affects the appearance of all active Metal-FX elements.
```typescript
import { setSharedPreset } from 'metal-fx';
// Change all active instances to gold dark mode
setSharedPreset('gold', 'dark');
```
--------------------------------
### Define PresetMode Interface
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/types.md
Configuration for a specific preset and theme combination. This interface details color, alpha, direction, speed, intensity, scale, and distortion parameters.
```typescript
interface PresetMode {
colors: [string, string, string, string, string, string, string];
alphas: [number, number, number, number, number, number, number];
direction: number;
speed: number;
intensity: number;
scale: number;
softness: number;
distortion: number;
complexity: number;
shape: number;
blur: number;
vignette: number;
vigOpacity: number;
shaderOpacity: number;
}
```
--------------------------------
### Control Global Preset
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/quick-reference.md
Use `setSharedPreset` to apply a global preset to all Metal-FX instances. This allows for consistent styling across the application.
```typescript
import { setSharedPreset } from 'metal-fx';
setSharedPreset('gold', 'dark');
```
--------------------------------
### Circle Variant MetalFX with Reflection Targets
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/api-reference-metalfx.md
Illustrates using the 'circle' variant of MetalFX and configuring reflection targets using React refs. This allows the effect to react to the position of other elements.
```typescript
const sendRef = useRef(null);
const chipRef = useRef(null);
return (
<>
>
);
```
--------------------------------
### Preset Interface
Source: https://github.com/jakubantalik/metal-fx/blob/main/_autodocs/quick-reference.md
Defines the structure for a Metal-FX preset, including its name and color modes (dark/light). Each mode contains detailed color, alpha, and animation parameters.
```typescript
interface Preset {
name: PresetName;
modes: { dark: PresetMode, light: PresetMode };
}
interface PresetMode {
colors: [string, string, string, string, string, string, string];
alphas: [number, number, number, number, number, number, number];
direction: number;
speed: number;
intensity: number;
scale: number;
softness: number;
distortion: number;
complexity: number;
shape: number;
blur: number;
vignette: number;
vigOpacity: number;
shaderOpacity: number;
}
```
--------------------------------
### Sizing Wrapper and Filling Child with MetalFx
Source: https://github.com/jakubantalik/metal-fx/blob/main/README.md
Pattern 2: Size the MetalFx wrapper element and explicitly stretch the child element to fill it. Use when the metal frame needs to be larger than the child.
```tsx
// Pattern 2: size the wrapper, child fills.
```