📢 新文章推送 · 每周更新优质内容 · 订阅更新 →
向下滚动
测试笔记

番茄钟专注计时器功能实现

AI 智能总结

功能概述

番茄钟是一个基于番茄工作法的专注计时器,完全在浏览器端运行,无需后端支持。核心特性包括:

  • 三种计时模式:专注(25min)、短休息(5min)、长休息(15min)
  • 圆形 SVG 进度条动画,不同模式不同颜色
  • 白噪音合成:6种环境音(雨声、森林、海浪等)
  • 任务清单:添加/完成/删除任务
  • 今日统计:完成番茄数、专注分钟、连续番茄、目标进度
  • 完成提醒音:Web Audio API 合成提示音
  • 数据持久化:localStorage 保存今日统计

页面架构

番茄钟作为独立页面类型(type: pomodoro)集成到 Hugo 主题中,与出行轨迹、在线工具等页面并列在导航栏「探索」菜单下。

1content/pomodoro/_index.md         ← 内容页面(Front Matter)
2layouts/pomodoro/single.html       ← 页面模板(HTML + CSS + JS)

内容页面

1---
2title: "番茄钟"
3type: pomodoro
4url: /pomodoro/
5---

首页排除

layouts/index.html 中排除 pomodoro 类型,避免在首页文章卡片中显示:

1{{ $allArticles := where ... "Type" "not in" (slice "moments" "amap" "pomodoro") }}

核心实现

1. 圆形进度条

使用 SVG stroke-dasharraystroke-dashoffset 实现环形进度条:

1<svg viewBox="0 0 280 280">
2  <circle class="pomo-clock-bg" cx="140" cy="140" r="126"></circle>
3  <circle class="pomo-clock-progress" cx="140" cy="140" r="126"
4    stroke-dasharray="791.68" stroke-dashoffset="0"></circle>
5</svg>

进度计算:

1var CIRCUMFERENCE = 2 * Math.PI * 126; // ≈ 791.68
2var progress = 1 - (state.timeLeft / state.totalTime);
3var offset = CIRCUMFERENCE * (1 - progress);
4element.style.strokeDashoffset = offset;

不同模式使用不同颜色:

  • 专注:红色渐变 #ef4444 → #f97316
  • 短休息:绿色渐变 #22c55e → #10b981
  • 长休息:紫色渐变 #6366f1 → #8b5cf6

2. 计时器逻辑

使用 setInterval 每秒更新,状态机管理三种模式切换:

 1var state = {
 2  mode: 'work',        // 当前模式
 3  running: false,      // 是否运行中
 4  timeLeft: 25 * 60,   // 剩余秒数
 5  totalTime: 25 * 60,  // 总秒数
 6  pomosCompleted: 0,   // 已完成番茄数
 7  streak: 0,           // 连续番茄
 8  totalMinutes: 0      // 总专注分钟
 9};
10
11function tick() {
12  if (state.timeLeft <= 0) { complete(); return; }
13  state.timeLeft--;
14  updateDisplay();
15}

完成一个番茄后自动切换:

  • 每 4 个番茄后进入长休息
  • 其他情况进入短休息
  • 休息结束后自动切回专注模式

3. 白噪音合成

使用 Web Audio API 生成白噪音,无需加载外部音频文件:

 1function createNoise(type) {
 2  var audioCtx = new AudioContext();
 3  var bufferSize = 2 * audioCtx.sampleRate;
 4  var buffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);
 5  var data = buffer.getChannelData(0);
 6
 7  // 不同类型使用不同的噪声算法
 8  if (type === 'rain') {
 9    for (var i = 0; i < bufferSize; i++)
10      data[i] = (Math.random() * 2 - 1) * 0.3;
11  } else if (type === 'ocean') {
12    for (var i = 0; i < bufferSize; i++) {
13      var wave = Math.sin(i / audioCtx.sampleRate * Math.PI * 0.1);
14      data[i] = (Math.random() * 2 - 1) * 0.2 * (0.5 + 0.5 * wave);
15    }
16  }
17  // ... 其他类型
18
19  var source = audioCtx.createBufferSource();
20  source.buffer = buffer;
21  source.loop = true;
22  source.connect(gainNode);
23  gainNode.connect(audioCtx.destination);
24}

6种白噪音的区别:

类型音量特点
雨声0.3纯随机噪声
森林0.15低音量噪声
海浪0.2正弦波调制噪声
篝火0.1低音量噪声
咖啡厅0.08极低音量噪声
微风0.12中等音量噪声

同一时间只能播放一种白噪音,切换时自动关闭前一个。

4. 提示音

计时完成时使用 Web Audio API 合成双音提示:

 1function playNotification() {
 2  var ctx = new AudioContext();
 3  // 第一声 800Hz
 4  var osc = ctx.createOscillator();
 5  osc.frequency.value = 800;
 6  osc.type = 'sine';
 7  // 0.3秒后第二声 1000Hz
 8  setTimeout(function() {
 9    var osc2 = ctx.createOscillator();
10    osc2.frequency.value = 1000;
11  }, 300);
12}

5. 数据持久化

今日统计数据保存到 localStorage,按日期重置:

1var today = new Date().toDateString();
2var saved = JSON.parse(localStorage.getItem('pomo_stats'));
3
4if (saved && saved.date === today) {
5  // 恢复今日数据
6  state.pomosCompleted = saved.pomos;
7  state.totalMinutes = saved.minutes;
8  state.streak = saved.streak;
9}

6. 页面标题

运行时在浏览器标签页显示倒计时:

1document.title = (state.running
2  ? String(min).padStart(2,'0') + ':' + String(sec).padStart(2,'0') + ' - '
3  : '') + '番茄钟';

样式统一

番茄钟页面的布局和样式与出行轨迹、在线工具等页面保持统一:

  • Banner:180px 高度渐变背景,圆角 20px,阴影效果
  • 布局:隐藏侧边栏,内容区最大宽度 860px 居中
  • 暗色模式:完整适配,渐变背景切换为深色调
  • 响应式:900px 和 600px 两个断点,移动端适配
  • 图标动画:标题图标带脉冲动画,与出行轨迹的弹跳动画风格一致

技术要点总结

模块技术方案
进度条SVG stroke-dashoffset 动画
计时器setInterval + 状态机
白噪音Web Audio API AudioBuffer 合成
提示音Web Audio API OscillatorNode
数据持久化localStorage 按日期存储
页面标题document.title 动态更新
任务清单纯 JS 数组管理 + DOM 渲染
样式CSS 变量 + 暗色模式 + 响应式
4 / 9
版权声明

本文作者 Lumin

本文链接 https://www.zhengquan.xyz/biji/pomodoro-timer-implementation/

许可协议 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

请作者喝杯咖啡 ☕

  • 微信打赏
    微信支付
  • 支付宝打赏
    支付宝
点击按钮查看打赏二维码
🎁 推荐工具
试试这些实用在线工具,提升工作效率
前往工具集 →

留言评论

期待你的想法

评论加载中