SuperAPI AI 工具集

tonejs

设计与创作

查看项目

更新于 10-24 17:22

技能介绍

Tone.js 是一个用于在浏览器中创建、播放和处理音频的 JavaScript 框架。本技能面向在项目中添加音频、声音设计、音乐编排或音频响应式动画的场景,并重点说明如何将 Tone.js 与 GSAP 动画时间线同步。

主要用途与适用场景

  • 在 GSAP 动画中同时播放音频文件(音效、旁白、音乐)。
  • 实现节拍同步或 BPM 锁定的动画,例如按节拍切换场景。
  • 制作音频响应式视觉:由波形或频率数据驱动 DOM/SVG 元素动画。
  • 以编程方式生成声音,例如合成器、振荡器、界面音效。
  • 为任意声源添加混响、延迟、失真等音频效果。

安装与初始化

  • 通过 CDN 引入:<script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.49/Tone.js"></script>
  • 通过 npm / bun 安装:bun add tone,然后 import * as Tone from 'tone';
  • 受浏览器自动播放策略限制,必须在用户手势处理器(如 click、keydown)内调用 await Tone.start(),否则音频上下文不会恢复。示例中在按钮点击事件中调用 Tone.start() 并启动 Tone.getTransport().start(),且使用 { once: true } 仅触发一次。

核心架构

  • 信号图结构为:声源(Synth、Player、Analyser)→ 效果器(Reverb、Delay、Distortion)→ 目标(toDestination())。
  • 所有节点通过 .connect() 或 .toDestination() 连接。

常用能力

  • 播放音调:new Tone.Synth().toDestination().triggerAttackRelease("C4", "8n")
  • 加载并播放文件:new Tone.Player(url).toDestination(),再调用 player.start()
  • 添加混响:const rev = new Tone.Reverb(2).toDestination(); synth.connect(rev)
  • 按节拍调度:Tone.getTransport().scheduleRepeat(cb, "4n")
  • 读取波形:new Tone.Analyser("waveform", 64).getValue()
  • 读取频率:new Tone.Analyser("fft", 32).getValue()
  • 设置 BPM:Tone.getTransport().bpm.value = 120
  • 将视觉同步到音频:Tone.getDraw().schedule(() => { /* gsap here */ }, time)
  • 停止并清空调度:Tone.getTransport().stop(); Tone.getTransport().cancel()

与 GSAP 同步的正确方式

  • Tone 回调运行在音频线程,直接在回调中调用 gsap.to() 会造成抖动。应使用 Tone.getDraw().schedule() 将音频事件桥接到视觉帧。
  • 示例:在 Tone.getTransport().scheduleRepeat 回调中通过 Tone.getDraw().schedule 调用 gsap.fromTo,而不是直接调用 gsap.to。

音频响应式动画

  • 将 Tone.Analyser 接入 GSAP ticker,每帧读取波形数据并驱动 DOM 元素。示例使用 gsap.ticker.add 读取 analyser.getValue()(Float32Array,值域 [-1, 1]),再用 gsap.set 设置元素 scaleY。
  • 在 ticker.add 内应使用 gsap.set() 而非 gsap.to(),避免每帧创建新补间带来开销。

BPM 锁定场景切换

  • 设置 bpm 后,使用 Tone.getTransport().scheduleRepeat 按小节("1m")触发,并通过 Tone.getDraw().schedule 执行 gsap.fromTo 切换场景透明度。

播放音频文件与效果器链

  • 使用 Tone.Player 加载音效或旁白,设置 autostart: false,在 GSAP 事件(如 onStart)中调用 player.start()。
  • 效果器链示例:Reverb 接 toDestination(),FeedbackDelay 连接 Reverb,Synth 连接 FeedbackDelay,再触发音符。

常见错误与修复

  • 音频不启动:先在 click 或 keydown 处理器中调用 await Tone.start()。
  • 视觉抖动:不要在 Tone 回调中直接调用 gsap.to(),改用 Tone.getDraw().schedule()。
  • ticker 中使用 gsap.to():改用 gsap.set()。
  • Transport 事件触发两次:重新调度前先调用 Tone.getTransport().cancel()。
  • Player 未就绪:在 player.load() 的 Promise 中或 onsuccess 内调用 player.start()。
  • Analyser 占用 CPU 高:使用较小缓冲区(32 至 64),波形足够时避免使用 FFT。

最小可运行示例(原生 HTML)

  • 页面引入 Tone.js 与 gsap.min.js,在 body 点击事件中 await Tone.start(),创建 Analyser 与 Synth,通过 gsap.ticker.add 读取波形并设置 .bar 元素 scaleY,最后触发音符。该示例同样使用 { once: true }。

限制与注意事项

  • 必须依赖用户手势触发音频初始化,否则无法播放。
  • 资料未提供关于收费、价格、平台兼容范围或性能指标的更多信息,暂未提供。