Реагируйте на собственные анимированные проблемы - PullRequest
0 голосов
/ 08 октября 2018

Я пытаюсь анимировать круг, чтобы расширить и сжать его в виде петли для дыхательного приложения для людей с паническими атаками.Я пытаюсь изменить текст во времени с помощью анимации.Вдыхание в состоянии - текстовая переменная, которая показана в кругу - это может быть «вдох», «удержание» или «выдох».Анимация заставляет круг двигаться от 60% к полному размеру в течение времени выдоха, затем он должен измениться на «держать», затем сделать паузу для дыхания и удержания, затем уменьшить до 60% и сказать «выдох».

class BreatheCircle extends React.Component {
  state = {
    animated:new Animated.Value(0.6),
    breathe: 'Inhale',

  }

  componentDidMount(){
    this.state.animated.setValue(0.6)
    this.animateCircle();
  }
  componentWillUnmount(){
    Animated.timing(this.state.animated).stop();
  }
  sleep(milliseconds) {
    var start = new Date().getTime();
    for (var i = 0; i < 1e7; i++) {
      if ((new Date().getTime() - start) > milliseconds){
        break;
      }
    }
  }
  animateCircle(){
      this.setState({breathe: 'Inhale'})
      Animated.timing(this.state.animated, {toValue: 1, duration:breatheTimings.in*1000}).start()
      this.sleep(breatheTimings.in*1000)
      this.setState({breathe: 'Hold'})
      this.sleep(breatheTimings.hold*1000)
      this.setState({breathe: 'Exhale'})
      Animated.timing(this.state.animated, {toValue: 0.6, duration:breatheTimings.out*1000}).start()
      this.sleep(breatheTimings.out*1000)
      this.animateCircle()
      }

В данный момент это не работает (тестирование с помощью expo). Пожалуйста, кто-нибудь может дать мне совет о том, куда идти с этим.Спасибо

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

вам не нужна функция сна, и вы можете попробовать Animated.sequence (документы здесь при записи).И я рекомендую вам написать «Вдох», «Вдох» и «Задержать» и играть с непрозрачностью.

class BreatheCircle extends React.Component {
      state = {
          circleAnimation: new Animated.Value(0.6),
          holdAnimation: new Animated.Value(0),
          inhaleAnimation: new Animated.Value(0),
          exhaleAnimation: new Animated.Value(0),
      }

  breathAnimation = Animated.sequence([
      Animated.timing(this.state.inhaleAnimation, {toValue: 1, duration:100}),
      Animated.timing(this.state.circleAnimation, {toValue: 1, duration:breatheTimings.in*1000}),
      Animated.timing(this.state.inhaleAnimation, {toValue: 0, duration:100}),
      Animated.timing(this.state.holdAnimation, {toValue: 1, duration:100}),
      Animated.timing(this.state.holdAnimation, {toValue: 0, duration:100, , delay: breatheTimings.hold*1000}), //delay for the hold to disappear
      Animated.timing(this.state.exhaleAnimation, {toValue: 1, duration:100}),
      Animated.timing(this.state.circleAnimation, {toValue: 0.6, duration:breatheTimings.out*1000}),
      Animated.timing(this.state.exhaleAnimation, {toValue: 0, duration:100}),
  ])

  componentDidMount(){
    // this.state.animated.setValue(0.6) // state already declare
    this.animateCircle();
  }
  componentWillUnmount(){
    this.breathAnimation.stop();
  }

  animateCircle(){
      this.breathAnimation.start(() => this.animatedCircle())
  }


  //[...]

  <Text style={{opacity: this.holdAnimation}}>Hold<Text>
  <Text style={{opacity: this.inhaleAnimation}}>Inhale<Text>
  <Text style={{opacity: this.exhaleAnimation}}>Exhale<Text>
0 голосов
/ 08 октября 2018

Вы звоните setState в то же время, JavaScript не останавливается и не ждет завершения других функций.

Я не буду переписывать этот код, а расскажу о логике вашего вопроса, ноСпособ сделать это правильно можно использовать prevState, возможно, внутри функции сна.Например:

sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if (!(new Date().getTime() - start) > milliseconds){
      this.setState(prevState => {
        if (prevState.breathe === "Inhale") {
          prevState.breathe = "hold";
        } else if(prevState.breathe === "hold") {
          prevState.breathe = "Exhale";
        } else {
          prevState.breathe = "Inhale"
        }
        return prevState
      });
    }
  }
}

из React docs :

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

...

Думайте о setState () как о запросе, а не как о немедленной команде для обновления компонента.Для лучшего восприятия производительности React может задержать ее, а затем обновить несколько компонентов за один проход.React не гарантирует, что изменения состояния будут применены немедленно.

...