### 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. ```