• Babel 插件通关秘籍
  • Git 原理详解及实用指南
  • Nest 通关秘籍
  • React 通关秘籍
  • TypeScript 全面进阶指南
  • TypeScript 类型体操通关秘籍
  • 现代CSS
  • Babel 插件通关秘籍
  • Git 原理详解及实用指南
  • Nest 通关秘籍
  • React 通关秘籍
  • TypeScript 全面进阶指南
  • TypeScript 类型体操通关秘籍
  • 现代CSS
  • React 通关秘籍

    • 1.关于本小册
    • 2.一网打尽组件常用Hook
    • 3.Hook的闭包陷阱的成因和解决方案
    • 4.React组件如何写TypeScript类型
    • 5.React组件如何调试
    • 6.受控模式VS非受控模式
    • 7.组件实战:迷你Calendar
    • 8.组件实战:Calendar日历组件(上)
    • 9.组件实战:Calendar日历组件(下)
    • 10.快速掌握Storybook
    • 11.React组件如何写单测
    • 12.深入理解Suspense和ErrorBoundary
    • 13.组件实战:Icon图标组件
    • 14.组件实战:Space间距组件
    • 15.React.Children和它的两种替代方案
    • 16.三个简单组件的封装
    • 17.浏览器的5种Observer
    • 18.组件实战:Watermark防删除水印组件
    • 19.手写react-lazyload
    • 20.图解网页的各种距离
    • 21.自定义hook练习
    • 22.自定义hook练习(二)
    • 23.用react-spring做弹簧动画
    • 24.react-spring结合use-gesture手势库实现交互动画
    • 25.用react-transition-group和react-spring做过渡动画
    • 26.快速掌握Tailwind:最流行的原子化CSS框架
    • 27.用CSSModules避免样式冲突
    • 28.CSSInJS:快速掌握styled-components
    • 29.react-spring实现滑入滑出的转场动画
    • 30.组件实战:Message全局提示组件
    • 31.组件实战:Popover气泡卡片组件
    • 32.项目里如何快速定位组件源码
    • 33.一次超爽的React调试体验
    • 34.组件实战:ColorPicker颜色选择器(一)
    • 35.组件实战:ColorPicker颜色选择器(二)
    • 36.组件实战:onBoarding漫游式引导组件
    • 37.组件实战:Upload拖拽上传
    • 38.组件实战:Form表单组件
    • 39.React组件库都是怎么构建的
    • 40.组件库实战:构建esm和cjs产物,发布到npm
    • 41.组件库实战:构建umd产物,通过unpkg访问
    • 42.数据不可变:immutable和immer
    • 43.基于ReactRouter实现keepalive
    • 44.Historyapi和ReactRouter实现原理
    • 45.ReactContext的实现原理和在antd里的应用
    • 46.ReactContext的性能缺点和解决方案
    • 47.手写一个Zustand
    • 48.原子化状态管理库Jotai
    • 49.用react-intl实现国际化
    • 50.国际化资源包如何通过Excel和GoogleSheet分享给产品经理
    • 51.基于react-dnd实现拖拽排序
    • 52.react-dnd实战:拖拽版TodoList
    • 53.ReactPlayground项目实战:需求分析、实现原理
    • 54.ReactPlayground项目实战:布局、代码编辑器
    • 55.ReactPlayground项目实战:多文件切换
    • 56.ReactPlayground项目实战:babel编译、iframe预览
    • 57.ReactPlayground项目实战:文件增删改
    • 58.ReactPlayground项目实战:错误显示、主题切换
    • 59.ReactPlayground项目实战:链接分享、代码下载
    • 60.ReactPlayground项目实战:WebWorker性能优化
    • 61.ReactPlayground项目实战:总结
    • 62.手写MiniReact:思路分析
    • 63.手写MiniReact:代码实现
    • 64.手写MiniReact:和真实React源码的对比
    • 65.React18的并发机制是怎么实现的
    • 66.Ref的实现原理
    • 67.低代码编辑器:核心数据结构、全局store
    • 68.低代码编辑器:拖拽组件到画布、拖拽编辑json
    • 69.低代码编辑器:画布区hover展示高亮框
    • 70.低代码编辑器:画布区click展示编辑框
    • 71.低代码编辑器:组件属性、样式编辑
    • 72.低代码编辑器:预览、大纲
    • 73.低代码编辑器:事件绑定
    • 74.低代码编辑器:动作弹窗
    • 75.低代码编辑器:自定义JS
    • 76.低代码编辑器:组件联动
    • 77.低代码编辑器:拖拽优化、Table组件
    • 78.低代码编辑器:Form组件、store持久化
    • 79.低代码编辑器:项目总结
    • 80.快速掌握ReactFlow画流程图
    • 81.ReactFlow振荡器调音:项目介绍
    • 82.ReactFlow振荡器调音:流程图绘制
    • 83.ReactFlow振荡器调音:合成声音
    • 84.AudioContext实现在线钢琴
    • 85.React服务端渲染:从SSR到hydrate
    • 86.小册总结

