Function-like interpolation in React Native?
I have a scrollview
fixed length in my RN project that is supposed to act like parralax scrolling behavior. When I scroll and move the Y component, the X component of the title moves to the right, so when it is on top, it is 56px from the left, leaving enough room for the back arrow.
But it is linear. Is there a way to make this exponential. The best example would be the paraclax scrolling of a WhatsApp contact:
How do I have it now = red line (linear)
How I would like it: blue line (linear with attenuation, exponential, whatever it was called)
I got the zoom animation, but the linear movement is like a thorn in my eye, and the documentation for the animation values is overwhelming and unclear.
I have defined:
scrollY: new Animated.Value(0)
in state and in mine scrollview
as follows:
<ScrollView
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {y: this.state.scrollY}}}]
)}
and mine Animated.View
inside it looks like this:
<Animated.View
style={[
{marginTop: 30, alignSelf: 'flex-start' },
{translateX: headerTranslateX}
]}]}>
<Text>Title</Text>
</Animated.View>
A and interpolation:
const titleTranslateX = this.state.scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE*0.6, HEADER_SCROLL_DISTANCE],
outputRange: [0, 0, 56],
extrapolate: 'clamp',
})
which is linear in nature (I tried to set 10+ keypoints per bit inputRange
and outputRange
, but it gets messy and doesn't look natural enough)
Any advice on how to achieve the desired effect?
source to share
The only thing it says in the Animated Ease docs (function interpolation) is:
Interpolation
Each property can be performed first using interpolation. Interpolation maps input ranges to output ranges, typically using linear interpolation, but also supports attenuation functions. By default, it extrapolates the curve outside the specified ranges, but you can also force it to clamp the output value.
It doesn't mention how you can add the attenuate function. However, you will find the following in the source code: https://github.com/facebook/react-native/blob/e2ce98b7c6f4f2fc7011c214f9edc1301ff30572/Libraries/Animated/src/Interpolation.js#L27
export type InterpolationConfigType = {
inputRange: Array<number>,
/* $FlowFixMe(>=0.38.0 site=react_native_fb,react_native_oss) - Flow error
* detected during the deployment of v0.38.0. To see the error, remove this
* comment and run flow
*/
outputRange: (Array<number> | Array<string>),
easing?: ((input: number) => number),
extrapolate?: ExtrapolateType,
extrapolateLeft?: ExtrapolateType,
extrapolateRight?: ExtrapolateType,
};
The attenuation function is linear by default (t) => t
, but you can make it the standard standard attenuation function. Here's a good list: https://gist.github.com/gre/1650294
Note: this won't work if you are using useNativeDriver: true
.
Hope this helps to reduce the sloppiness!
source to share