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
相关产品推荐
相关产品推荐

