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

时间:2018-03-29 22:42:56

标签: javascript react-native linear-gradients

我正在使用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值。

我没有正确使用Animated API或LinearGradient吗?或者这样做是不可能的?

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>
    );
  }
}

1 个答案:

答案 0 :(得分:0)

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