前端如何实现图中红框里的形状?

前端如何实现图中红框里的形状
image.png

阅读 1.9k
2 个回答

<html>
<head>
</head>
<body>
    <div class="test" style="
    --percent: 46%;
    width: 100px;
    height: 100px;
    background-color: #000;
    -webkit-mask-image: radial-gradient(circle at 150%, transparent 50%, black 51%, black 69%, transparent 70%);
    background-image: linear-gradient(to top, #39F 0%, #39F var(--percent), transparent var(--percent));
">
</div>
</body></html>

SVG应该可以 只是得研究下怎么绘制。之前做过类似的
感觉可以折中一下,绘制成圆环

image.png

通过代码方式控制图形绘制

import React from "react";

interface SectorProps {
  outerRadius: number;
  innerRadius: number;
  startAngle: number;
  sweepAngle: number;
  fillColor?: string;
  gradientColors?: string[];
  strokeColor?: string;
  strokeWidth?: number;
  opacity?: number;
}

const Sector: React.FC<SectorProps> = ({
                                         outerRadius,
                                         innerRadius,
                                         startAngle,
                                         sweepAngle,
                                         fillColor = "blue",
                                         gradientColors,
                                         strokeColor = "black",
                                         strokeWidth = 2,
                                         opacity = 1.0,
                                       }) => {
  const center = outerRadius;
  const gradientId = `gradient-${Math.random().toString(36).substr(2, 9)}`;

  const polarToCartesian = (radius: number, angle: number) => {
    const radians = ((angle - 90) * Math.PI) / 180;
    return {
      x: center + radius * Math.cos(radians),
      y: center + radius * Math.sin(radians),
    };
  };

  const outerStart = polarToCartesian(outerRadius, startAngle);
  const outerEnd = polarToCartesian(outerRadius, startAngle + sweepAngle);
  const innerStart = polarToCartesian(innerRadius, startAngle + sweepAngle);
  const innerEnd = polarToCartesian(innerRadius, startAngle);
  const largeArcFlag = sweepAngle > 180 ? 1 : 0;

  const pathData = `M ${outerStart.x} ${outerStart.y} A ${outerRadius} ${outerRadius} 0 ${largeArcFlag} 1 ${outerEnd.x} ${outerEnd.y} 
                    L ${innerStart.x} ${innerStart.y} A ${innerRadius} ${innerRadius} 0 ${largeArcFlag} 0 ${innerEnd.x} ${innerEnd.y} Z`;

  return (
    <svg width={outerRadius * 2} height={outerRadius * 2} viewBox={`0 0 ${outerRadius * 2} ${outerRadius * 2}`} opacity={opacity}>
      {gradientColors && gradientColors.length > 1 && (
        <defs>
          <linearGradient id={gradientId} gradientUnits="userSpaceOnUse" x1={outerStart.x} y1={outerStart.y} x2={outerEnd.x} y2={outerEnd.y}>
            {gradientColors.map((color, index) => (
              <stop key={index} offset={`${(index / (gradientColors.length - 1)) * 100}%`} stopColor={color} />
            ))}
          </linearGradient>
        </defs>
      )}
      <path d={pathData} fill={gradientColors && gradientColors.length > 1 ? `url(#${gradientId})` : fillColor} stroke={strokeColor} strokeWidth={strokeWidth} />
    </svg>
  );
};

export default Sector;
推荐问题