Повторить анимацию с новым анимированным api

React-native вводит новый API Animated, я хочу создать анимацию цикла, такую ​​как масштабирование пузырьков, а затем уменьшить масштаб и повторить этот прогресс.

Однако я не могу понять это. Я пробовал написать код ниже

class TestProject extends React.Component {

  constructor(): void {
    super();
    this.state = {
      bounceValue: new Animated.Value(0),
      v: 1,
    };
  }

  componentDidMount() {
    this.state.bounceValue.setValue(1.5);

    let animation = Animated.timing(this.state.bounceValue, {
      toValue: this.state.v,
    });

    setInterval(() => {
      animation.stop();

      if (this.state.flag) {
        this.state.v = 0.5;
        this.state.bounceValue.setValue(0.5);
      }
      else {
        this.state.v = 1.5;
        this.state.bounceValue.setValue(1.5);
      }

      animation.start();
    }, 5000);

  }

  render(): ReactElement {
    return (
      <View style={styles.imageContainer}>
        <Image
          style={styles.image}
          source={{uri: 'http://image142-c.poco.cn/best_pocoers/20130517/91062013051716553599334223.jpg'}}
        />
        <Animated.Text
          style={[
            styles.test,
            {transform: [
              {scale: this.state.bounceValue},
            ],}
          ]
          }>
          haha
        </Animated.Text>
      </View>
    );
  }

}

но не работает очень хорошо.

Любое предложение будет оценено.

Ответы

Ответ 1

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

//this.state.animatedStartValue = 0;

function cycleAnimation() {
  Animated.sequence([
    Animated.timing(this.state.animatedStartValue, {
      toValue: 1,
      duration: 500,
      delay: 1000
    }),
    Animated.timing(this.state.animatedStartValue, {
      toValue: 0,
      duration: 500
    })
  ]).start(() => {
    cycleAnimation();
  });
}

Если я переключу эту анимацию на нее, она будет исчезать в/из, но я накладываю ее поверх базы, чтобы имитировать активное состояние или кнопку стиля hotspot

  <TouchableOpacity>
    <Animated.Image
      source={activeImageSource}
      style={this.state.animatedStartValue}}
    />
    <Image source={nonActiveImageSource}
    />
  </TouchableOpacity>

Реагировать на последовательную документацию по последовательности

Ответ 2

Теперь существует анимация цикла:

Animated.loop(
  Animated.sequence([
    Animated.timing(this.state.animatedStartValue, {
      toValue: 1,
      duration: 500,
      delay: 1000
    }),
    Animated.timing(this.state.animatedStartValue, {
      toValue: 0,
      duration: 500
    })
  ]),
  {
    iterations: 4
  }
).start()

Ответ 3

улучшенная версия ответа @bcomerford

//this.state.animatedStartValue = 0;

function cycleAnimation() {
  Animated.sequence([
    Animated.timing(this.state.animatedStartValue, {
      toValue: 1,
      duration: 500,
      delay: 1000
    }),
    Animated.timing(this.state.animatedStartValue, {
      toValue: 0,
      duration: 500
   })
  ]).start(event => {
    if (event.finished) {
      cycleAnimation();
    }
  });
}

Ответ 4

Кажется, что 'looping' теперь не поддерживается Animated api.

Мне удалось это сделать, запустив анимацию снова, когда она закончилась.

startAnimation() {
  Animated.timing(this._animatedValue, {
    toValue: 100,
    duration: 1000,
  }).start(() => {
    this.startAnimation();
  });
}

введите описание изображения здесь

Ожидаем лучшего решения...

Ответ 5

Вы можете установить еще одну анимацию, а затем снова вызвать анимацию:

Пример, который я сделал, чтобы угаснуть текст:

  textAnimate: function() {
    Animated.timing(
      this.state.textOpacity,
      {
        toValue: 0.3,                         
        duration: 500, 
      }
    ).start(() => {
      Animated.timing(  
        this.state.textOpacity,            
        {
          toValue: 1,                    
          duration: 500,          
        }
      ).start(() => {
          this.textAnimate();
        });
    });    
  },

  componentDidMount: function() {
    this.state.textOpacity.setValue(1)
    this.textAnimate();
  },

Ответ 6

Попробуйте что-то вроде этого:

componentDidMount() {
    this.bootAnimation();
  }

  bootAnimation() {
    this.animation = Animated.loop(
      Animated.timing(this.state.progress, {
        toValue: 1,
        duration: 5000
      })
    ).start();
  }