Реагировать на собственный трансформированный значок преобразования в зависимости от типа вращения - PullRequest
0 голосов
/ 18 апреля 2020

Это то, что я могу sh Я мог бы сделать:

enter image description here

Это то, что делает код ниже, я хотел бы сделать это в соответствии с углом степени: 90, 180, 210 значок перемещается по этой градации приятного внешнего круга.

Я пытался вот так: stackoverflow но я хотел бы сделать это без анимации.

Можете ли вы дать мне руку, какой-нибудь совет?

Ссылка: закуска

редактировать: закуска

код:

import React, { useState } from 'react';
import { StyleSheet, View, Animated, Text } from 'react-native';
import Svg, { Circle, G } from 'react-native-svg';
const AnimatedCircle = Animated.createAnimatedComponent(Circle);

export default ({
  image,
  width,
  height,
  innerCircle = false,
  innerCircleRadius = 13,
  innerCircleFillPercentage = 25,
  innerCircleStroke = '#143c5b',
  innerCircleStrokeAnimated = '#02ac8a',
  outerCircle = false,
  outerCircleRadius = 18,
  outerCircleFillPercentage = 50,
  outerCircleStroke = '#1f4a42',
  outerCircleStrokeAnimated = '#028cfe',
  degree,
}) => {
  const innerCirclePerimeter = 2 * Math.PI * innerCircleRadius;
  const innerCircleStrokeDashOffset =
    innerCirclePerimeter -
    (innerCirclePerimeter * innerCircleFillPercentage) / 100;

  const outerCirclePerimeter = 2 * Math.PI * outerCircleRadius;
  const outerCircleStrokeDashOffset =
    outerCirclePerimeter -
    (outerCirclePerimeter * outerCircleFillPercentage) / 100;

  const [springValue] = useState(new Animated.Value(1.3));

  const [innerCircleInitialFill] = useState(
    new Animated.Value(innerCirclePerimeter)
  );
  const [outerCircleInitialFill] = useState(
    new Animated.Value(outerCirclePerimeter)
  );

  React.useEffect(() => {
    Animated.parallel([
      Animated.timing(innerCircleInitialFill, {
        toValue: innerCircleStrokeDashOffset,
        duration: 1000,
      }),
      Animated.timing(outerCircleInitialFill, {
        toValue: outerCircleStrokeDashOffset,
        duration: 2000,
      }),
      Animated.spring(springValue, {
        toValue: 1,
        friction: 1,
      }),
    ]).start();
  }, [
    innerCircleInitialFill,
    outerCircleInitialFill,
    springValue,
    innerCircleStrokeDashOffset,
    outerCircleStrokeDashOffset,
  ]);

  const outer = () => {
    return (
      outerCircle && (
        <>
          <Circle
            cx="25"
            cy="25"
            r={outerCircleRadius}
            fill="transparent"
            stroke={outerCircleStroke}
            strokeDasharray="10, 1"
            strokeDashoffset="30"
            strokeWidth={0.5}
          />
          <AnimatedCircle
            cx="25"
            cy="25"
            r={outerCircleRadius}
            fill="transparent"
            stroke={innerCircleStrokeAnimated}
            strokeDasharray={outerCirclePerimeter}
            strokeDashoffset={outerCircleInitialFill}
            strokeLinecap={'round'}
          />
        </>
      )
    );
  };

  const inner = () => {
    return (
      innerCircle && (
        <>
          <Circle
            cx="25"
            cy="25"
            r={innerCircleRadius}
            fill="transparent"
            stroke={innerCircleStroke}
            strokeDasharray="1"
            strokeWidth={0.5}
          />
          <AnimatedCircle
            cx="25"
            cy="25"
            r={innerCircleRadius}
            fill="transparent"
            stroke={outerCircleStrokeAnimated}
            strokeDasharray={innerCirclePerimeter}
            strokeDashoffset={innerCircleInitialFill}
            strokeLinecap={'round'}
          />
        </>
      )
    );
  };

  const Image = () => (
    <View
      style={{
        position: 'absolute',
        justifyContent: 'center',
        alignItems: 'center',
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
      }}>
      <Animated.Image
        source={image}
        style={[
          styles.image,
          {
            width,
            height,
            borderRadius: width * 0.5,
            transform: [{ scale: springValue }],
          },
        ]}
      />
    </View>
  );

  return (
    <View
      style={[
        styles.container,
        {
          //width: width * 1.5,
          //height: height * 1.5,
          borderRadius: 2 * Math.PI * outerCircleRadius,
        },
      ]}>
      <View>
        <Svg
          viewBox={`0 0 50 50`}
          width={width * 2.5}
          height={height * 2.5}
          style={{
            transform: [{ rotateZ: '-90deg' }],
          }}>
          <G>
            {outer()}
            {inner()}
          </G>
        </Svg>
        {Image()}

        <Text
          style={{
            fontSize: 10,
            fontWeight: 'bold',
            color: '#ffffff',

            position: 'absolute',
            justifyContent: 'center',
            alignItems: 'center',
            textAlign: 'center',

            backgroundColor: '#1393DB',
            borderRadius: 10,
            width: 20,
            height: 20,
            shadowColor: '#000',
            shadowOffset: {
              width: 0,
              height: 2,
            },
            shadowOpacity: 0.25,
            shadowRadius: 3.84,
            elevation: 5,
          }}>
          21
        </Text>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    justifyContent: 'center',
    alignItems: 'center',
    //backgroundColor: 'rgba(168, 152, 50, 0.5)',
  },
});
...