主题
5.3 单文件小工具:木鱼与番茄钟
木鱼和番茄钟功能不多,却包含了需求讨论、界面交互、状态保存和浏览器验证这些完整环节。我们先用单个 HTML 文件完成它们,练习把一个想法逐步变成可以检查的结果。
什么是“意图驱动”与“单文件架构”?
在过去,如果你想做一个具有交互动效、音效播放和本地存储的网页小工具,通常需要经历漫长的工序:搭脚手架、配置打包工具、设计 CSS 样式、寻找无版权音效 MP3 文件、调试 JavaScript 逻辑……
而在 Vibe Coding 时代,这个过程发生了变化:
- 🍳 意图驱动(Intent-Driven):就像你去一家米其林餐厅点餐,你只需要说“我想要一份七分熟、带黑松露香气的菲力牛排”,大厨(AI)就会主动向你确认配菜偏好、烹饪温度,随后在后厨完成所有煎烤与摆盘,直接把成品端到你面前;
- 自包含单文件应用(Single-File App):HTML 结构、页面样式、Web Audio 音效和 Canvas 动效都放在一个
.html文件中。它不需要 Node.js 构建步骤;若使用 CDN 或本地存储,仍要检查网络与浏览器限制。
实战前置:对齐模型与 Skills 配置
动手前先统一实战环境,避免安装和配置差异影响后面的练习。
1. 选用零门槛免费模型:OpenCode Zen MiMo V2.5 Free
对于本节这种轻量级的前端单文件实战,完全不需要调用昂贵的商业旗舰大模型。OpenCode 官方提供的免费模型 MiMo V2.5 Free 已经具备了极强的推理与代码生成能力:
- 🚀 完全免费:零 API 计费负担,新手随便折腾不用心疼 Token;
- 🧠 支持深度推理(Reasoning):能在生成代码前自主规划 DOM 结构与动画链路;
- 📚 200,000 超长上下文:轻松容纳几千行代码与设计上下文。
在 OpenCode 顶部或右下角模型切换面板中,选择 MiMo V2.5 Free 即可:

2. 为什么本节“不加装 omo-slim 与重型 MCP”?
在上一节 5.2 高级配置 中,我们学习了功能强大的 oh-my-opencode-slim 多角色协作和 MCP 扩展坞。但在第一次破冰实战中,我们特意采用极简纯净方案:
💡 核心考量:
- 降低上手门槛:先掌握 OpenCode 最原生的 Plan 模式(规划) 与 Build 模式(构建);
- 凸显原生实力:体验在不依赖额外复杂插件的情况下,AI 仅凭自身推理与基础规范就能交付的高水准。
3. Skills 还是全局 Skills?
在 OpenCode 中,Skills(技能包)支持两种存放形式:
| 技能类型 | 存放路径 | 作用范围 | 适用场景 |
|---|---|---|---|
| 全局技能 (Global Skills) | ~/.config/opencode/skills/ | 全局所有项目可见 | 通用的代码规范(如 simplify 重构规则、全局 git 规范) |
| 技能 (Project Skills) | 当前项目根目录下的 .opencode/skills/ | 仅当前项目生效 | 特定项目依赖的前端动效规范、特定框架模板、专属 API 契约 |
🌟 配置的巨大优势: 我们可以直接让 AI 帮我们把需要的 skills 下载或生成到当前项目的
.opencode/skills/目录下。 这样不仅完全不会影响到电脑里的其他项目,而且当把整个项目文件夹分享给他人或提交到团队代码仓时,所有协作者都能立刻获得完全一致的 AI 辅助能力。
本节实战中,我们已经在项目目录 .opencode/skills/ 中挂载了以下五大核心技能,它们各司其职、组合发力,共同保障 AI 交付出颜值与质量俱佳的单文件应用:
- 📦
single-file-app:约定单文件 HTML 规范(通过公共 CDN 引入 Tailwind CSS、Lucide 图标、LocalStorage 持久化、双击即跑); - 🎨
tailwind-ui-master:约定暗黑深色系 + 毛玻璃拟态(Glassmorphism)+ 霓虹渐变点缀的高质感 UI 设计规范,让木鱼与番茄钟自带沉浸式赛博朋克审美; - ✨
html5-canvas-artist:约定 Canvas 60fps 粒子爆发动效与 Web Audio API 纯原生合成音效规范(免除外链 MP3 丢失风险); - 🧹
simplify:约定代码精简重构规则(消除深嵌套、剔除冗余样板代码),确保生成的单文件代码整洁、清晰、易读; - 🌐
agent-browser:约定自动化浏览器测试规范(模拟点击交互、截图、检查控制台报错),用于双击即跑后的可视化自查与验收闭环。
💡 Skills 是「可插拔的军火库」,随时按需补充:技能包并非一成不变,随着项目不断进阶,你随时可以在
.opencode/skills/中挂载更多专项技能(如后端 API、数据可视化、文档生成等),让 AI 始终遵循最新、最合适的规范作战。
Plan 模式:从模糊灵感开启“需求对齐会”
1. 提出初始需求
在开发初期,我们往往只有一个模糊的方向:“我想做个解压木鱼和番茄钟”,但并不清楚具体需要哪些控件、什么样的配色或交互形式。
此时,千万不要直接开工写代码。我们先将 OpenCode 切换至 Plan(规划模式),输入提示词:
text
要做赛博极客解压木鱼 & 专注番茄钟这个小工具,但我没有什么头绪,你能和我讨论一些方案吗?2. 交互式多轮需求对齐
收到意图后,OpenCode 并没有盲目堆砌代码,而是化身为资深产品经理兼架构师,通过交互式弹窗向我们发起了针对性提问:
问题 1/4:架构形态选择
“你希望这两个功能是合并成一个应用,还是做成两个独立的小工具?”
- 选项 A:合并成一个应用(木鱼解压 + 番茄钟计时,在一个界面里切换)
- 选项 B:两个独立应用(两个独立的 HTML 文件,各自独立运行)

