Ant Design 圆形进度条

<div class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"><div class="ant-progress-inner" style="width: 120px; height: 120px; font-size: 24px;"><svg class="ant-progress-circle " viewBox="0 0 100 100"><path class="ant-progress-circle-trail" d="M 50,50 m 0,-47a 47,47 0 1 1 0,94a 47,47 0 1 1 0,-94" stroke-linecap="round" stroke-width="6" fill-opacity="0" style="stroke-dasharray: 295.31px, 295.31px; stroke-dashoffset: 0px; transition: stroke-dashoffset 0.3s ease 0s, stroke-dasharray 0.3s ease 0s, stroke 0.3s ease 0s, stroke-width 0.06s ease 0.3s;"></path><path class="ant-progress-circle-path" d="M 50,50 m 0,-47a 47,47 0 1 1 0,94a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="6" opacity="1" fill-opacity="0" style="stroke-dasharray: 221.482px, 295.31px; stroke-dashoffset: 0px; transition: stroke-dashoffset 0.3s ease 0s, stroke-dasharray 0.3s ease 0s, stroke 0.3s ease 0s, stroke-width 0.06s ease 0.3s;"></path></svg><span class="ant-progress-text" title="75%">75%</span></div></div>
.ant-progress-inner {position: relative;display: inline-block;width: 100%;overflow: hidden;vertical-align: middle;background-color: #f5f5f5;border-radius: 100px;}.ant-progress-circle .ant-progress-inner {position: relative;line-height: 1;background-color: transparent;}.ant-progress-circle-trail {stroke: #f5f5f5;}.ant-progress-inner:not(.ant-progress-circle-gradient) .ant-progress-circle-path {stroke: #1890ff;}.ant-progress-text {display: inline-block;width: 2em;margin-left: 8px;color: rgba(0,0,0,.45);font-size: 1em;line-height: 1;white-space: nowrap;text-align: left;vertical-align: middle;word-break: normal;}.ant-progress-circle .ant-progress-text {position: absolute;top: 50%;left: 50%;width: 100%;margin: 0;padding: 0;color: rgba(0,0,0,.65);font-size: 1em;line-height: 1;white-space: normal;text-align: center;-webkit-transform: translate(-50%,-50%);transform: translate(-50%,-50%);}
SVG path 圆弧(A)指令
M = moveto L = lineto H = horizontal lineto V = vertical lineto C = curveto S = smooth curveto Q = quadratic Bézier curve T = smooth quadratic Bézier curveto A = elliptical Arc Z = closepath
以上所有命令均允许小写字母。大写表示绝对定位,小写表示相对定位。

- rx, ry 起始点
- x1, y1 终点
- rotation 椭圆的旋转角度
- large-arc-flag 指定采用椭圆上大的那部分圆弧(1)还是小的那部分(0)
- sweep-flag 指定采用顺时针的椭圆路径(1)还是逆时针的(0),如图中右边的(1)和左边的椭圆(0)
上面的 SVG 代码中 a 47,47 0 1 1 0,94 和 a 47,47 0 1 1 0,-94 表示顺时针画了2个半圆。
stroke-dasharray
是一个
和 数列,数与数之间用逗号或者空白隔开,指定短划线和缺口的长度。如果提供了奇数个值,则这个值的数列重复一次,从而变成偶数个值。因此,5,3,2 等同于 5,3,2,5,3,2。
stroke-dashoffset 表示向左偏移的距离,常与 stroke-dasharray 一起使用,实现一些好看的动画效果。
例如上面的代码中,
- 第一个 path 设置的
stroke-dasharray: 295.31px, 295.31px; stroke-dashoffset: 0px;,其中 295.31px 是圆周长,这句代码实际上是画了个圆; - 第二个 path 设置的
stroke-dasharray: 221.482px, 295.31px; stroke-dashoffset: 0px; transition: stroke-dashoffset 0.3s ease 0s, stroke-dasharray 0.3s ease 0s, stroke 0.3s ease 0s, stroke-width 0.06s ease 0.3s;,221.482px 是 75% 的进度条弧长,这句代码是在画带动效的进度条。
动态计算 style 代码
function getPathStyles(offset, percent, strokeColor, strokeWidth, gapDegree = 0, gapPosition) {const radius = 50 - strokeWidth / 2;let beginPositionX = 0;let beginPositionY = -radius;let endPositionX = 0;let endPositionY = -2 * radius;switch (gapPosition) {case 'left':beginPositionX = -radius;beginPositionY = 0;endPositionX = 2 * radius;endPositionY = 0;break;case 'right':beginPositionX = radius;beginPositionY = 0;endPositionX = -2 * radius;endPositionY = 0;break;case 'bottom':beginPositionY = radius;endPositionY = 2 * radius;break;default:}const pathString = `M 50,50 m ${beginPositionX},${beginPositionY}a ${radius},${radius} 0 1 1 ${endPositionX},${-endPositionY}a ${radius},${radius} 0 1 1 ${-endPositionX},${endPositionY}`;const len = Math.PI * 2 * radius;const pathStyle = {stroke: strokeColor,strokeDasharray: `${(percent / 100) * (len - gapDegree)}px ${len}px`,strokeDashoffset: `-${gapDegree / 2 + (offset / 100) * (len - gapDegree)}px`,transition:'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s', // eslint-disable-line};return {pathString,pathStyle,};}
