React-Native:如何绘制具有随机边数的形状(边数将是用户输入值)?

React-Native : How to draw shapes with random number of sides ( number of sides will be a user input value)?

如果用户输入数字4,生成的形状将变成正方形。如果用户输入 9 形状将变成 nonagon。 这应该是一个本机反应解决方案:) 有什么想法吗?

代码应为 self-explanatory。您定位圆上的点,并在 svg 多边形的帮助下用线连接它们。

Snack

import React, { useState, useEffect } from 'react';
import { View, StyleSheet, Dimensions, Text, TextInput } from 'react-native';
import Svg, { Polygon } from 'react-native-svg';
import Constants from 'expo-constants';

export default function App() {
  const windowWidth = Dimensions.get('window').width;
  const Center = windowWidth / 2;
  const Radius = Center - 20;

  const [numSides, setNumSides] = useState(3);
  const [polygonPoints, setPolygonPoints] = useState();

  useEffect(() => {
    let newPolyPoints = '';
    const angle = 2 * Math.PI / numSides;
    for (let side = 0; side < numSides; side++) {
      const x = Math.cos(angle * side) * Radius + Center;
      const y = Math.sin(angle * side) * Radius + Center;
      newPolyPoints = `${newPolyPoints} ${x},${y}`;
    }
    setPolygonPoints(newPolyPoints);
  }, [numSides]);

  const inputIsValid = t => {
    const int = parseInt(t, 10);
    return isNaN(int) === false && int >= 3;
  }

  return (
    <View style={styles.container}>
      <View style={styles.inputContainer}>
        <Text style={styles.label}>
          {'Number of sides: '}
        </Text>
        <TextInput
          style={styles.textInput}
          defaultValue={numSides.toString()}
          selectTextOnFocus
          onChangeText={t => {
            if (inputIsValid(t)) {
              const int = parseInt(t, 10);
              setNumSides(int);
            }
          }}
        />
      </View>
      <Svg style={styles.svg} width={windowWidth} height={windowWidth}>
        <Polygon
          points={polygonPoints}
          fill="lime"
          stroke="purple"
          strokeWidth="1"
        />
      </Svg>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  inputContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    marginVertical: 20,
    marginHorizontal: 12,
  },
  label: {
    fontSize: 18,
  },
  textInput: {
    backgroundColor: 'white',
    flex: 1,
    fontSize: 18,
  },
  svg: {
    aspectRatio: 1,
    backgroundColor: 'tomato',
  },
});