纯 JS + SVG 实现环形专注计时器:思路与踩坑记录

举报
yd_280401882 发表于 2026/11/01 06:18:49 2026/11/01
【摘要】 在日常工作和学习中,我常用番茄工作法来保持专注。市面上很多计时器组件要么依赖第三方库,要么样式难以定制,于是我动手用纯 JavaScript 加 SVG 实现了一个环形专注计时器,在这里把实现思路分享给大家。

在日常工作和学习中,我常用番茄工作法来保持专注。市面上很多计时器组件要么依赖第三方库,要么样式难以定制,于是我动手用纯 JavaScript 加 SVG 实现了一个环形专注计时器,在这里把实现思路分享给大家。

一、整体思路

计时器的核心是一个环形进度条:外层圆环表示剩余时间比例,中心显示倒计时数字。SVG 的 stroke-dasharray 与 stroke-dashoffset 属性天然适合做这类进度动画——圆环周长固定,随时间推进不断减小 dashoffset,就得到了"时间在流逝"的视觉效果。

二、关键实现

1. 计算周长:取半径 r,周长 C=2πr。把圆环的 stroke-dasharray 设为 C,初始 dashoffset 为 0。

2. 每秒更新:setInterval 每秒触发一次,剩余秒数减一,同时把 dashoffset 更新为 C*(1-剩余/总时长),中心文字同步刷新。

3. 平滑动画:给 stroke-dashoffset 加上 CSS transition,指针式的跳动就变成了连续的动画。

4. 主题切换:把颜色抽成 CSS 变量,切换主题时只需替换几个变量值,圆环、按钮、背景全部联动。

三、踩过的坑

- setInterval 在浏览器后台标签页会被节流,导致计时不准。解决办法是基于时间戳差值计算剩余时间,而不是单纯依赖计数器。

- SVG 圆环默认从 3 点钟方向开始,需要 rotate(-90deg) 才能从 12 点开始。

- 移动端 Safari 对 foreignObject 支持不佳,文字部分我最终改用 HTML 绝对定位叠加。

四、小结

这个计时器零依赖、单文件即可运行,也很适合作为前端新手理解 SVG 与动画的练手项目。后续我计划加上任务记录与统计功能,欢迎大家在评论区交流自己的专注管理方法。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。