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

如何创建底部裁剪的圆形进度条?优先采用Material UI实现

底部裁剪圆形进度条的Material UI实现思路

方案一:基于CircularProgress二次封装

利用Material UI内置的CircularProgress组件,通过SVG遮罩精准裁剪底部区域,叠加背景和进度两层进度条实现效果:

import { CircularProgress, Box } from '@mui/material';

const ClippedCircularProgress = ({ value, size = 200, thickness = 4 }) => {
  return (
    <Box sx={{ position: 'relative', width: size, height: size }}>
      {/* 定义遮罩,保留顶部85%的圆形区域 */}
      <svg width={size} height={size} style={{ position: 'absolute' }}>
        <defs>
          <mask id="bottomClipMask">
            <rect width="100%" height="85%" fill="white" />
            <circle cx="50%" cy="50%" r={size / 2} fill="white" />
          </mask>
        </defs>
      </svg>

      {/* 灰色背景进度条 */}
      <CircularProgress
        variant="determinate"
        value={100}
        size={size}
        thickness={thickness}
        sx={{
          position: 'absolute',
          color: 'rgba(0, 0, 0, 0.12)',
          mask: 'url(#bottomClipMask)',
        }}
      />

      {/* 彩色实际进度条 */}
      <CircularProgress
        variant="determinate"
        value={value}
        size={size}
        thickness={thickness}
        sx={{
          position: 'absolute',
          mask: 'url(#bottomClipMask)',
        }}
      />
    </Box>
  );
};

// 使用示例
// <ClippedCircularProgress value={70} />

方案二:自定义SVG进度条

如果需要更灵活的样式控制,直接用SVG绘制圆弧并添加裁剪,完全自定义进度条形态:

import { Box } from '@mui/material';
import { useTheme } from '@mui/material/styles';

const CustomClippedProgress = ({ value = 0, size = 200, strokeWidth = 4 }) => {
  const theme = useTheme();
  const radius = (size - strokeWidth) / 2;
  const circumference = 2 * Math.PI * radius;
  const strokeOffset = circumference - (value / 100) * circumference;

  return (
    <Box sx={{ width: size, height: size }}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        <defs>
          {/* 裁剪路径:隐藏底部15%区域 */}
          <clipPath id="progressClip">
            <rect x="0" y="0" width={size} height={size * 0.85} />
          </clipPath>
        </defs>

        {/* 背景圆弧 */}
        <circle
          cx={size / 2}
          cy={size / 2}
          r={radius}
          fill="none"
          stroke={theme.palette.grey[300]}
          strokeWidth={strokeWidth}
          clipPath="url(#progressClip)"
        />

        {/* 进度圆弧 */}
        <circle
          cx={size / 2}
          cy={size / 2}
          r={radius}
          fill="none"
          stroke={theme.palette.primary.main}
          strokeWidth={strokeWidth}
          strokeDasharray={circumference}
          strokeDashoffset={strokeOffset}
          strokeLinecap="round"
          transform={`rotate(-90 ${size / 2} ${size / 2})`}
          clipPath="url(#progressClip)"
          style={{ transition: 'stroke-dashoffset 0.3s ease-in-out' }}
        />
      </svg>
    </Box>
  );
};

// 使用示例
// <CustomClippedProgress value={65} />

调整技巧

  • 裁剪范围:修改代码中85%或0.85的数值,数值越小,底部裁剪区域越大
  • 样式定制:通过stroke属性修改颜色,strokeWidth调整进度条粗细,strokeLinecap设置端点样式(圆角/直角)
  • 动画优化:自定义SVG方案中添加transition属性,让进度变化更平滑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:11:05