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

ReactJS开发中如何在SVG圆形内部渲染N个均等扇形切片

问题原因

你当前遇到的问题核心是圆形和扇形切片使用的坐标体系不匹配:

  • 扇形切片是基于「单位圆」逻辑生成的:圆心在坐标原点(0,0),半径为1,坐标取值范围在-1到1之间
  • 你写的circle标签用的是像素坐标:圆心在(150,150),半径148,是为306x306的无viewBox画布设计的
  • viewBox="-1 -1 2 2"的作用是把SVG画布的可视区域映射为x从-1到1、y从-1到1的范围,刚好匹配你的切片坐标,但完全不匹配你写的circle的像素坐标,所以两者不能同时显示。

解决方案1(推荐,改动最小)

保留现有的viewBox属性,仅修改circle标签的参数适配单位圆坐标系即可:

<div className="container">
  <svg
    height="306"
    width="306"
    viewBox="-1 -1 2 2"
  >
    <circle cx="0" cy="0" r="1" stroke="black"
      strokeWidth="0.02" fill={"transparent"}/>
    {this.renderSlices()}
  </svg>
</div>

说明:
单位圆的圆心就是(0,0),半径1和切片的半径完全对齐,描边宽度按单位坐标系缩小即可,你可以调整strokeWidth数值到你需要的粗细。


解决方案2(移除viewBox的方案)

如果不想用viewBox,就修改切片的生成逻辑,把单位坐标映射为306x306画布的像素坐标:
首先修改getCoordinatesForPercent方法:

getCoordinatesForPercent(percent: string) {
  const radius = 150; // 和circle的半径保持一致
  const centerX = 153; // 306宽度的一半
  const centerY = 153; // 306高度的一半
  const x = Math.cos(2 * Math.PI * parseFloat(percent)) * radius + centerX;
  const y = Math.sin(2 * Math.PI * parseFloat(percent)) * radius + centerY;
  return [x, y];
}

然后渲染部分移除viewBox,用适配像素坐标的circle标签即可:

<div className="container">
  <svg
    height="306"
    width="306"
  >
    <circle cx="153" cy="153" r="150" stroke="black"
      strokeWidth="2" fill={"transparent"}/>
    {this.renderSlices()}
  </svg>
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:36:03