Анимация движения по кругу в React Native - PullRequest
2 голосов
/ 04 февраля 2020

Мне нужно создать анимацию с изображением, которое будет кружить вокруг другого изображения. Я уже пытался использовать предложения из аналогичного вопроса, например Анимировать круг вокруг другого круга , но, к сожалению, это не помогло. Я попытался найти сторонние модули, которые предлагали бы желаемую функциональность, но не нашел то, что соответствовало бы моим потребностям.

Я нашел полезную статью , чтобы понять круговое движение в JavaScript, однако мне трудно воспроизвести его в анимации React Native. Я считаю, что мне просто трудно понять правильное использование свойств стиля Анимированный API и transform, когда речь идет о анимации кругового движения.


<View style={animationContainer}>
    <Image
      source={require('./images/image.png')}
      style={image}
    />
    <Animated.Image
      source={require('./images/icon.png')}
      style={circlingIcon}
    />
</View>

1 Ответ

0 голосов
/ 10 февраля 2020

Я взял решение из вопроса отреагировал собственным анимацией преобразования окружностей и немного изменил его рефакторинг, разделив интерполяцию координат по Y и X в двух разных функциях.

interface InterpolatedMotion {
  translateX: Animated.Value;
  translateY: Animated.Value;
}

interface AnimatedIcon extends InterpolatedMotion {
  animated: Animated.Value;
}

interface State {
  icon: AnimatedIcon;
}

const defaultAnimatedIcon = (animatedValue: number): AnimatedIcon => ({
  animated: new Animated.Value(animatedValue),
  translateX: new Animated.Value(0),
  translateY: new Animated.Value(0),
});

export class Animation extends PureComponent<Props, State> {
  state = {
    icon: defaultAnimatedIcon(0),
  }

  constructor(props) {
    super(props);
    let { icon } = this.state;

    icon.animated.setValue(0);

    const snapshot = 50;
    const radius = 200;

    const inOutX = this.interpolateCircularMotionOverX(snapshot, radius);

    icon.translateX = coins.animated.interpolate(inOutX);

    const inOutY = this.interpolateCircularMotionOverY(snapshot, radius);

    icon.translateY = coins.animated.interpolate(inOutY);
  }

  componentWillMount(): void {
    this.startAnimation();
  }

  startAnimation = (): void => {
    let { icon } = this.state;

    icon.animated.setValue(0);

    let animations = [
      Animated.timing(
        icon.animated,
        {
          toValue: 1,
          duration: 8000,
          easing: Easing.linear,
        },
      ),
    ];

    Animated.loop(
      Animated.parallel(animations),
    ).start(() => {
      icon.animated.setValue(0);
    });
  }

  interpolateCircularMotionOverX = (snapshot: number, radius: number) => {
    const inputRange = [];
    const outputRange = [];
    for (let i = 0; i <= snapshot * 2; ++i) {
      const value = i / snapshot;
      const move = Math.sin(value * Math.PI * 2) * radius;
      inputRange.push(value);
      outputRange.push(move);
    }
    return { inputRange, outputRange };
  }

  interpolateCircularMotionOverY = (snapshot: number, radius: number) => {
    const inputRange = [];
    const outputRange = [];
    for (let i = 0; i <= snapshot * 2; ++i) {
      const value = i / snapshot;
      const move = -Math.cos(value * Math.PI * 2) * radius;
      inputRange.push(value);
      outputRange.push(move);
    }
    return { inputRange, outputRange };
  }

  render(): JSX.Element {
    const { icon } = this.state;

    const transformIcon = [
      { translateY: icon.translateY },
      { translateX: icon.translateX },
    ];

    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
          <View style={{ flex: 1 }}>
            <Animated.Image
              source={require('./images/coins.png')}
              style={[Styles.forms.circlingIcon, { transform: transformCoins }]}
            />
          </View>
        </View>
    );
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...