问题 2/4:木鱼交互偏好
“木鱼的交互方式你有偏好吗?”
- 选项 A:点击木鱼敲击(点击木鱼本体,有敲击动效和音效)
- 选项 B:敲击木槌(用鼠标拖动木槌敲击)
- 选项 C:都行,你推荐(根据极客风格来设计)

问题 4/4:番茄钟核心功能
“番茄钟需要哪些核心功能?”
- 选项 A:基础计时器(25分钟工作 + 5分钟休息,简单切换)
- 选项 B:带统计(计时 + 今日完成番茄数统计)
- 选项 C:完整版(计时 + 统计 + 白噪音/环境音)

3. AI 输出的完整技术与设计蓝图
在收集完我们的偏好后,AI 立即整理出了一份条理清晰的详细设计方案:
好的,方案清晰了。下面是两个独立应用的详细设计讨论:
🥁 应用一:赛博木鱼
核心体验:点击木鱼 → 视觉/听觉反馈 → 功德数字飙升
元素 说明 木鱼本体 暗黑风格 + 霓虹描边,点击时触发缩放回弹动画 敲击音效 Web Audio 合成木质敲击声(零 MP3),低沉浑厚 飘字反馈 每次敲击弹出 +1 功德 / 赛博功德 +1,随机位置上浮消失 连击特效 连续快速点击触发霓虹光晕 + 粒子爆发 功德计数 大号数字显示,带千分位格式化 赛博朋克元素:
- 背景:深空黑 + 霓虹网格地面(CSS 扫描线与网格)
- 故障艺术:功德数字偶尔抖动/错位
- 霓虹光效:木鱼边缘发光,点击时脉冲扩散
- 色调:紫 / 青 / 粉 霓虹三色系
⏱️ 应用二:专注番茄钟
核心体验:25分钟专注 → 5分钟休息,干净利落
元素 说明 环形进度条 SVG 圆环倒计时,霓虹渐变描边 状态切换 专注中 → 休息中,自动循环 开始/暂停 一个按钮搞定,极简操作 音效提示 到时触发合成提示音(不吓人,有科技感) 赛博朋克元素:
- 背景:暗黑 + 漂浮的代码粒子
- 配色:专注时青色冷调,休息时紫色暖调
- 字体:等宽字体(JetBrains Mono / Fira Code)模拟终端感
🛠️ 技术选型
技术 用途 Tailwind CSS (CDN) 快速样式开发,暗黑模式 Lucide Icons (CDN) 播放/暂停等图标 Web Audio API 零依赖纯算法合成音效 HTML5 Canvas 粒子系统、飘字动效 CSS Animations 脉冲、悬浮与扫描线效果 LocalStorage 本地保存功德数、番茄钟完成数 📂 文件结构
text05_OpenCode实战/project_01_赛博解压小工具/ ├── cyber-muyu.html # 赛博木鱼 └── pomodoro-clock.html # 专注番茄钟
Build 模式:从计划转入实现
确认方案无误后,我们直接将 OpenCode 切换至 Build(构建模式),输入:“确认”。
1. AI 自主建立任务追踪与规范遵循
进入 Build 模式后,AI 会自动建立 Todo 进度项,严格遵循 AGENTS.md 和 .opencode/skills/ 里的开发规则:
- 采用单文件 HTML 架构;
- 使用 Tailwind CSS CDN;
- 赛博朋克暗黑风格;
- 不擅自 commit。

