Sound 交互音效
默认关闭的合成 UI 反馈音
API 参考
| 名称 | 说明 |
|---|---|
configureSound({ enabled, volume }) | 开关与主音量(0–1,越界夹取),返回生效后的配置 |
getSoundConfig() | 当前配置的副本 |
playSound(type | preset) | 播放,返回是否真的播了 |
sound.click() / .key() / .toggle() / .success() / .error() / .open() / .close() | 快捷方法 |
isSoundSupported() | 浏览器是否支持 Web Audio |
disposeSound() | 关闭音频图,下次播放时重建 |
SOUND_PRESETS | 预设表,可读取参数或作为自定义起点 |
默认关闭
import { configureSound, sound } from '@talex-touch/tuffex/utils'
configureSound({ enabled: true, volume: 0.6 })
sound.click()
- 未开启时不发声,也不创建
AudioContext。 - 音频图懒建:浏览器会挂起非用户手势中创建的
AudioContext,从不播放的页面不应持有一个。
为什么用合成
几个振荡器加一条包络:零打包体积,任意采样率下不糊,也不会 404;代价是音色不如采样丰富。
预设
七个,刻意不多。峰值与时长经 OfflineAudioContext 逐样本实测。
| 预设 | 用途 | 峰值 | 时长 |
|---|---|---|---|
click | 按钮按下 | 0.103 | 40ms |
key | 文本框逐字符 | 0.056 | 27ms |
toggle | 开关 / 复选框打开 | 0.089 | 65ms |
success | 动作完成(上行两音) | 0.090 | 188ms |
error | 动作被拒(下行两音) | 0.100 | 216ms |
open | 面板 / 对话框打开 | 0.078 | 91ms |
close | 面板 / 对话框关闭 | 0.077 | 91ms |
key峰值最低:它按字符触发,用click的音量会变成打字机。open/close的峰值与时长镜像,只有滑音方向相反:方向承载语义,音量不承载。- 全部不削波,峰值都在 0.06–0.11。
- 时长预算由测试守住:即时反馈(
click/key/toggle)≤ 80ms,状态提示(其余)≤ 250ms。
自定义
playSound 也接受现场构造的音型:
import { playSound } from '@talex-touch/tuffex/utils'
playSound({
layers: [
{ wave: 'sine', freq: [400, 700], gain: 0.09, decay: 0.12 },
{ wave: 'sine', freq: 900, gain: 0.06, decay: 0.1, delay: 0.08 },
],
})
freq 给两个值即为滑音;delay 让第二个音错开,构成两音音型而非和弦。
契约
- 永不抛错:关闭、不支持或浏览器尚未见到用户手势时,
playSound静默返回false。 - 被自动播放策略挂起的 context 在下次播放时
resume(),失败也不抛。 - 每个声音结束后断开自己的包络节点,连打不会在主增益上堆积死节点。
- 噪声缓冲复用,不按次生成。
- 主音量改动立即作用于现有音频图,无需重建。
和震动的关系
useVibrate 是同层的另一条反馈通道,形态一致(预设表 + 主函数 + 快捷对象)。同一动作不要同时触发音效和震动:双重反馈读起来像触发了两次。
查看源码
packages/tuffex/packages/components/src/sound/index.ts