Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Animated.diffClamp in react native

Any code example of how to implement Animated.diffClamp?

I'm trying to create a header scroll animation like the one featured in the google play app. I already hide the header when you start scrolling down, but the problem is that I want to show the header again as soon as you start scrolling up, it shows only when you reach the top of the view.

class Services extends Component {
  constructor(props){
  super(props);
  this.state = {
    scrollY : new Animated.Value(0),
  }
}

renderScrollViewContent(){
  return (
    <View style={styles.scrollViewContent}>
    </View>
  )
}

render() {
  const headerHeight = this.state.scrollY.interpolate({
    inputRange: [0, 60],
    outputRange: [0, -60],
    extrapolate: 'clamp'
  });

  return (
    <View style={styles.container}>
      <ScrollView style={styles.container}
        scrollEventThrottle={16}
        onScroll={Animated.event(
          [{nativeEvent: {contentOffset: {y: this.state.scrollY}}}]
        )}
      >
        {this.renderScrollViewContent()}
      </ScrollView>
      <Animated.View style={[styles.header, {top: headerHeight}]}>
        <View style={styles.bar}>
          <Text style={styles.title}>Title</Text>
        </View>
      </Animated.View>
    </View>
  );
 }
}
like image 304
Luis Fer Garcia Avatar asked Jan 27 '17 19:01

Luis Fer Garcia


1 Answers

We added this exactly for this use case. Here's the doc page https://reactnative.dev/docs/animated#diffclamp

I also recommend using it with a translate transform (better perf and can be used with native driver). Here's your example render using it:

const headerTranslate = Animated.diffClamp(this.state.scrollY, 0, 60)
  .interpolate({
    inputRange: [0, 1],
    outputRange: [0, -1],
  });
 
return (
 <View style={styles.container}>
   <ScrollView style={styles.container}
     scrollEventThrottle={16}
     onScroll={Animated.event(
       [{nativeEvent: {contentOffset: {y: this.state.scrollY}}}]
     )}
   >
     {this.renderScrollViewContent()}
   </ScrollView>
   <Animated.View style={[styles.header, {transform: [{translateY: headerTranslate}]}]}>
     <View style={styles.bar}>
       <Text style={styles.title}>Title</Text>
     </View>
   </Animated.View>
 </View>
);

How it works is we pass the scroll position to diffClamp so it is clamped between 0 and 60, after we use interpolate to make the value negative (we want it to translate up).

like image 89
Janic Duplessis Avatar answered Sep 29 '22 13:09

Janic Duplessis