线上代码地址
<div class="circular-progress-bar">
<svg>
<circle class="circle-bg" />
<circle class="circle-progress" style="stroke-dasharray: calc(2 * 3.1415 * var(--r) * (var(--percent) / 100)), 1000" />
</svg>
</div>
<br />
<br />
<p>
<label>进度</label>
<input type="range" min="0" max="100" value="0" oninput="changeConfig(this, '--percent')" />
</p>
<p>
<label>环形大小</label>
<input type="range" min="100" max="400" value="200" oninput="changeConfig(this, '--size', 'px')" />
</p>
<p>
<label>进度条宽度</label>
<input type="range" min="1" max="50" value="10" oninput="changeConfig(this, '--progress-border', 'px')" />
</p>
<p>
<label>进度条颜色</label>
<input type="color" value="#ff0000" oninput="changeConfig(this, '--progress-color')" />
</p>
<p>
<label>背景色</label>
<input type="color" value="#cccccc" oninput="changeConfig(this, '--bg-color')" />
<button onclick="changeDemo({ value: 'transparent' }, '--bg-color')">透明</button>
</p>
.circular-progress-bar {
--size: 200px; /* 环形大小 */
--percent: 0; /* 进度 */
--progress-border: 10px; /* 进度条宽度:要带单位,不然计算半径的时候有问题,要和 --size 统一 */
--progress-color: red; /* 进度条颜色 */
--bg-color: green; /* 不是进度条的颜色 */
position: relative;
width: var(--size);
height: var(--size);
border-radius: 50%;
}
.circular-progress-bar::before {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
counter-reset: progress var(--percent);/* 用于重置计数器的初始值,并且命名为progress */
content: counter(progress) "%";
white-space: nowrap;
font-size: 18px;
}
.circular-progress-bar svg {
width: 100%;
height: 100%;
}
.circular-progress-bar svg circle {
--r: calc((var(--size) - var(--progress-border)) / 2);
fill: none;
stroke-width: var(--progress-border);
stroke-linecap: round;
stroke: var(--progress-color);
transition: stroke-dasharray 0.3 linear;
cx: calc(var(--size) / 2);
cy: calc(var(--size) / 2);
r: var(--r);
}
.circular-progress-bar svg .circle-bg {
stroke: var(--bg-color);
}
.circular-progress-bar svg .circle-progress {
opacity: var(--percent); /* 进度:0 的时候不需要显示 */
}
const progressEl = document.querySelector('.circular-progress-bar');
function changeConfig({ value }, property, unit = '') {
progressEl.style.setProperty(property, value + unit);
}