随后,AI 依次完成两个独立应用的编写,生成文件结构清晰明了:

2. 实现要点一:Web Audio API 纯算法合成音效(零外部 MP3 依赖)
很多传统前端教程在做音效时,都会让大家去网上找 dong.mp3 或 bell.wav。但外链音频经常失效、加载缓慢,甚至有跨域或版权风险。
在本项目中,AI 使用了浏览器的原生 Web Audio API:
javascript
// 🎵 纯算法实时合成沉浸式木鱼敲击声
function playWoodblockSound() {
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const now = audioCtx.currentTime;
// 1. 创建三角波振荡器模拟木质共鸣
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
const filter = audioCtx.createBiquadFilter();
osc.type = 'triangle';
// 频率在 0.12 秒内由 580Hz 骤降至 120Hz,模拟敲击木质空腔的瞬态衰减
osc.frequency.setValueAtTime(580, now);
osc.frequency.exponentialRampToValueAtTime(120, now + 0.12);
// 2. 带通滤波器滤除多余高频,让声音更浑厚扎实
filter.type = 'bandpass';
filter.frequency.setValueAtTime(650, now);
filter.Q.setValueAtTime(3, now);
// 3. 指数音量衰减,杜绝爆音
gain.gain.setValueAtTime(0.9, now);
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.12);
// 4. 连接音频节点链路:振荡器 -> 滤波器 -> 音量增益 -> 扬声器输出
osc.connect(filter);
filter.connect(gain);
gain.connect(audioCtx.destination);
osc.start(now);
osc.stop(now + 0.12);
}音效由浏览器在本地合成,无需下载 MP3。实际响应仍受浏览器音频策略和设备影响,应检查首次点击与连续点击的表现。
3. 实现要点二:HTML5 Canvas 60fps 霓虹粒子与连击系统
在 cyber-muyu.html 中,每次点击木鱼,除了触发木鱼本身的缩放回弹动画外,底层 Canvas 会根据点击坐标以物理速度、角度和透明度衰减发射一簇霓虹粒子,并触发随机祝福语上浮飘字(如 功德 +1 · 需求不改、功德 +1 · 线上零 Bug、功德 +1 · 头发茂密)。
快速连续敲击还会触发 Combo 连击倍率计算(x2 ~ x99) 与 100 次敲击大圆满的五彩纸屑撒花特效(canvas-confetti)。
4. 实现要点三:SVG 动态圆环进度与时空舱番茄钟
在 pomodoro-clock.html 中,倒计时采用了现代极客最爱的 SVG 动态圆环描边偏移(stroke-dashoffset) 算法:
- ⚡ 深度专注模式(25分钟):冷艳青色霓虹光晕(
#00f0ff); - ☕ 快速小憩模式(5分钟):浪漫品红霓虹光晕(
#ff007f); - 🌴 深度大休模式(15分钟):温暖琥珀金霓虹光晕(
#f59e0b); - 🚀 10秒快速演示模式:在设置弹窗中一键开启,无需苦等 25 分钟即可立即验证到时提醒和水晶和弦音效。
即时反馈:双击即跑与真实浏览器运行效果
代码生成完毕后,所有文件均已妥善保存在项目目录下的 project_01_赛博解压小工具/ 文件夹中:
- 📁 木鱼应用:cyber-muyu.html
- 📁 番茄钟应用:pomodoro-clock.html
快速体验方式:双击打开。
因为这两个小工具都是标准的自包含单文件 HTML 格式,你不需要在本地运行任何 Node.js 服务,也不需要打开命令行,直接双击文件,就能在浏览器中打开运行。
1. 赛博解压木鱼(Cyber Muyu)实际效果
深黑背景搭配赛博霓虹网格,中心是发光的赛博木鱼,点击伴随着清脆的 Web Audio 合成音效与飘字,非常解压:

2. 专注番茄钟(Focus Clock)实际效果
科技感十足的青色发光倒计时环、等宽数字显示、实时的番茄轮次与专注统计,营造出沉浸的专注氛围:

💡 进阶自测:本节五大 Skills 中已挂载
agent-browser。想体验自动化验收闭环,可以让 AI 调用该技能在真实浏览器中模拟点击、切换模式并截图检查控制台报错,形成「生成 → 自测 → 微调」的闭环(更完整的演示见 5.4 节)。
意图微调:不满意就「追加一句话」
双击打开体验后,如果对某个细节不满意(比如木鱼敲击声太闷、番茄钟配色想换、飘字文案想改),不需要重新开一个会话,直接在原会话里追加一句新意图即可:
💬 追加示例: “木鱼敲击声再清脆一点,飘字改成‘心诚则灵’,番茄钟专注时长改成 50 分钟。”
AI 会基于已有代码做最小改动(Surgical Edit),而不是推倒重来。这正是 Vibe Coding 的核心体验之一:把改动意图讲清楚,剩下的交给 AI。
实战探秘:挂载 Skills 与不挂载 Skills 的效果大 PK。
💡 给同学们的实操小建议: 强烈推荐大家在本地做一个趣味对比实验 —— 把前面同一份设计计划提示词发给没有加载 Skills 的 AI,与加载了 Skills 的 AI 进行一次 PK,亲身体会一下 Skills 技能包的巨大魔力。
| 对比维度 | ❌ 没有加载 Skills 的 AI | ✅ 挂载了五大 Skills(single-file-app + tailwind-ui-master + html5-canvas-artist 等) |
|---|---|---|
| 文件组织形式 | 可能把代码拆成 index.html、style.css、main.js 多个文件,或引入不需要的构建步骤。 | 按本项目约定生成一个 .html 文件,并说明 CDN、音效和本地存储的运行条件。 |
| 音效实现方案 | 代码可能引用仓库中并不存在的 MP3 文件,导致页面打开后没有声音。 | 使用 Web Audio API 在浏览器中合成音效,不依赖额外音频文件;仍需遵守浏览器的音频播放限制。 |
| UI 与交互审美 | 往往是灰白色的默认原生 HTML 按钮、生硬的文本换行,缺乏现代科技质感。 | 自动应用 Tailwind 暗黑深色系、霓虹发光(Glow)、平滑过渡动画与精美排版。 |
| 动效呈现水平 | 几乎没有动效,或者只是简单的 CSS 淡入淡出。 | 自动构建 HTML5 Canvas 60fps 粒子爆发物理系统 与 SVG 动态圆环渲染。 |
这个对比说明,Skills 的作用是把文件组织、交互边界和验收方式写成可重复采用的项目约定。它能减少遗漏,但最终效果仍要通过实际运行来判断。
把交互细节写成验收条件
“做一个好用的番茄钟”不足以决定暂停、刷新和到点提醒的行为。像定闹钟前先确认响铃时间一样,需要把几个状态约定清楚,AI 才能据此实现。
| 操作 | 需要约定的结果 |
|---|---|
| 开始计时 | 从设定时长开始;再次点击不启动第二个计时器 |
| 暂停后继续 | 保留剩余时间,不回到初始值 |
| 重置 | 停止当前计时,恢复设定值 |
| 刷新页面 | 明确选择恢复状态或重新开始 |
| 切换到后台再回来 | 剩余时间与实际经过的时间一致 |
浏览器后台标签页可能降低定时回调频率,因此倒计时不宜只依赖“每回调一次减一秒”。可以记录目标结束时间,在每次更新时根据当前时间计算剩余值。这样页面暂时不刷新,也不至于不断积累误差。
木鱼则重点检查连续点击、静音和音效首次启动。动效再丰富,也不能遮挡按钮或让快速点击失去响应。
本地保存不是云端备份。换浏览器、清理站点数据后记录可能消失,直接以文件方式打开时的 localStorage 行为也没有统一保证。需要稳定复现时,可使用本地网页服务并保持相同访问地址,参见 MDN 本地存储说明。
单文件应用仍然需要工程约束
代码集中在一个 HTML 文件中,部署步骤少了,但运行环境的差异仍然存在。页面若依赖 CDN,离线时样式或脚本可能加载失败;音效通常要在用户交互后才能播放;定时器在后台标签页中可能被降低频率。这些约束应写进需求和验收说明。
可再补四项检查:刷新后状态是否符合约定;快速连续点击是否创建重复任务;键盘能否操作主要按钮;静音或减少动画的用户是否仍能完成核心操作。若加入本地存储,还要给清空记录提供入口,并说明数据只保存在当前浏览器。
单文件适合功能边界清楚的小工具。当样式、逻辑和测试已经难以定位,或者多人需要同时修改不同部分时,再拆分文件更合适。是否拆分应由维护成本决定,不能只看代码行数。
本节回顾
单文件项目也需要明确交互状态。暂停、刷新、快速点击和后台计时这些细节,比页面第一次打开时的效果更能说明工具是否可用。
继续阅读:5.4 交互网页:灵感卡片生成器。
官方权威与拓展学习资源
- MDN Web Audio API 官方中文文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Audio_API
- MDN Canvas API 官方中文教程:https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API
- Tailwind CSS 官方文档:https://tailwindcss.com/docs
- Lucide 图标库官方检索:https://lucide.dev/icons/
- Canvas-Confetti 开源项目 (GitHub):https://github.com/catdad/canvas-confetti
- OpenCode 官方文档:https://opencode.ai/docs