You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:基于CSS和JS实现倒计时填充式圆形进度条的问题

解决倒计时填充圆形的问题

首先咱们先理清楚核心需求:随着倒计时推进,圆形从0%逐步填充到100%——比如10秒倒计时,剩余5秒时刚好填充一半,结束时完全填满。你现在遇到的初始全填充、圆形转动这两个问题,咱们一步步来搞定。

问题根源分析

  1. 初始全填充:大概率是填充逻辑的初始值搞反了——比如误把初始填充比例设成了100%,或者旋转角度的计算逻辑出错
  2. 圆形转动:应该是transform-origin没设置到圆心位置,或者动画错误地旋转了整个容器,而非只调整填充范围

推荐实现方案(CSS + JS)

我推荐用**锥形渐变(conic-gradient)**来做填充,配合JS动态计算填充比例,这种方式简单直观,完全不会出现转动问题。

1. HTML结构

先搭个基础结构,一个容器包裹填充层和倒计时文本:

<div class="countdown-circle">
  <div class="fill-circle"></div>
  <div class="countdown-text">10</div>
</div>

2. CSS样式

设置圆形的基础样式,重点是把transform-origin固定在圆心,用锥形渐变实现填充效果,初始状态隐藏全部填充:

.countdown-circle {
  position: relative;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: #eee; /* 灰色背景圆环 */
}

.fill-circle {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  /* 让锥形渐变的起点从顶部开始,初始填充比例为0 */
  transform: rotate(-90deg);
  transform-origin: center;
  background: conic-gradient(#4285f4 0%, transparent 0%);
  clip-path: circle(50% at center); /* 裁剪成圆形,避免渐变超出范围 */
}

.countdown-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 32px;
  font-weight: bold;
}

3. JS逻辑

核心是计算已过时间占总倒计时的比例,然后动态调整锥形渐变的填充范围:

// 配置参数
const totalSeconds = 10; // 总倒计时秒数
let remainingSeconds = totalSeconds;

const fillCircle = document.querySelector('.fill-circle');
const countdownText = document.querySelector('.countdown-text');

// 初始化显示
updateCircle();
countdownText.textContent = remainingSeconds;

// 启动倒计时
const interval = setInterval(() => {
  remainingSeconds--;
  updateCircle();
  countdownText.textContent = remainingSeconds;

  if (remainingSeconds <= 0) {
    clearInterval(interval);
    countdownText.textContent = 'Done!'; // 倒计时结束提示
  }
}, 1000);

// 更新圆形填充状态
function updateCircle() {
  // 计算已过时间的比例:(总时间-剩余时间)/总时间
  const filledRatio = (totalSeconds - remainingSeconds) / totalSeconds;
  const filledPercent = filledRatio * 100;
  // 修改锥形渐变的填充范围
  fillCircle.style.background = `conic-gradient(#4285f4 ${filledPercent}%, transparent ${filledPercent}%)`;
}

为什么这个方案能解决你的问题?

  • 初始状态正确:初始时filledRatio为0,渐变填充比例是0%,圆形完全显示背景灰色
  • 不会转动:我们只修改渐变的填充百分比,没有旋转整个fill-circle元素,transform-origin只是确保渐变起点在顶部,不会导致元素转动
  • 填充逻辑准确:已过时间占总时间的比例就是填充比例,10秒倒计时到第5秒时,filledRatio是0.5,刚好填充50%(半个圆)

如果你之前用的是SVG方案

如果之前是用SVG的<circle>和<path>做填充,问题可能出在stroke-dasharray和stroke-dashoffset的计算上——比如初始stroke-dashoffset设成了0(导致全填充),或者动画错误添加了旋转属性。可以参考上面的比例逻辑,动态调整stroke-dashoffset的值,确保初始时隐藏全部填充。

内容的提问来源于stack exchange,提问作者karen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:41:52