从React Native动画中强制请求插值

时间:2018-02-10 22:19:11

标签: animation react-native colors interpolation

我正在尝试从反应原生动画中检索当前颜色。它通过interpolate映射到一组颜色字符串。

class IconTransition extends React.Component<Props, State> {
  protected _param: number = 0;

  constructor(props: Props) {
    super(props);

    this.state = {
      param: new Animated.Value(0)
    };

    this.state.param.addListener(param => {
      this._param = param.value;
    });
  }

  componentDidMount() {
    Animated.spring(this.state.param, {
      mass: 1,
      stiffness: 10,
      damping: 10,
      toValue: 1
    });
  }

  componentWillReceiveProps() {
    // I want to do something like this. Would be awesome
    // if I could avoid the listener in the constructor.
    //
    // const currentColor = Animated.interpolate.get({
    //   currentInput: this._param,
    //   outputRange: ["#FFFFFF", "#000000"]
    // });
  }

  render() {
    return (
      <AnimatedIcon
        {...this.props}
        color={this.state.param.interpolate({
          inputRange: [0, 1],
          outputRange: ["#FFFFFF", "#000000"]
        })}
      />
    );
  }
}

我想检索颜色,如插值,如果动画未完成。我知道我可能会使用一个外部库,例如chroma-js(特别是chroma.mix函数)来实现这一点 - 但是有不同的方法来插入两种不同的颜色,我宁愿如果我可以避免它,就不依赖于外部库。

所以...更大的问题仍然存在,我如何命令性地请求interpolation API的输出值?我们不能listen插值,就像我们使用Animated.Value()一样吗?

1 个答案:

答案 0 :(得分:0)

一段时间以来,我一直在尝试做同样的事情,您需要牢记一些事情:

如果将所有这些放在一起,那么您将获得如下所示的效果,在我的情况下如此:

import React from 'react';
import {View, processColor} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';

class BackgroundColorLinearGradientText extends React.Component {

    /**
     * Class constructor.
     */
    constructor(props, context) {
        super(props, context);
        this.backgroundColor = new Animated.Value(0);
        this.backgroundColor.addListener(i => {
            let interpolated = this.backgroundColor.interpolate({
                inputRange: [0, 1],
                outputRange: ['#FF0000', '#00FF00'],
            }).__getValue();
            if (this.background) {
                this.background.setNativeProps({colors: [processColor(interpolated), processColor(this.background.props.colors[1])]})
            }
        });
    }

    componentDidMount() {
        Animated.timing(this.backgroundColor, {
            toValue: 1,
            duration: 3000,
        }).start();
    }

    render() {
        return (
            <LinearGradient ref={i => this.background = i} colors={['red', 'blue']} style={{flex: 1}}>
                <View style={{
                    flex: 1,
                    justifyContent: 'center',
                    alignItems: 'center',
                }}>
                    Content
                </View>
            </LinearGradient>
        );
    }
}

这将创建一个具有红色到蓝色渐变背景的屏幕,并在三秒钟内过渡到绿色到蓝色。