Skip to content

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 即可:

OpenCode Zen MiMo V2.5 Free 模型选择

2. 为什么本节“不加装 omo-slim 与重型 MCP”? ​

在上一节 5.2 高级配置 中,我们学习了功能强大的 oh-my-opencode-slim 多角色协作和 MCP 扩展坞。但在第一次破冰实战中,我们特意采用极简纯净方案:

💡 核心考量:

  1. 降低上手门槛:先掌握 OpenCode 最原生的 Plan 模式(规划) 与 Build 模式(构建);
  2. 凸显原生实力:体验在不依赖额外复杂插件的情况下,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 文件,各自独立运行)
Plan 模式交互提问 1/4

问题 2/4:木鱼交互偏好 ​

“木鱼的交互方式你有偏好吗?”

  • 选项 A:点击木鱼敲击(点击木鱼本体,有敲击动效和音效)
  • 选项 B:敲击木槌(用鼠标拖动木槌敲击)
  • 选项 C:都行,你推荐(根据极客风格来设计)
Plan 模式交互提问 2/4

问题 4/4:番茄钟核心功能 ​

“番茄钟需要哪些核心功能?”

  • 选项 A:基础计时器(25分钟工作 + 5分钟休息,简单切换)
  • 选项 B:带统计(计时 + 今日完成番茄数统计)
  • 选项 C:完整版(计时 + 统计 + 白噪音/环境音)
Plan 模式交互提问 4/4

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本地保存功德数、番茄钟完成数

📂 文件结构 ​

text
05_OpenCode实战/project_01_赛博解压小工具/
├── cyber-muyu.html        # 赛博木鱼
└── pomodoro-clock.html    # 专注番茄钟

Build 模式:从计划转入实现 ​

确认方案无误后,我们直接将 OpenCode 切换至 Build(构建模式),输入:“确认”。

1. AI 自主建立任务追踪与规范遵循 ​

进入 Build 模式后,AI 会自动建立 Todo 进度项,严格遵循 AGENTS.md 和 .opencode/skills/ 里的开发规则:

  1. 采用单文件 HTML 架构;
  2. 使用 Tailwind CSS CDN;
  3. 赛博朋克暗黑风格;
  4. 不擅自 commit。
Build 模式任务列表与规范遵循

随后,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)。

3. 实现要点二:HTML5 Canvas 60fps 霓虹粒子与连击系统


4. 实现要点三:SVG 动态圆环进度与时空舱番茄钟 ​

在 pomodoro-clock.html 中,倒计时采用了现代极客最爱的 SVG 动态圆环描边偏移(stroke-dashoffset) 算法:

  • ⚡ 深度专注模式(25分钟):冷艳青色霓虹光晕(#00f0ff);
  • ☕ 快速小憩模式(5分钟):浪漫品红霓虹光晕(#ff007f);
  • 🌴 深度大休模式(15分钟):温暖琥珀金霓虹光晕(#f59e0b);
  • 🚀 10秒快速演示模式:在设置弹窗中一键开启,无需苦等 25 分钟即可立即验证到时提醒和水晶和弦音效。

即时反馈:双击即跑与真实浏览器运行效果 ​

代码生成完毕后,所有文件均已妥善保存在项目目录下的 project_01_赛博解压小工具/ 文件夹中:

快速体验方式:双击打开。 ​

因为这两个小工具都是标准的自包含单文件 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 交互网页:灵感卡片生成器。

官方权威与拓展学习资源 ​