如何构建带进度与轨道间隙的React圆形进度条
React 实现带间隙的圆形进度条组件
要实现进度段与轨道段之间的间隙效果,核心是利用SVG的stroke-dasharray和stroke-dashoffset属性,让轨道和进度圆环的间隙位置完全对齐。以下是具体实现方案:
核心思路
- 用两个SVG
<circle>元素分别实现轨道和进度条:- 轨道圆环通过
stroke-dasharray定义线段与间隙的长度,形成带间隙的环形轨道。 - 进度圆环使用相同的
stroke-dasharray,通过stroke-dashoffset控制显示的进度长度,确保进度段与轨道的间隙完美对齐。
- 轨道圆环通过
- 通过
rotate(-90deg)让进度从顶部开始,符合常规视觉习惯;用strokeLinecap="round"让进度段两端呈现圆角,匹配设计风格。
完整组件代码
import React from 'react'; const CircularProgressBar = ({ percentage, radius = 80, strokeWidth = 12, segments = 12, gapRatio = 0.2 }) => { const circumference = 2 * Math.PI * radius; // 计算单段间隙的弧长(按占单段总角度的比例) const segmentTotalAngle = 360 / segments; const gapAngle = segmentTotalAngle * gapRatio; const segmentAngle = segmentTotalAngle - gapAngle; const segmentLength = (segmentAngle / 360) * circumference; const gapLength = (gapAngle / 360) * circumference; // 计算进度的总显示长度(扣除所有间隙后的有效周长 × 百分比) const progressTotalLength = (circumference - segments * gapLength) * (percentage / 100); return ( <svg width={radius * 2} height={radius * 2} viewBox={`0 0 ${radius * 2} ${radius * 2}`} > {/* 带间隙的轨道圆环 */} <circle cx={radius} cy={radius} r={radius - strokeWidth / 2} fill="none" stroke="#e0e0e0" strokeWidth={strokeWidth} strokeDasharray={`${segmentLength} ${gapLength}`} strokeLinecap="round" /> {/* 进度圆环 */} <circle cx={radius} cy={radius} r={radius - strokeWidth / 2} fill="none" stroke="#2196F3" strokeWidth={strokeWidth} strokeDasharray={`${segmentLength} ${gapLength}`} strokeDashoffset={circumference - progressTotalLength} strokeLinecap="round" transform={`rotate(-90 ${radius} ${radius})`} style={{ transition: 'stroke-dashoffset 0.3s ease-in-out' }} /> {/* 中间百分比文本 */} <text x={radius} y={radius} textAnchor="middle" dominantBaseline="middle" fontSize={radius / 3} fontWeight="bold" > {`${Math.round(percentage)}%`} </text> </svg> ); }; export default CircularProgressBar;
参数说明与自定义调整
percentage:必填,进度百分比(0-100)。radius:可选,圆形进度条的半径,默认80。strokeWidth:可选,圆环的线条宽度,默认12。segments:可选,轨道/进度的分段数量,默认12,数值越大间隙越密集。gapRatio:可选,间隙占单段总角度的比例(0-1),默认0.2,数值越大间隙越宽。
使用示例
// 在项目中引入并使用 <CircularProgressBar percentage={65} radius={100} strokeWidth={15} segments={16} gapRatio={0.15} />
关键细节解释
- stroke-dasharray:轨道和进度圆环共用相同的线段/间隙长度配置,确保两者的间隙位置完全对应。
- stroke-dashoffset:通过计算
circumference - progressTotalLength,让进度从顶部开始逐步显示,百分比越高,偏移值越小,进度越长。 - 过渡动画:给进度圆环添加
transition属性,实现进度变化时的平滑动画效果。
内容的提问来源于stack exchange,提问作者Ümit Aparı
相关产品推荐
相关产品推荐

