组件/MetalFx

MetalFx

按钮、文字与徽标的 WebGL2 液态金属材质

已验证自 0.6.2

用法

基础

TxMetalFx 包裹恰好一个宿主元素,在 WebGL2 画布上为它绘制金属环。

示例加载中...

变体

button 是 1 px 环的胶囊,circle 是 2 px 环的正圆;环半径取自子元素的 border-radius。

<template>
  <TxMetalFx variant="button" preset="silver" :strength="0.7">
    <a href="/pricing">升级到 Pro</a>
  </TxMetalFx>

  <TxMetalFx variant="circle" preset="gold" inner-shadow :scale="1.5">
    <button type="button" aria-label="发送">↑</button>
  </TxMetalFx>
</template>

文字与徽标

TxMetalText 与 TxMetalBadge 固定使用 chromatic 材质,并以自身文本作为 aria-label。

<template>
  <TxMetalText font="600 32px/1.1 Inter, sans-serif" color="#e8e8e8">Pro</TxMetalText>
  <TxMetalBadge>Beta</TxMetalBadge>
</template>

最佳实践

  • 图标类子元素显式给出宽高;包裹层是 inline-flex,尺寸跟随子元素。
  • 子元素背景保持透明,自定义填充写在 TxMetalFx 上。
  • 每页只用一个预设与主题:所有实例共用一份材质,最后应用的生效。
  • 金属元素彼此拉开,并排的两个金属按钮会争夺视觉焦点。
  • reflectionTargets 只传能持有引用的稳定邻元素。

API 参考

TxMetalFx

属性

属性类型默认值说明
variant'button' | 'circle''button'环基线:胶囊 1 px,圆形 2 px。
preset'chromatic' | 'silver' | 'gold''chromatic'金属颜色,每个预设都有明暗两套调校。
theme'auto' | 'dark' | 'light''auto'预设的明暗侧;auto 实时跟随系统。
strengthnumber1同时缩放着色器不透明度与辉光 alpha(0-1)。
glowGainnumber1仅作用于辉光的倍数,相乘后钳制到 0-1。
pausedbooleanfalse冻结在当前帧。
borderRadiusnumber自动探测环半径(CSS px)。
normalizeHostStylesbooleantrue剥离子元素的边框、outline 与 box-shadow。
reflectionTargetsArray<Element | { ref, strength }>无接收镜像反射的邻元素。
disableGlowbooleanfalse移除游走辉光,保留金属环。
innerShadowboolean | { offsetY, blur, alpha, color }关环顶部内侧的高光边。
shaderScalenumber变体基线 × scale覆盖着色器采样尺度。
ringCssPxnumber变体基线 × scale覆盖环厚度(CSS px)。
scalenumber1引擎内所有绝对像素常量的总倍数。
mask(ctx, size) => void无自定义 alpha 遮罩,着色器只保留遮罩覆盖处。
glowMode'mask' | 'ring''mask'设置 mask 后辉光的落位方式。

插槽

插槽参数说明
default-恰好一个宿主元素,保留其自身事件处理。

CSS 变量

变量来源说明
--mfx-strengthstrength钳制到 0-1 的强度,供下游 CSS 读取。
--mfx-radiusborderRadius 或自动探测环半径(px)。

TxMetalText

属性

属性类型默认值说明
fontstring必填CSS font 简写。
colorstring必填金属下方的底色。
strengthnumber1金属不透明度。
reflectionTargetsArray<Element | { ref, strength }>无接收金属反射的邻元素。
childrenstring无默认插槽为空时的文本。
theme'auto' | 'dark' | 'light'无预设的明暗侧;未传时跟随系统。
innerShadowTextInnerShadow | nullFIGMA_INNER_SHADOW字形内侧顶部的高光边;null 关闭。
glowbooleanfalse在字形上显示辉光。
glowGainnumber2.5glow 开启时的辉光倍数。
metalOpacitynumber0.62金属盖过底色的程度(0-1),与 strength 相乘。
shaderScalenumber2.8字形内金属纹理的缩放。

插槽

插槽参数说明
default-标签文本。

TxMetalBadge

属性

属性类型默认值说明
childrenstring'New'默认插槽为空时的文本。
strengthnumber1金属不透明度。
theme'auto' | 'dark' | 'light'无预设的明暗侧;未传时跟随系统。
scalenumber1整体尺寸倍数(基准 45×25)。
reflectionTargetsArray<Element | { ref, strength }>无接收金属反射的邻元素。
metalOpacitynumber0.8金属盖过白底的程度(0-1),与 strength 相乘。
shaderScalenumber1.6金属纹理的缩放。
coreMetalBadgeCore{ r: 46, blur: 100, a: 0.94, size: 49 }文字下白色核心的半径、过渡、不透明度与尺寸。
gradientnumber0自上而下的白色渐变强度(0-1)。
glownumber0.41内侧白色辉光强度(0-1)。
textColorstring'#323232'文字颜色。

插槽

插槽参数说明
default-标签文本,为空时用 children。

概述

  • 全页实例共用一个 WebGL2 上下文、一份材质和一个约 15 fps 的循环;离屏实例(IntersectionObserver,64 px 边距)不渲染,标签页隐藏时循环停止。
  • 首帧金属绘制完成前,包裹层连同子元素不可见;在那之前不要测量或动画化子元素。
  • 反射只在暗色主题渲染;亮色主题下不扫描 DOM,也没有逐帧开销。
  • 着色器不响应减少动态效果,需要时自行传 paused(可选 disableGlow)。
  • 光标反射需经 setCursorSprite 注册精灵图,否则保持关闭;减少动态效果、forced-colors 与粗指针下自动关闭。
  • 不支持 WebGL2 时,子元素保留自身样式,渲染在 div.metal-fx-fallback[data-metal-fx-unsupported] 中,不画环。

技术实现

  • engine/** 逐字移植自 Jakubantalik/Libraries · metal-fx v2(MIT © Jakub Antalik),Vue 壳沿用 React 包裹层的生命周期、测量与清理。
  • 页面级调校使用模块导出的引擎原语:setGlowConfig、setCursorLightConfig、setBendConfig、isMetalFxSupported 等。
  • 源码:packages/tuffex/packages/components/src/metal-fx/。
查看源码
packages/tuffex/packages/components/src/metal-fx/index.ts