竹知了:零依赖单文件,用 Web Audio 复刻传统玩具的哇哇声

探索竹知了项目:一个零依赖单文件的 Web 模拟,真实录音采样、绳系质点物理,移动端优先,带你重温童年玩具的声音。

竹知了:零依赖单文件,用 Web Audio 复刻传统玩具的哇哇声

还记得小时候路边摊上几块钱一个的竹知了吗?一转就发出“哇——哇——”的叫声,烦人又让人着迷。如今实物越来越难找,但一位开发者用纯前端技术把它搬到了浏览器里——竹知了(zhuzhiliao)是一个零依赖、单文件的 Web 模拟,真实录音采样,移动端优先,打开即玩。

为什么值得关注?

这个项目最吸引人的地方在于它的极简与深度并存

  • 零依赖单文件:整个应用就是一个 index.html,内嵌了 Canvas 渲染、Web Audio 音频处理、录音采样,甚至 PWA 的 manifest 和 service worker。无需构建,无需联网,双击就能玩。
  • 真实物理模拟:竹筒被建模为绳系质点,重力、弹性绳、空气阻力,用 1/240 秒定步长积分。发声的核心变量是绳方向的角速度——转得越快,绳越紧,声音越响越亮。
  • 真实录音采样:主音源是从实拍视频中截取的 1.72 秒录音(恰好 4 个“哇”周期),经过包络对齐和无缝循环处理,以 AAC 格式内嵌在 HTML 中。回放速率随甩动转速变化,甩得越快叫得越急越高。

玩法与交互

打开页面后,你可以:

  • 手动甩:按住屏幕画圈,像甩真玩具一样。触屏时锚点会自动抬到指尖上方,避免手挡住小蝉。
  • 自动甩:点击按钮或按空格键,让玩具自己转起来。
  • 甩手机(移动端,需 HTTPS 或本地文件):握住手机划圈,重力方向在机身坐标里转动,直接驱动甩杆。iOS 首次需授权动作传感器。

技术亮点

声音合成链

如果录音采样解码失败,项目还内置了一套纯合成兜底方案,模拟真实玩具的发声原理:

真实玩具 合成实现
松香黏滑摩擦产生脉冲 锯齿波振荡器,频率随转速升高(55~195 Hz),tanh 软削波增毛糙谐波
蝉鸣颗粒感 24~45 Hz 正弦低频调幅 + 带通摩擦噪声底
竹膜 + 筒腔共鸣 三个并联带通共振峰(1050 / 2150 / 3350 Hz)
转圈带来的“哇——哇——” 带通滤波器中心频率随转动相位扫频

物理模拟

竹筒是绳系质点,受力包括重力、只拉不推的弹性绳、空气阻力。发声条件是绳方向的角速度超过约 1.1 圈/秒且绳张紧,否则不发声。松手后靠惯性余音渐歇。

移动端优先

  • 安全区适配,绳长随屏幕缩放。
  • 触摸时锚点自动上移,避免手指遮挡。
  • 多点触控互斥,防止误操作。
  • 音频在首次触摸/点击时初始化,并在抬手时补解锁(符合 user activation 规则)。
  • iOS 的 interrupted 状态和旧内核 roundRect 均有兜底。

性能优化

静态场景预合成为离屏层,静置 8 秒自动挂起音频线程省电。

计数与隐私

页面底部显示你自己的“哇数”,手动甩出的每一圈记一“哇”,自动甩不计。数据存在浏览器 localStorage 中,不上传、不联网、没有后端——页面加载完就再不发任何请求。

早先有过一套 Cloudflare Worker + Durable Object 的全站实时计数,现已整体下线,后端代码也从仓库移除。

许可与声明

注意:本项目不是开源项目。源码公开仅供学习交流,但未授权任何人再分发或公开部署。官方站点只有 https://zhuzhiliao.icu,其他任何域名上的部署都未经授权。

允许:阅读研究源码、在自己拥有或控制的设备上本地运行、为学习或个人使用而修改。

不授权:再分发(含修改版)、部署到第三方可访问的位置、对外提供服务、商业使用、移除版权声明。

如何本地运行

# 直接打开 index.html 即可,无需构建
# 或者起个静态服务,手机连同一 Wi-Fi 访问
python3 -m http.server 8123

总结

竹知了是一个把传统玩具与现代 Web 技术巧妙结合的案例。它展示了如何用单文件实现复杂的物理模拟和音频处理,同时保持极致的可移植性。无论你是对 Web Audio 感兴趣,还是想重温童年记忆,都值得打开 https://zhuzhiliao.icu 甩两下。

如果它唤起了你的回忆,或者你觉得这套“真实录音采样 + 绳系质点物理”塞进单文件的做法有点意思,不妨去 GitHub 点个 Star。

Source

imsai-sh/zhuzhiliao: 竹知了 —— 一转就哇哇叫的传统玩具,Web 模拟版。零依赖单文件,真实录音采样,移动端优先。