web-dev-qa-db-ja.com

パーセンテージに基づいてボタンの幅をアニメーション化するにはどうすればよいですか?

_<AnimatedButton />_を持っています

isFullWidthというブール値である小道具に応じて、100%の幅から40%の幅になるようにアニメーション化したいと思います。

私が持っています:

_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>
    }
}
_

問題は、アニメーション化せずに適切なパーセンテージにジャンプすることです。幅を単に_this.state.animatedValue_に設定し、パーセンテージではなくピクセルのみを使用してみました。 150から400およびそれ以降で、期待どおりに正常に動作します。

同じ質問が言うrgba(220, 100, 50, 0.8)からrgba(30, 70, 30, 1.0)への行き帰りに適用されますか?

11
VDog

interpolation について詳しく読むことをお勧めします。これは、React Nativeでほとんどすべての種類のアニメーションを実行するときに非常に役立つためです。

基本的にinterpolateを使用すると、アニメートされた値を他の値にマッピングできます。あなたのケースでは、40〜100の数値を50%のようなパーセント文字列にマッピングします。 2番目に行うことは、40〜100の数値を(例として)赤から青への色にマッピングすることです。

内挿ドキュメントを完全に読み、それを試してみて、その後に質問があるかどうか尋ねてください:)

だから私はこのようにします:

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