代码之家  ›  专栏  ›  技术社区  ›  Anand Rockzz

MUI圆形前进到半圆

  •  0
  • Anand Rockzz  · 技术社区  · 1 年前

    使用CircularProgress我可以获得

    enter image description here

    有没有一种简单的方法可以把它变成这样的半圆形?

    enter image description here

    2 回复  |  直到 1 年前
        1
  •  2
  •   Danziger    1 年前

    你可以,但你将无法使用 CircularProgressWithLabel 。您可以做的是:

    • 创建包装的自定义组件 CircularProgress
    • 缩小 value 道具来自 [0, 100] [0, 50]
    • 旋转 循环程序 -90deg (所以它是从左边开始的,而不是从上面开始的。
    • 自己盖上标签。

    它可能看起来像这样:

    import * as React from "react";
    import Box from "@mui/material/Box";
    import Typography from "@mui/material/Typography";
    import CircularProgress from "@mui/material/CircularProgress";
    
    function parse() { ... }
    
    export const function ArcProgress({
      size,
      value,
      ...props,
    }) {
      const [sizeValue, sizeUnit] = parse(size);
      const halfSize = `${ sizeValue / 2 }${ sizeUnit }`;
      const scaledValue = value / 2;
    
      return (
        <Box
          sx={{
            position: "relative",
            display: "inline-flex",
            width: size,
            height: halfSize,
            overflow: "hidden",
          }}>
    
          <Box
            sx={{
              position: "absolute",
              display: "inline-flex",
              top: 0,
              left: 0,
              transform: "rotate(-90deg)",
            }}>
            <CircularProgress
              { ...props }
              size={ size }
              value={ scaledValue } />
          </Box>
    
          <Typography
            variant="caption"
            sx={{
              position: "absolute",
              bottom: 0,
              left: 0,
              width: '100%',
              textAlign: 'center',
            }}>
            { value }%
          </Typography>
    
        </Box>
      );
    }
    
        2
  •  1
  •   Anand Rockzz    1 年前

    我最终做了以下事情。

    半循环程序.tsx

    import React from 'react'
    import './SemiCircularProgress.css'
    export interface SemiCircularProgressProps {
      value: number
    }
    const SemiCircularProgress = (props: SemiCircularProgressProps) => {
      return (
        <div role="semicircularprogressbar" style={{ ['--value' as any]: props.value }}>
          <span style={{ fontSize: 40, color: '#2b256b' }}>{props.value}%</span>
        </div>
      )
    }
    
    export default SemiCircularProgress
    

    半循环进程.css

    @keyframes semicircularprogress {
      0% {
        --percentage: 0;
      }
    
      100% {
        --percentage: var(--value);
      }
    }
    
    @property --percentage {
      syntax: '<number>';
      inherits: true;
      initial-value: 0;
    }
    
    [role="semicircularprogressbar"] {
      --percentage: var(--value);
      --primary: #ffffff;
      --secondary: #2b256b;
      --size: 300px;
      animation: semicircularprogress 2s 0.5s forwards;
      width: 100%;
      aspect-ratio: 2 / 1;
      border-radius: 50% / 100% 100% 0 0;
      position: relative;
      overflow: hidden;
      display: flex;
      align-items: flex-end;
      justify-content: center;
    }
    
    [role="semicircularprogressbar"]::before {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: conic-gradient(from 0.75turn at 50% 100%, var(--primary) calc(var(--percentage) * 1% / 2), var(--secondary) calc(var(--percentage) * 1% / 2 + 0.1%));
      mask: radial-gradient(at 50% 100%, white 55%, transparent 55.5%);
      mask-mode: alpha;
      -webkit-mask: radial-gradient(at 50% 100%, #0000 55%, #000 55.5%);
      -webkit-mask-mode: alpha;
    }
    
    [role="semicircularprogressbar"]::after {
      counter-reset: percentage var(--value);
      content: '';
      font-family: Helvetica, Arial, sans-serif;
      font-size: calc(var(--size) / 5);
      color: var(--primary);
    }
    

    像这样使用

    <SemiCircularProgress value={95} />