极简番茄钟 + 任务看板:纯前端 Pomodoro 工具深度解析
关键词:Pomodoro、番茄钟、任务看板、纯前端、localStorage、CSS动画、requestAnimationFrame、暗色模式、响应式设计
一、什么是 Pomo-Board?
在快节奏的开发工作中,时间管理和任务追踪是提升效率的关键。番茄工作法(Pomodoro Technique)通过将工作时间划分为 25 分钟专注段和 5 分钟休息段,帮助开发者保持高效专注。
Pomo-Board 是 Toolion 平台(工具狮轻量应用中心)中的一个纯前端应用,它将番茄钟计时器与任务看板合二为一,提供了一站式的专注力管理方案。所有功能完全在浏览器端运行,无需后端服务,零配置开箱即用。
项目地址:极简番茄钟 + 任务看板

二、核心功能概览
| 番茄钟计时器 | 圆形进度环动画,专注/休息模式自动切换 |
| 任务管理 | 添加、完成、删除任务,任务列表实时更新 |
| 数据统计 | 每日番茄钟计数,持久化存储不丢失 |
| 多种时长预设 | 25/5、30/5、45/10 三种经典配置一键切换 |
| 暗色/亮色模式 | 一键切换主题,偏好自动保存 |
| 音频提醒 | 计时结束时播放提示音,视觉闪烁双重通知 |
| 键盘快捷键 | Enter 添加任务,空格键开始/暂停计时 |
| 每日自动重置 | 每天零点自动清空任务和计数 |
三、技术架构
3.1 整体架构
┌─────────────────────────────────────────────────┐
│ 客户端 (Browser) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ 番茄钟计时器 │ │ 任务看板 │ │ 设置系统 │ │
│ │ requestAnim │ │ localStorage│ │ 主题切换 │ │
│ │ CSS conic │ │ 任务CRUD │ │ 预设配置 │ │
│ │ 进度环 │ │ 计数统计 │ │ 每日重置 │ │
│ └──────────────┘ └──────────────┘ └──────────┘ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 音频通知 │ │ 键盘事件 │ │
│ │ Web Audio │ │ Enter/Space │ │
│ └──────────────┘ └──────────────┘ │
└──────────────────────┬──────────────────────────┘
│ 纯前端,无后端依赖
┌──────────────────────▼──────────────────────────┐
│ Toolion 平台 │
│ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ 应用列表 │ │ 路由注册 │ │ 静态资源服务 │ │
│ └──────────┘ └──────────┘ └──────────────┘ │
└─────────────────────────────────────────────────┘
3.2 技术栈
| 前端框架 | 原生 HTML/CSS/JS | 零框架依赖,极致轻量 |
| 构建工具 | npx serve | 静态文件服务,开发即启 |
| 样式方案 | CSS 自定义属性 | 主题切换、响应式布局 |
| 状态管理 | 全局 state 对象 | 集中式状态管理 |
| 持久化 | localStorage | 浏览器本地存储 |
| 动画引擎 | requestAnimationFrame | 流畅的计时动画 |
| 音频通知 | Web Audio API | 浏览器端音效合成 |
| 图标 | SVG + Emoji | 轻量级图标方案 |
四、核心实现详解
4.1 番茄钟计时器
番茄钟是应用的核心功能,采用 requestAnimationFrame 实现高精度计时,配合 CSS conic-gradient 实现圆形进度环动画。
计时循环实现:
const tick = (timestamp) => {
if (!state.lastTick) state.lastTick = timestamp;
const elapsed = (timestamp – state.lastTick) / 1000;
state.lastTick = timestamp;
if (state.timeRemaining > 0) {
state.timeRemaining -= elapsed;
if (state.timeRemaining < 0) state.timeRemaining = 0;
updateTimerDisplay();
state.rafId = requestAnimationFrame(tick);
} else {
endTimer();
}
};
state.rafId = requestAnimationFrame(tick);
圆形进度环:
进度环使用 CSS conic-gradient 实现,通过动态更新 –progress 变量来改变渐变色带的角度:
.timer-ring {
background: conic-gradient(
var(–accent) 0deg,
var(–accent) var(–progress, 0deg),
var(–border) var(–progress, 0deg),
var(–border) 360deg
);
-webkit-mask: radial-gradient(closest-side, white 85%, transparent 85%);
mask: radial-gradient(closest-side, white 85%, transparent 85%);
}
这种实现方式避免了 SVG 或 Canvas 的复杂性,仅用 CSS 即可实现流畅的进度动画。
4.2 任务管理
任务模块实现了完整的 CRUD 功能,所有操作即时持久化到 localStorage。
任务数据结构:
{
id: Date.now(), // 唯一标识
text: "任务内容", // 任务文本
completed: false, // 完成状态
createdAt: Date.now() // 创建时间
}
任务添加与完成:
function addTask() {
const text = elements.taskInput.value.trim();
if (!text) return;
const newTask = {
id: Date.now(),
text,
completed: false,
createdAt: Date.now()
};
state.tasks.unshift(newTask);
input.value = '';
renderTasks();
saveToStorage();
}
function toggleTask(index) {
const task = state.tasks[index];
task.completed = !task.completed;
if (task.completed) {
state.pomodoroCount++;
} else {
state.pomodoroCount = Math.max(0, state.pomodoroCount – 1);
}
renderTasks();
updatePomodoroCount();
saveToStorage();
}
番茄计数联动:每完成一个任务,番茄计数自动加 1;取消完成时自动减 1,确保数据一致性。
4.3 模式切换与自动流转
番茄钟支持专注模式和休息模式的无缝切换:
function endTimer() {
if (state.settings.currentMode === 'focus') {
state.settings.currentMode = 'break';
} else {
state.settings.currentMode = 'focus';
}
updateTimeRemaining();
elements.timerBtn.textContent = '开始';
playNotificationSound();
flashTimer();
}
计时结束后自动切换模式,并触发音频通知和视觉闪烁提醒。
4.4 主题系统
通过 CSS 自定义属性和 data-theme 属性实现亮色/暗色模式切换:
[data-theme="light"] {
–bg: #f5f5f5;
–surface: #ffffff;
–text: #1a1a1a;
–accent: #2563eb;
–success: #22c55e;
}
[data-theme="dark"] {
–bg: #1a1a1a;
–surface: #252525;
–text: #e0e0e0;
–accent: #3b82f6;
–success: #22c55e;
}
主题偏好通过 localStorage 自动保存,下次打开自动恢复。
4.5 音频通知
使用 Web Audio API 在计时结束时生成提示音,无需任何外部音频文件:
function playNotificationSound() {
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const oscillator = audioContext.createOscillator();
const gainNode = audioContext.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);
oscillator.frequency.setValueAtTime(800, audioContext.currentTime);
gainNode.gain.setValueAtTime(0.1, audioContext.currentTime);
gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.2);
oscillator.start(audioContext.currentTime);
oscillator.stop(audioContext.currentTime + 0.2);
}
4.6 键盘快捷键
应用支持全局键盘快捷键,提升操作效率:
function handleKeyDown(e) {
if (e.key === 'Enter' && document.activeElement === elements.taskInput) {
addTask();
}
if (e.key === ' ' && e.target.tagName !== 'INPUT' && e.target.tagName !== 'BUTTON') {
e.preventDefault();
startTimer();
}
}
- Enter:在输入框中快速添加任务
- 空格键:全局开始/暂停计时器
- 点击计时器:点击圆形计时器区域也可开始/暂停
4.7 每日自动重置
通过检测日期变化实现每日零点自动重置:
const today = new Date().toDateString();
const lastReset = localStorage.getItem('pomo_last_reset');
if (lastReset !== today) {
state.tasks = [];
state.pomodoroCount = 0;
localStorage.setItem('pomo_last_reset', today);
}
五、前端页面结构
5.1 整体布局
┌─────────────────────────────────────────────────┐
│ 导航栏:返回 │ 🍅 标题 │ 暗色/亮色切换 │
├─────────────────────────────────────────────────┤
│ 今日任务 🍅 0 │
├──────────────────────┬──────────────────────────┤
│ │ │
│ 任务输入区 │ 番茄钟计时器 │
│ ┌──────────┐ + │ ┌────────────┐ │
│ │ 输入框 │ │ │ 圆形进度环 │ │
│ └──────────┘ │ │ 25:00 │ │
│ │ │ 专注中 │ │
│ 任务列表 │ ├────────────┤ │
│ ┌────────────┐ │ │ 25/5 30/5 │ │
│ │ ☐ 任务1 │ │ │ [开始][重置] │ │
│ │ ☑ 任务2 │ │ └────────────┘ │
│ │ ☐ 任务3 │ │ │
│ └────────────┘ │ │
│ │ │
├──────────────────────┴──────────────────────────┤
│ 底部:粤ICP备… · Toolion · 工具狮 © 2026 │
└─────────────────────────────────────────────────┘
5.2 响应式设计
- 移动端(< 480px):任务区和计时器垂直堆叠,计时器缩小至 160px
- 桌面端(≥ 1024px):任务区和计时器左右并排布局,最大宽度 1024px
- 平板端:自适应中间尺寸
六、项目结构
apps/pomo-board/
├── index.html # HTML 入口,包含完整样式和结构
├── app.js # 核心逻辑:计时器、任务管理、主题切换
├── package.json # 依赖配置(仅需 npx serve)
├── favicon.svg # 应用图标(SVG 格式)
└── assets/
└── theme.js # 主题管理模块
七、关键代码解析
7.1 状态管理
Pomo-Board 采用集中式全局状态对象管理所有应用状态:
let state = {
tasks: [],
pomodoroCount: 0,
settings: { …DEFAULT_SETTINGS },
timeRemaining: 25 * 60,
isRunning: false,
isPaused: false,
lastTick: null,
rafId: null
};
所有状态变更后调用 saveToStorage() 持久化,确保刷新页面后数据不丢失。
7.2 requestAnimationFrame 计时精度
使用 requestAnimationFrame 而非 setInterval 的优势:
- 与浏览器刷新率同步,动画更流畅
- 页面不可见时自动暂停,节省资源
- 基于时间戳计算 elapsed,避免累积误差
const tick = (timestamp) => {
const elapsed = (timestamp – state.lastTick) / 1000;
state.timeRemaining -= elapsed;
state.rafId = requestAnimationFrame(tick);
};
7.3 CSS conic-gradient 进度环
进度环的核心实现利用了 CSS 的 conic-gradient 和 mask 属性:
.timer-ring {
background: conic-gradient(
var(–accent) 0deg,
var(–accent) var(–progress, 0deg),
var(–border) var(–progress, 0deg),
var(–border) 360deg
);
-webkit-mask: radial-gradient(closest-side, white 85%, transparent 85%);
mask: radial-gradient(closest-side, white 85%, transparent 85%);
}
mask 属性将中心区域挖空,形成环形进度效果。–progress 变量由 JavaScript 动态计算并更新。
7.4 持久化策略
function saveToStorage() {
localStorage.setItem(STORAGE_KEYS.tasks, JSON.stringify(state.tasks));
localStorage.setItem(STORAGE_KEYS.count, state.pomodoroCount.toString());
localStorage.setItem(STORAGE_KEYS.settings, JSON.stringify(state.settings));
}
三个独立的 storage key 分别存储任务列表、番茄计数和设置,便于部分更新和调试。
八、使用场景
九、总结
Pomo-Board 是一个功能完备的轻量级番茄钟 + 任务看板工具,它将番茄工作法的核心理念与任务管理完美结合。
其技术实现值得学习:
- 零框架依赖:纯原生 HTML/CSS/JS 实现,无需构建步骤
- requestAnimationFrame 计时:高精度、低资源消耗的动画循环
- CSS conic-gradient 进度环:纯 CSS 实现精美的圆形进度动画
- Web Audio API 通知:浏览器端合成音效,无需外部资源
- localStorage 持久化:零后端数据保存,刷新不丢失
- CSS 自定义属性主题:亮色/暗色模式一键切换
- 响应式布局:完美适配手机、平板、桌面各种屏幕
如果你正在寻找一个简单好用的番茄钟工具,不妨试试 Pomo-Board!
本文由 Pomo-Board 团队出品,更多信息请访问 Toolion.cn





