如何制作动画线性渐变按钮?

How can I make an animated Linear Gradient button?

我正在使用 React Native,我们需要的组件之一是带有渐变背景的按钮。 OnPress 颜色应该从它们的基值平滑地动画到它们的活动值,并且当你完成时它们应该平滑地回到它们的基值。我正在使用 TouchableHighlight 组件来访问 onShowUnderlay 和 onHideUnderlay 函数以触发渐变变化。

我成功地让它在状态变化时突然改变,但我很难让它流畅地制作动画。当我使用以下代码时,模拟器给我这个错误:JSON value '<null>' of type NSNull cannot be converted to a UI Color. Did you forget to call processColor() on the JS side?,我认为这与 LinearGradient 无法将插值读取为 RGBA 值有关。

我没有正确使用动画 API 或线性渐变吗?还是根本不可能这样做?

import React, { PureComponent } from 'react';
import { Animated, View, TouchableHighlight, Text } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import styles from './styles/FooterButton.styles';

const AnimatedGradient = Animated.createAnimatedComponent(LinearGradient);

export default class FooterGradientButton extends PureComponent {
    midColor = new Animated.Value(0);
    lastColor = new Animated.Value(0);

  showUnderlay = () => {
    this.midColor.setValue(0);
    this.lastColor.setValue(0);
    Animated.parallel([
      Animated.timing(this.midColor, {
        duration: 500,
        toValue: 1,
      }),
      Animated.timing(this.lastColor, {
        duration: 500,
        toValue: 1,
      }),
    ]).start();
  };

  hideUnderlay = () => {
    this.midColor.setValue(1);
    this.lastColor.setValue(1);
    Animated.parallel([
      Animated.timing(this.midColor, {
        duration: 500,
        toValue: 0,
      }),
      Animated.timing(this.lastColor, {
        duration: 500,
        toValue: 0,
      }),
    ]).start();
  };

  render() {
    const firstColor = 'rgba(52, 85, 219, 1)';
    const midColor = this.midColor.interpolate({
      inputRange: [0, 1],
      outputRange: ['rgba(19, 144, 255, 1)', 'rgba(52,85,219, 1)'],
    });
    const lastColor = this.lastColor.interpolate({
      inputRange: [0, 1],
      outputRange: ['rgba(2,194,211, 1)', 'rgba(30,144,255, 1)'],
    });

    return (
      <View style={[styles.margin, styles.shadow]}>
        <AnimatedGradient start={{ x: 0.0, y: 0.5 }} end={{ x: 1, y: 0.5 }} style={{ flex: 1 }} colors={[firstColor, midColor, lastColor]}>
          <TouchableHighlight
            activeOpacity={1}
            underlayColor="#ffffff00"
            onShowUnderlay={() => this.showUnderlay()}
            onHideUnderlay={() => this.hideUnderlay()}
            style={[styles.gradientButton, styles.androidButton]}
            onPress={() => (!this.props.inactive ? this.props.onPress() : null)}
          >
            <Text style={[styles.buttonText, { color: 'white' }]}>NEXT</Text>
          </TouchableHighlight>
        </AnimatedGradient>
      </View>
    );
  }
}

看看react native placeholder。您应该能够传递线性渐变并为其设置动画。