学完 React Flow,我们来做一个实战案例:振荡器调音。

什么是振荡器呢?

我们知道,声音是由振动产生的,不同的频率,不同的振动波型,就会产生不同的声音。

比如钢琴的琴键,每个键的声音都不同,这个就是不同的振荡频率产生的。

浏览器提供了振荡器的 api createOscillator:

image.png

这样用:

image.png

var audioCtx = new (window.AudioContext || window.webkitAudioContext)();

var oscillator = audioCtx.createOscillator();

oscillator.type = "square";
oscillator.frequency.setValueAtTime(3000, audioCtx.currentTime);
oscillator.connect(audioCtx.destination);
oscillator.start();

你可以现在打开 devtools 跑下这段代码:

image.png

是不是听到了一个持续的尖锐的声音?

这就是振荡器生成的。

我们可以设置不同的频率、波形,产生不同的声音。

频率好理解,不同波形也就是这个:

2024-08-29 10.20.08.gif

你可以打开链接听一下区别。

正弦波(sine):

image.png

jaudio

方波(square):

image.png

jaudio

三角波(triangle):

image.png

jaudio

锯齿波(sawtooth):

image.png

jaudio

有的同学可能会问,这有什么用呢?

有很多用处:

比如生成钢琴不同琴键的声音:

2024-08-29 10.26.21.gif

jaudio

实现原理就是正弦波,不同琴键振荡频率不同:

所以说,通过 createOscillator 创建振荡器,然后修改波形、修改频率,就能产生不同的声音。

这个频率在网上也可以搜到:

image.png

声音调好了之后,你还可以通过 GainNode 调节音量:

image.png

比如下面的代码:

image.png

通过 createOscillator 创建振荡器,然后用 createGain 创建调节音量的节点。

oscillator 连接 gainNode,gainNode 连接最终输出。

这样,就实现了调音、音量修改、输出声音的流程。

这个过程很适合用流程图来做:

2024-08-29 11.25.33.gif

在振荡器节点调节频率和波形,在 Gain 节点调节音量,最后在输出节点播放调节好的声音。

而且振荡器节点是可以设置多个的,会把多种声音合并播放:

image.png

这就是我们要做的实战项目,通过 React Flow 添加振荡器节点、设置参数,节点连接之后,播放合成的声音。

总结

这节我们学了 AudioContext 的 createOscillator api,它会创建一个振荡器,可以设置不同的波形、频率,产生不同的声音。

比如钢琴琴键的声音,游戏中的一些音效,都是设置不同波形、频率产生的。

而且还可以通过 GainNode 来调节音量。

可以通过流程图来可视化的创建 Oscillator 节点,设置参数,最后输出声音。

下节开始我们正式进入开发。

上次更新: 6/21/25, 9:42 AM
贡献者: YNight
Prev
80.快速掌握ReactFlow画流程图
Next
82.ReactFlow振荡器调音:流程图绘制