React Native:动画组件只能运行一次

时间:2019-12-07 09:29:11

标签: javascript react-native animation

我正在React Native中创建一个圆形轮播 设计中的圆圈上有一些项目,当用户单击向上或向下按钮时,它将向上或向下移动项目。

这里是enter image description here

现在,使用React Native Animated,我只能使项目移动一次 但我不知道为什么它只移动一次?如果我再次点击上升按钮一次,它就不再移动

这是代码

import * as React from 'react';
import { Text, View, StyleSheet, Animated, Button } from 'react-native';
import Constants from 'expo-constants';

function degToRad(deg) {
  return (deg * Math.PI) / 180;
}

export default class Circle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      //usersList: ['A'],
      usersList: ['A', 'B', 'C', 'D', 'E', 'F'],
    };
    this.animations = [];
    for (let i = 0; i < this.state.usersList.length; i++) {
      this.animations.push(new Animated.ValueXY(this.returnXY(i)));
    }
  }

  returnXY = index => {
    let degree = (index * 360) / this.state.usersList.length;
    const { size, symbolSize } = this.props;
    const angleRad = degToRad(degree); //45
    const radius = size / 2;
    const center = radius;
    let x = radius * Math.cos(angleRad) + center - symbolSize / 2;
    let y = radius * Math.sin(angleRad) + center - symbolSize / 2;
    return { x, y };
  };

  constructoCircleElements = () => {
    let object = [];
    const { symbolSize } = this.props;

    for (let i = 0; i < this.state.usersList.length; i++) {
      let animation = this.animations[i].getLayout();
      object.push(
        <Animated.View
          style={[
            styles.symbol,
            {
              width: symbolSize * 2,
              height: symbolSize,
              borderRadius: symbolSize / 2,
            },
            animation,
          ]}>
          <Text style={{ color: 'white' }}>{this.state.usersList[i]}</Text>
        </Animated.View>
      );
    }
    return object;
  };

  goUp = () => {
    console.log('GO UP');
    for (let i = 0; i < this.state.usersList.length; i++) {
      let { x, y } = this.returnXY(i + 1);
      Animated.spring(this.animations[i], {
        toValue: { x, y },
      }).start();
    }
  };

  render() {
    const { size } = this.props;
    let displayList = this.constructoCircleElements();

    return (
      <View>
        <View
          style={[
            styles.circle,
            {
              width: size,
              height: size,
              borderRadius: size / 2,
            },
          ]}>
          <Text style={styles.circleCaption}>A</Text>
          {displayList}
        </View>
        <Button title={'UP'} color="black" onPress={this.goUp} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  circle: {
    backgroundColor: 'transparent',
    alignItems: 'center',
    justifyContent: 'center',
    borderWidth: 3,
    borderRadius: 500,
    borderStyle: 'dotted',
    borderColor: '#fff',
  },
  circleCaption: {
    fontSize: 70,
  },
  symbol: {
    backgroundColor: 'green',
    position: 'absolute',
  },
});

https://snack.expo.io/@rex_rau/sponaneous-yogurt 在Circle.js内部

我认为是因为我没有将项目x和y更新为最新状态? 但我不确定该怎么办?

谢谢

1 个答案:

答案 0 :(得分:1)

您没有保存圈子项目的当前索引。我对您的代码做了一些修改:

constructor(props) {
    super(props);
    this.state = {
      //usersList: ['A'],
      usersList: ['A', 'B', 'C', 'D', 'E', 'F'],
    };
    this.animations = [];
    for (let i = 0; i < this.state.usersList.length; i++) {
      //Here I added index 
      this.animations.push({
        value: new Animated.ValueXY(this.returnXY(i)),
        index: i,
      });
    }
  }

  returnXY = index => {
    let degree = (index * 360) / this.state.usersList.length;
    const { size, symbolSize } = this.props;
    const angleRad = degToRad(degree); //45
    const radius = size / 2;
    const center = radius;
    let x = radius * Math.cos(angleRad) + center - symbolSize / 2;
    let y = radius * Math.sin(angleRad) + center - symbolSize / 2;
    return { x, y };
  };

  constructoCircleElements = () => {
    let object = [];
    const { symbolSize } = this.props;

    for (let i = 0; i < this.state.usersList.length; i++) {
      let animation = this.animations[i].value.getLayout();
      object.push(
        <Animated.View
          style={[
            styles.symbol,
            {
              width: symbolSize * 2,
              height: symbolSize,
              borderRadius: symbolSize / 2,
            },
            animation,
          ]}>
          <Text style={{ color: 'white' }}>{this.state.usersList[i]}</Text>
        </Animated.View>
      );
    }
    return object;
  };

  goUp = () => {
    let temp = [];
    for (let i = 0; i < this.state.usersList.length; i++) {
      //Here I increment the count
      let { x, y } = this.returnXY(++this.animations[i].index);
      let animation = Animated.spring(this.animations[i].value, {
        toValue: { x, y },
      });
      temp.push(animation);
    }
    Animated.parallel(temp).start();
  };

  render() {
    const { size } = this.props;
    let displayList = this.constructoCircleElements();

    return (
      <View>
        <View
          style={[
            styles.circle,
            {
              width: size,
              height: size,
              borderRadius: size / 2,
            },
          ]}>
          <Text style={styles.circleCaption}>A</Text>
          {displayList}
        </View>
        <Button title={'UP'} color="white" onPress={this.goUp} />
      </View>
    );
  }
}

Here是测试的零食!

相关问题