《晚霞专注钟》:一个单文件网页番茄钟的设计与实现
番茄钟工具多如牛毛,但大多数都在「催」人:红色的倒计时、刺耳的提示音、超时未完成的负罪感。我想反着来——做一个不催人的专注计时器:整个页面是一片黄昏,计时开始后,一轮太阳随着进度缓缓下沉;时间走完,太阳正好沉到地平线附近,抬头就是晚霞。这个小作品叫《晚霞专注钟》,已经发布在华为云开发者作品展览馆,源码开源在 GitHub(sangtiandetian/dusk-focus-clock),全文只有一个 HTML 文件,无框架、无图片资源、无构建步骤,浏览器打开就能用。
一、设计:一片 CSS 画出来的黄昏
页面背景是一条五段的线性渐变,从深紫到橙红,模拟黄昏时天空的层次:
background: linear-gradient(180deg, #2b1055 0%, #7597de 30%, #ff9a76 62%, #ff6b6b 82%, #845ec2 100%);
太阳是一个 150px 的 div,圆形、径向渐变,再加一层大范围的 box-shadow 做光晕:
.sun {
width: 150px; height: 150px; border-radius: 50%;
background: radial-gradient(circle, #ffd93d 0%, #ff9a3d 70%, #ff7b3d 100%);
box-shadow: 0 0 80px 30px rgba(255, 170, 60, .45);
}
不引用任何图片,整个「场景」就是渐变加几何图形,文件小、加载快,也天然适配任何屏幕。
二、核心机制:让太阳跟着进度下沉
关键只有一行进度计算:p = 1 - left / total,其中 left 是剩余秒数、total 是本轮总秒数。每秒 tick 时,把 p 映射为太阳的位移和缩放:
function render() {
clock.textContent = fmt(left);
var p = 1 - left / total;
sun.style.transform = 'translateY(' + (p * 46) + 'px) scale(' + (1 - p * 0.12) + ')';
}
太阳最多下沉 46px、同时缩小到 88%,配合 CSS 里给 .sun 设置的 transition: transform 1s ease,每一秒的移动都是平滑滑动而不是跳格。这样时间进度就变成了一个不用读数字也能感知的视觉信号:瞥一眼太阳的高度,就知道这一轮走到哪了。
三、时长档位与完成计数
页面提供三档:专注 25 分钟、专注 15 分钟、休息 5 分钟,按钮上用 data-min 存分钟数,点击时切换 total 并重置状态,不用为每档写一份逻辑。
完成次数按天统计,用 localStorage 存,键名里直接拼上日期字符串:
var KEY = 'dusk-focus-' + new Date().toDateString();
done = parseInt(localStorage.getItem(KEY) || '0', 10);
跨天之后键名自动变化,计数天然清零,不需要写任何「每日重置」的定时逻辑。另外有个小规则:只有 15 分钟以上的专注轮次才计次,5 分钟休息走完不计数,避免把休息也刷成「成果」。
四、两个实现细节
一是数字不跳动:倒计时用 font-variant-numeric: tabular-nums,让每一位数字等宽,25:00 变成 24:59 时整串文字不会左右抖动。
二是先承认 setInterval 的漂移:setInterval(fn, 1000) 在页面切到后台时会被浏览器节流,长时间计时会有误差。这个小工具单轮最长 25 分钟、且切后台通常意味着人已经离开,我接受了这个误差;如果要做严谨的计时,应该改成记录结束时间戳、每 tick 用 Date.now() 反推剩余时间,漂移就不存在了——这也是下一版准备改的点。
五、小结
《晚霞专注钟》的全部逻辑不到一百行 JavaScript,它想验证的事情很简单:计时器不一定要用进度条和百分比,把进度翻译成一个自然现象——日落——专注的过程就安静下来了。作品已发布在华为云开发者作品展览馆(作品名:《晚霞专注钟》),源码在 GitHub 仓库 sangtiandetian/dusk-focus-clock,欢迎试用和提 Issue。
- 点赞
- 收藏
- 关注作者
评论(0)