Javascript остановить вращение анимации после поворота в определенной степени - PullRequest
0 голосов
/ 01 мая 2020

Я хочу сделать поворот изображения до определенной степени после нажатия кнопки. Я следовал некоторым учебникам по inte rnet для реализации основы моего кода.

Я использую изображение arrow.png из inte rnet и хочу, чтобы оно вращалось с анимацией с + 45deg каждый раз Я нажимаю кнопку. Например, стрелка указывает по умолчанию вправо, после нажатия кнопки я хочу, чтобы она повернулась по часовой стрелке в нижний правый угол. Из этой позиции повторное нажатие должно вращать кончиком вниз и т. Д. c.

Моя проблема в том, что после нажатия кнопки моя анимация застряла в oop, и я не знаю, как заставить его вращаться с + 45 градусов, не переходя от 0 градусов каждый раз, когда я делаю это.

Это мой код


class App extends Component {
  constructor() {
    super();
    this.RotateValueHolder = new Animated.Value(0);
  }

  StartImageRotateFunction() {
    this.RotateValueHolder.setValue(0);
    Animated.timing(this.RotateValueHolder, {
      toValue: 1,
      duration: 1000,
      easing: Easing.linear,
    }).start(() => this.StartImageRotateFunction());
  }

  state = {
    count: 0,
  };

  onPress = () => {
    this.setState({
      count: this.state.count + 1,
    });
    this.StartImageRotateFunction(0);
  };

  render() {
    const RotateData = this.RotateValueHolder.interpolate({
      inputRange: [0, 1],
      outputRange: ['0deg', '45deg'],
    });

    return (
      <View style={styles.container}>
        <Animated.Image
          source={{ uri: 'https://img.icons8.com/plasticine/2x/arrow.png' }}
          style={{
            width: 200,
            height: 200,
            transform: [{ rotate: RotateData }],
          }}
        />
        <TouchableOpacity style={styles.button} onPress={this.onPress}>
          <Text>Apasa aici</Text>
        </TouchableOpacity>
        <View style={styles.countContainer}>
          <Text>Ai apasat aici de {this.state.count} times</Text>
          <Text>{this.estedisperat()} </Text>
        </View>
      </View>
    );
  }



Ответы [ 2 ]

1 голос
/ 02 мая 2020

Я вижу в вашем примере некоторые лишние фрагменты, см. Объяснение, где они закомментированы.

Вот рабочий пример

class App extends Component {
  constructor() {
    super();
    this.RotateValueHolder = new Animated.Value(0);

/*
  It seem that it could be defined only once, 
  recalculate the same transform on every render is not necessary  
*/
    this.RotateData = this.RotateValueHolder.interpolate({
      inputRange: [0, 1],
      outputRange: ['0deg', '45deg'],
    });
  }

  StartImageRotateFunction() {
   /*
Loop problem starts here, omit
This one set rotate value to 0 on very call 
    // this.RotateValueHolder.setValue(0);   
  */   
    Animated.timing(this.RotateValueHolder, {
      /*
      Next problem.
      instead times to times set target value to 1 you should use cuurent value from state 
      // toValue: 1,
      */
      toValue: this.state.count,
      duration: 1000,
      easing: Easing.linear,
    })
     /*
     call `.start()` is required, but when you pass callback into
     it will invoked just after animation ends,
     in your case it had start looping 
     // .start(() => this.StartImageRotateFunction());
     */
     .start();
  }

  state = {
    count: 0,
  };

  onPress = () => {
    this.setState({
      count: this.state.count + 1,
    }, () => this.StartImageRotateFunction());
    /*
     Last, bat not least, start animation after set new state
    // this.StartImageRotateFunction(0);
    */
  };

  render() {
    return (
      <View style={styles.container}>
        <Animated.Image
          source={{ uri: 'https://img.icons8.com/plasticine/2x/arrow.png' }}
          style={{
            width: 200,
            height: 200,
            transform: [{ rotate: this.RotateData /* `this`, due to moved in constructor */ }],
          }}
        />
        <TouchableOpacity style={styles.button} onPress={this.onPress}>
          <Text>Apasa aici</Text>
        </TouchableOpacity>
        <View style={styles.countContainer}>
          <Text>Ai apasat aici de {this.state.count} times</Text>
          <Text>{
/* just replace absent function with expected behavior */ 
`rotated ${(this.state.count * 45) % 360}`
}</Text>
        </View>
      </View>
    );
  }
}
1 голос
/ 01 мая 2020

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

Еще одна вещь, которая выглядит так, как будто может быть проблема, состоит в том, что ваша линия transform: [{ rotate: RotateData }] не привязана ни к какому другому состоянию, что означает, что будущие нажатия не будут быть в состоянии сообщить количество поворотов, которые должны произойти. Я бы ожидал какую-то линию, например

const degrees = this.state.count * 45; чтобы обозначить количество градусов, которое стрелка должна поворачивать после каждого щелчка.

Также, задавая вопрос, постарайтесь выделить проблемы на независимые части. Вы упоминаете две вещи:

  • Ваша анимация застревает в oop
  • Вы не знаете, как повернуть кнопку

Насколько далеко как показано во втором пуле выше, см. этот пример

Что необходимо отметить в вашей функции Animate, так это то, что она принимает домен и диапазон. Чтобы обеспечить постоянное вращение и количество кликов в указанном диапазоне, вы можете использовать оператор % по модулю. Смотрите упрощенный пример, который я создал здесь.

https://codesandbox.io/s/lucid-bas-bs7fw

import React, { useState } from "react";

const App = () => {
  const [count, setCount] = useState(0);

  const increment = () => setCount(count + 1);
  return (
    <>
      <button onClick={increment}>Increment</button>
      <div>{count * 45}</div>
    </>
  );
};

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