欢迎光临
我们一直在努力

极简番茄钟 + 任务看板:纯前端 Pomodoro 工具深度解析

极简番茄钟 + 任务看板:纯前端 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 分别存储任务列表、番茄计数和设置,便于部分更新和调试。


八、使用场景

  • 深度工作:开启番茄钟,添加待办任务,专注完成代码编写
  • 学习备考:设置 45/10 模式,搭配学习任务列表
  • 日常规划:将每日待办事项添加到任务看板,完成即打勾
  • 团队协作:无需登录,打开即用,适合快速共享使用
  • 效率追踪:每日番茄计数记录,追踪自己的专注时长

  • 九、总结

    Pomo-Board 是一个功能完备的轻量级番茄钟 + 任务看板工具,它将番茄工作法的核心理念与任务管理完美结合。

    其技术实现值得学习:

    • 零框架依赖:纯原生 HTML/CSS/JS 实现,无需构建步骤
    • requestAnimationFrame 计时:高精度、低资源消耗的动画循环
    • CSS conic-gradient 进度环:纯 CSS 实现精美的圆形进度动画
    • Web Audio API 通知:浏览器端合成音效,无需外部资源
    • localStorage 持久化:零后端数据保存,刷新不丢失
    • CSS 自定义属性主题:亮色/暗色模式一键切换
    • 响应式布局:完美适配手机、平板、桌面各种屏幕

    如果你正在寻找一个简单好用的番茄钟工具,不妨试试 Pomo-Board!


    本文由 Pomo-Board 团队出品,更多信息请访问 Toolion.cn

    赞(0)
    未经允许不得转载:171主机测评 » 极简番茄钟 + 任务看板:纯前端 Pomodoro 工具深度解析
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址