大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。
图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG
我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。
展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!
文章目录
摘要
专注变得越来越难,信息流轰炸、内心焦虑、注意力跳跃……本篇文章带你一步一步开发一个轻量的「微型专注计时器」,它融合了 Pomodoro 番茄时间法、白噪音播放、渐进式倒计时动画,还能自动进入“信息干扰隔离”状态。你只需点击开始,它就能为你屏蔽琐碎,开启片刻的清净。
引言
我们常常想“我就专注 25 分钟”,结果打开浏览器 3 秒钟,消息弹窗、社交诱惑、系统提醒就把我们拉走了。市面上的 Pomodoro 工具很多,但大多冗杂、不支持静音沉浸,白噪音也需要额外开播放器。
所以我们来做一个更符合「静下来就开始专注」需求的计时器。它小巧、离线、免安装,甚至可以当成你的浏览器启动页,随时点击就能用。
整体设计思路
核心功能列表
-
3 种专注模式切换:阅读 / 写作 / 放松
-
每种模式对应不同时间段(如 25min / 45min / 10min)
-
内置白噪音播放器(默认播放海浪声)
-
动态倒计时圆环动画(SVG 实现)
-
倒计时期间屏蔽系统通知、弹窗提醒(Web API + 最佳实践)
-
音效提示与震动提醒(可选)
技术选型
模块 | 技术 |
---|---|
前端框架 | Vue 3 + Composition API |
动画展示 | SVG + CSS 动态绑定 |
音频播放 | HTML5 <audio> + 白噪音资源 |
通知权限 | Notification API + Page Visibility |
离线能力 | PWA + Service Worker(可选) |
页面布局设计
页面结构草图
[ 模式选择(阅读 / 写作 / 放松) ]
[ 倒计时圆环动画 ]
[ 当前剩余时间 ]
[ 白噪音播放器控制(开/关) ]
[ 开始 / 暂停 / 重置按钮 ]
关键模块实现
模式与倒计时状态管理
// useFocusTimer.js
import { ref, computed } from 'vue'
export const modes = {
reading: { label: '阅读', duration: 25 * 60 },
writing: { label: '写作', duration: 45 * 60 },
relaxing: { label: '放松', duration: 10 * 60 }
}
export function useFocusTimer() {
const currentMode = ref('reading')
const timeLeft = ref(modes[currentMode.value].duration)
const isRunning = ref(false)
let timer = null
const start = () => {
if (!isRunning.value) {
isRunning.value = true
timer = setInterval(() => {
timeLeft.value--
if (timeLeft.value <= 0) {
clearInterval(timer)
isRunning.value = false
new Notification('专注时间结束', { body: '你可以稍作休息啦!' })
navigator.vibrate?.(500)
}
}, 1000)
}
}
const reset = () => {
clearInterval(timer)
timeLeft.value = modes[currentMode.value].duration
isRunning.value = false
}
return {
currentMode,
timeLeft,
isRunning,
start,
reset
}
}
动态倒计时圆环动画(SVG 实现)
<!-- FocusCircle.vue -->
<svg viewBox="0 0 100 100">
<circle class="bg" cx="50" cy="50" r="45" />
<circle class="progress"
:stroke-dasharray="strokeLength"
:stroke-dashoffset="offset"
cx="50" cy="50" r="45" />
</svg>
const percent = computed(() => timeLeft.value / totalDuration)
const offset = computed(() => 2 * Math.PI * 45 * (1 - percent.value))
circle.progress {
stroke: #4CAF50;
stroke-width: 6;
fill: none;
transform: rotate(-90deg);
transform-origin: center;
transition: stroke-dashoffset 1s linear;
}
白噪音播放器嵌入
<!-- BackgroundAudio.vue -->
<audio ref="player" loop :src="src" autoplay muted />
onMounted(() => {
const audio = player.value
audio.muted = false
audio.volume = 0.5
audio.play()
})
默认使用的白噪音可选择如下之一:
-
海浪声(waves.mp3)
-
雨声(rain.mp3)
-
咖啡店背景(cafe.mp3)
自动屏蔽干扰机制
// 在专注期间关闭通知权限提示
document.addEventListener('visibilitychange', () => {
if (document.hidden && isRunning.value) {
new Notification('回到专注页面', { body: '你正在计时中...' })
}
})
建议同时关闭系统层级通知,或通过系统设置关闭该标签页的提示权限,保持全屏专注体验。
使用场景说明
写论文时
-
选择“写作模式”,系统自动设置为 45 分钟专注时段
-
白噪音选择雨声,营造沉静氛围
-
动态圆环动画提示进度,防止你频繁看时间
短暂放松
-
吃完饭点“放松模式”
-
10分钟的海浪声 + 倒计时
-
结束后振动提醒你“该进入新一轮专注了”
QA 环节
Q:这个页面能离线使用吗?
可以,只要你部署时加上 PWA 支持或者直接打开本地文件也能运行,不依赖服务器。
Q:如何支持自动切换下一个 Pomodoro 时段?
可以用定时器链式回调逻辑,比如设定“25 分钟专注 → 5 分钟放松 → 再来一轮”,配合状态机实现切换。
Q:白噪音资源从哪里来?
可以用无版权音源(如 Mixkit、YouTube 音频库),放在本地或 CDN 上。
总结
通过这个小项目,我们把以下功能融合在一个轻巧页面里:
-
任务专注倒计时
-
不同场景切换
-
白噪音心理辅助
-
简洁动画反馈
-
自动屏蔽提醒机制
整个系统不到 300 行代码,却能有效帮我们构建一个「沉浸式专注环境」。