【问题标题】:How to draw a circle with n slices如何用n个切片画一个圆
【发布时间】:2019-12-14 19:35:20
【问题描述】:

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

【问题讨论】:

    标签: javascript reactjs react-native react-native-svg


    【解决方案1】:

    我已经努力为您找到解决方案

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

    基于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,如何在SVG的g标签中使用这段代码。这是 'M0 250 L125 34 C87 12 44 0 0 0 v250 z' 我的 12 片圆的路径。我需要制作 n 片(例如 2-15 片)。但我做不到!
    【解决方案2】:

    按照@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>
        )
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-24
      • 2021-02-11
      • 2021-05-21
      • 2012-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多