我有一些<AnimatedButton />
我想设置动画从100%的宽度变为40%的宽度,具体取决于一个名为isFullWidth的 bool 值的 Prop 。

我有:

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)然后返回的问题?

最佳答案

我建议您阅读更多有关interpolation的信息,因为在React Native中进行几乎任何类型的动画处理时,它都非常有用。

基本上,您可以使用interpolate将某些动画值映射到其他值。在您的情况下,您希望将40-100之间的数字映射到50%之类的百分比字符串。您要做的第二件事是将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%', '100%'],
        }),
        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>;
  }
}

07-28 01:11
查看更多