如何用n片画一个圆

How to draw a circle with n slices

我正在使用 react-native-svg 模块,我想绘制一个分成 n 片的圆。 我的圆半径是 41,圆心是 (50, 50) 例如对于 n=6 我想画这样的东西:

我努力为您找到解决方案

但我一路上学到了很多东西

基于this article

import Svg, {Path} from 'react-native-svg';

import React from 'react';
import {View, StyleSheet} from 'react-native';

export default class SvgExample extends React.Component {
  slice() {
    let slices = [];

  //option 1  Equal size pieces
    slices.push({percent: 0.25, color: 'blue'});
    slices.push({percent: 0.10, color: 'red'});
    slices.push({percent: 0.28, color: 'green'});
    slices.push({percent: 0.19, color: 'yellow'});


    //option 2  Different size pieces
    // const numberOfSlice = 6; //number for slice

    // const colorArr = ['red', 'green', 'yellow', 'blue']; //color the slice
    // for (let i = 0; i < numberOfSlice; i++) {
    //   slices.push({percent: 1 / numberOfSlice, color: colorArr[i] || 'gray'});
    // }

    let cumulativePercent = 0;

    function getCoordinatesForPercent(percent) {
      const x = Math.cos(2 * Math.PI * percent);
      const y = Math.sin(2 * Math.PI * percent);
      return [x, y];
    }

    let arr = [];
    arr = slices.map(slice => {
      const [startX, startY] = getCoordinatesForPercent(cumulativePercent);
      cumulativePercent += slice.percent;
      const [endX, endY] = getCoordinatesForPercent(cumulativePercent);
      const largeArcFlag = slice.percent > 0.5 ? 1 : 0;
      const pathData = [
        `M ${startX} ${startY}`, // Move
        `A 1 1 0 ${largeArcFlag} 1 ${endX} ${endY}`, // Arc
        'L 0 0', // Line
      ].join(' ');
      return <Path d={pathData} fill={slice.color} key={pathData} />;
    });
    return arr;
  }

  render() {
    return (
      <View
        style={[
          StyleSheet.absoluteFill,
          {alignItems: 'center', justifyContent: 'center'},
        ]}>
        <Svg
          height="100"
          width="100"
          viewBox="-1 -1 2 2"
          style={{transform: [{rotate: '-90deg'}]}}>
          {this.slice()}
        </Svg>
      </View>
    );
  }
}

expo codesandbox

根据 @Yoel 回答,功能性 React-Native 的更多更新版本。

import React from "react";
import { Path, Svg } from "react-native-svg";
import {View} from "react-native";

export type PieCircleProps = {
    slices: Slice[];
}

export type Slice = {
    percentage: number;
    color: string;
}

export const PieCircle: React.FunctionComponent<PieCircleProps> = (
    {
        slices
    }
) => {
    let totalPercentage = 0;
    
    const getCoordinatesForPercent = () => {
        const x = Math.cos(2 * Math.PI * totalPercentage);
        const y = Math.sin(2 * Math.PI * totalPercentage);
        return [x, y];
    }
    
    const _renderSlice = (
        {
            percentage,
            color
        }: Slice
    ) => {
        const [startX, startY] = getCoordinatesForPercent();
        totalPercentage += percentage;
        const [endX, endY] = getCoordinatesForPercent();
        
        const largeArcFlag = percentage > 0.5 ? 1 : 0;
        const pathData = [
            `M ${startX} ${startY}`, // Move
            `A 1 1 0 ${largeArcFlag} 1 ${endX} ${endY}`, // Arc
            'L 0 0', // Line
        ].join(' ');
        
        return <Path
            d={pathData}
            fill={color}
            key={pathData}
        />;
    }
    
    return (
        <View
            style={[
                {alignItems: 'center', justifyContent: 'center'},
            ]}>
            <Svg
                height="100"
                width="100"
                viewBox="-1 -1 2 2"
                style={{transform: [{rotate: '-90deg'}]}}
            >
                {
                    slices.map(slice => _renderSlice(slice))
                }
            </Svg>
        </View>
    )
}