web-dev-qa-db-fra.com

Comment animer la largeur d'un bouton en fonction du pourcentage, et la même chose pour son backgroundColor?

J'ai quelques <AnimatedButton />

Je veux l'animer pour passer de 100% à 40% de largeur en fonction d'un accessoire qui est un booléen appelé isFullWidth.

J'ai:

class AnimatedButton extends Component {
    constructor(props) {
      super(props);
      this.state = { width: new Animated.Value(100) };
    }
    toggleWidth() {
      const endWidth = this.props.isFullWidth ? 40 : 100;

      Animated.timing(this.state.width, {
        toValue: endWidth,
        duration: 200,
        easing: Easing.linear,
      }).start();
    }

    render() {
      <TouchableOpacity
       style={{ width: `${this.state.width}%` }}
       onPress={this.props.onPress}
      >
       // more stuff
      </TouchableOpacity>
    }
}

Le problème est qu'il saute simplement dans le pourcentage approprié sans animation. J'ai essayé de régler la largeur à seulement this.state.animatedValue Et plutôt que d'utiliser un pourcentage, utilisez simplement des pixels, par exemple 150 à 400 et retour, et cela fonctionne bien comme prévu.

La même question s'applique pour passer de dire rgba(220, 100, 50, 0.8) à rgba(30, 70, 30, 1.0) et vice-versa?

11
VDog

Je vous suggère de lire plus sur interpolation car il est très utile lorsque vous faites presque n'importe quel type d'animation en React Native.

Fondamentalement, avec interpolate, vous pouvez mapper certaines valeurs animées à d'autres valeurs. Dans votre cas, vous souhaitez mapper un nombre compris entre 40 et 100 à une chaîne de pourcentage comme 50%. La deuxième chose que vous voulez faire est de mapper le numéro entre 40-100 à la couleur (à titre d'exemple) du rouge au bleu.

Lisez les documents d'interpolation entièrement et expérimentez-le et demandez si vous avez des questions après cela :)

Donc je le ferais comme ceci:

class AnimatedButton extends Component {
  constructor(props) {
    super(props);
    this.state = { width: new Animated.Value(100) };
  }

  toggleWidth() {
    const endWidth = this.props.isFullWidth ? 40 : 100;

    Animated.timing(this.state.width, {
      toValue: endWidth,
      duration: 200,
      easing: Easing.linear,
    }).start();
  }

  render() {
    <TouchableOpacity
      style={{
        width: this.state.width.interpolate({
          inputRange: [0, 1],
          outputRange: ['0%', '1%'],
        }),
        backgroundColor: this.state.width.interpolate({
          inputRange: [40, 100],
          outputRange: ['rgba(30, 70, 30, 1.0)', 'rgba(220, 100, 50, 0.8)'],
        }),
      }}
      onPress={this.props.onPress}
    >
      // more stuff
    </TouchableOpacity>;
  }
}
22
Henrik R