I'm trying to retrieve the current color from a react-native animation. It's mapped through interpolate to a set of color strings.
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"]
})}
/>
);
}
}
I want to retrieve the color, as interpolated, should the animation not finish. I'm aware I could probably use an external library such a chroma-js (in particular, the chroma.mix function) to achieve this - but there are different ways to interpolate through two different colors and I'd rather not depend on an external library if I can avoid it.
So... the greater question remains, how can I imperatively request an output value from the interpolation API? Can we not listen on interpolated values, just as we do with Animated.Value()?
To get the current value of Animated. Value with React Native, we call addListener on the animated value object. to call spinValue. addListener with a callback to get the current value of the animated value from the value property.
The updated answer should be: . start(({finished}) => { if (finished) { console. log('animation ended!) } })
I was trying to do the same for a while now and there's a few things you need to keep in mind:
addListener and setNativeProps methods
https://facebook.github.io/react-native/docs/animations#setnativeprops
__getValue method to check the current value.
This is the function you want to call in the listener to check the
current interpolated value
https://github.com/facebook/react-native/blob/master/Libraries/Animated/src/nodes/AnimatedInterpolation.js#L327
processColor
https://github.com/facebook/react-native/blob/master/Libraries/StyleSheet/processColor.js
If you put that all together you can get somthing like the following, which worked in my case:
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>
);
}
}
This will create a screen which has a red to blue gradient background, transitioning to green to blue in three seconds.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With