VoiceBeam
沿元素底边律动的音频响应辉光
用法
基础
包裹恰好一个自带圆角的元素;传麦克风的 stream,或用 level 手动驱动。
示例加载中...
麦克风输入
useMicrophone() 关闭回声消除、降噪与自动增益后请求 getUserMedia;start() 必须在点击事件里调用。
<script setup lang="ts">
import { useMicrophone } from '@talex-touch/tuffex/pro'
const mic = useMicrophone()
const live = computed(() => mic.state.value === 'live')
</script>
<template>
<TxVoiceBeam :stream="mic.stream.value" :processing="transcribing">
<TxCard :radius="16" :padding="24" shadow="none">想问点什么…</TxCard>
</TxVoiceBeam>
<TxButton :aria-pressed="live" @click="live ? mic.stop() : mic.start()">
{{ live ? '停止' : '说话' }}
</TxButton>
</template>
宿主预设与配色
type 选择宿主预设,显式传入的几何属性覆盖预设值;colorVariant 选择调色板。
<template>
<TxVoiceBeam type="pill" color-variant="ocean" :scale="0.9">
<div class="pill">录音中…</div>
</TxVoiceBeam>
<TxVoiceBeam type="mobile" color-variant="candy" :level="() => 0.8">
<div class="screen">正在聆听</div>
</TxVoiceBeam>
</template>
最佳实践
- 不要把辉光当作麦克风开着的唯一指示:保留文字状态与按钮的
aria-pressed,并用role="status"播报变化。 level传 getter(:level="() => meter.value")而不是响应式数字:getter 每帧采样一次,不触发重渲染。- 需保持清晰的文字与控件放到
position: relative; z-index: 5;被包裹元素内的浮层会被裁掉,用 portal 移出。 - 关闭语音界面时调用
mic.stop(),组合式函数只在卸载时停止音轨。 - 实例要少:每个实例都有模糊图层与画布,不适合密集列表。
API 参考
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
type | 'default' | 'pill' | 'mobile' | 'default' | 宿主预设(聊天输入框 / 录音胶囊 / 手机底部),提供几何默认值。 |
stream | MediaStream | null | null | 要响应的实时音频;优先于 level。 |
level | number | () => number | 0 | 无 stream 时的手动电平(0-1)。 |
sensitivity | number | 3.1 | 分析音频的输入增益。 |
threshold | number | 0.015 | 噪声门(0-1),低于它的电平视为静音。 |
attack / release | number | 0.325 / 0.86 | 辉光上升与回落的秒数。 |
idle / breatheDuration | number | 0.23 / 5.2 | 静音时的存在感与呼吸周期(秒)。 |
reach / spread | number | 1.2 / 1.05 | 满电平时的升高与横向扩张倍数。 |
bands | boolean | true | 低 / 中 / 高频段独立驱动各色瓣。 |
flow | number | 48 | 满电平下频谱的横向流速(px/s)。 |
processing | boolean | false | 收拢为一束往返行进的光束并保持点亮。 |
processingDuration / processingLevel / processingEase / processingTravel / processingCurve | number | 1.1 / 0.55 / 0.6 / 1.55 / 2.1 | 处理阶段的往返周期、保持亮度、形变时长、行程与缓动。 |
cornerFollow | number | 0.45 | 处理阶段辉光沿圆角抬起的程度。 |
colorVariant | 'colorful' | 'mono' | 'ocean' | 'sunset' | … | 'colorful' | 色瓣调色板。 |
colors | string[] | 无 | 最多七个色瓣颜色,中心优先。 |
bandColors | { core?, above?, mid?, below? } | 主题默认 | 光带脊线与色边的颜色。 |
theme | 'dark' | 'light' | 'auto' | 'dark' | 背景适配;auto 跟随系统偏好。 |
staticColors | boolean | false | 关闭缓慢的色相漂移。 |
hueRange / hueDuration | number | 24 / 40、12 / 8.5 | 色相漂移范围(度)与周期(秒);默认值分暗色 / 亮色。 |
active | boolean | true | 关闭时辉光淡出并停止音频分析。 |
paused | boolean | false | 把辉光、光带与分析冻结在最后一帧。 |
borderRadius | number | 自动探测 | 圆角半径(px)。 |
brightness / saturation | number | 主题默认 | 辉光亮度与饱和度倍数。 |
glowSize | number | 1 | 辉光模糊半径倍数。 |
strokeOpacity / innerOpacity / bloomOpacity | number | 1 | 描边、内光与光晕层的不透明度倍数。 |
scale | number | 1 | 一次缩放全部像素尺寸。 |
bend、bandStrength、bandWidth、bandPosition、bandCurve、bandSpread、bandSkew、bandOffset、bandTail、bandTailPosition、bandTailCurve、bandTailOverflow、bandAberration | number | 已调校 | 辉光轮廓与光带的形状。 |
distortion / distortionDetail | number | 0.62 / 2.3 | 光带下方光的横向扭曲强度与噪声粒度。 |
glowWidth、glowHeight、lobeSpacing、rangeWidth、rangeHeight、softness、coreSize、coreLight、coreLightWidth、coreLightHeight、strokeScale、innerScale、innerHeight、bloomScale、bloomHeight | number | 已调校 | 色瓣、可见范围、核心与光晕的几何。 |
strength | number | 1 | 整体效果不透明度(0-1),不影响子元素。 |
css | string | 无 | 追加在生成样式表之后的 CSS;{id} 按实例替换。 |
插槽
| 插槽 | 参数 | 说明 |
|---|---|---|
default | - | 被包裹的元素;光束图层渲染在它背后与上方。 |
事件
| 事件 | 载荷 | 说明 |
|---|---|---|
level | (level: number) | 每帧触发,携带当前展示的平滑电平。 |
activate | - | 淡入完成时触发。 |
deactivate | - | 淡出完成时触发。 |
CSS 变量
| 变量 | 来源 | 说明 |
|---|---|---|
--voice-strength | strength | 光束图层不透明度(0-1)。 |
--voice-stroke-opacity / --voice-inner-opacity / --voice-bloom-opacity | 宿主样式 | 各层不透明度倍数,与 strokeOpacity / innerOpacity / bloomOpacity 相乘;组件不写入。 |
概述
- 按子元素的
border-top-left-radius(取不到时为 16 px)裁剪,光束贴合元素边缘。 - 全页共用一个约 60 fps 封顶的
requestAnimationFrame循环;实例滚出视口(256 px 边距)后注销并释放分析器。 - 每页共用一个
AudioContext,每个 stream 一个 source 节点(引用计数),每个实例一个分析器;音频只分析,不播放。 - 使用
stream时读取 RMS 电平与三个频段(80-300、300-2000、2000-6000 Hz)。 - 减少动态效果时停止待机呼吸、色彩流动、色相漂移、扭曲与处理扫描;对声音的反应保留,因为它本质是电平表。
技术实现
styles.ts、presets.ts、voice-driver.ts、audio.ts、color.ts逐字移植自 Jakubantalik/Libraries · voice-glow(MIT © Jakub Antalik);useMicrophone是上游 React hook 的 Vue 移植。- 源码:
packages/tuffex/packages/components/src/voice-beam/。
查看源码
packages/tuffex/packages/components/src/voice-beam/index.ts