Animating the scale of an image based on the scroll view's offset

172 Views Asked by At

I'm building a header component similar to Twitter's profile page, where, as the user scrolls down the image will scale along with the scroll views scroll position. As the user scrolls up it should do the reverse with the header being clamped to a minimum height.

I have managed to achieve the scrolling down aspect where when the user pulls down on the scroll view the image scales in proportion to the scroll position, however, I am not able to figure out the reverse aspect.

VARIABLES

const EXPANDED_HEIGHT = width / 2 - (insets.top + 56);
const COLLAPSED_HEIGHT = insets.top + 56;
const scrollY = useRef(new Animated.Value(0)).current;

CODE

    <View style={{ flex: 1, backgroundColor: "white" }}>
      <AnimatedImage
        source={{ uri: venue.image_URL.landscape }}
        height={COLLAPSED_HEIGHT + EXPANDED_HEIGHT}
        width={width}
        style={{
          position: "absolute",
          left: 0,
          right: 0,
          height: COLLAPSED_HEIGHT + EXPANDED_HEIGHT,
          zIndex: 2,
          transform: [
            {
              scale: scrollY.interpolate({
                inputRange: [-100, 0],
                outputRange: [2, 1],
                extrapolateLeft: "extend",
                extrapolateRight: "clamp",
              }),
            },
          ],
        }}
      >
        <AnimatedBlurView
          tint="dark"
          intensity={33}
          style={{
            ...StyleSheet.absoluteFillObject,
            zIndex: 2,
            opacity: scrollY.interpolate({
              inputRange: [-50, 0, 50, 100],
              outputRange: [1, 0, 0, 1],
            }),
          }}
        />
      </AnimatedImage>
      <Animated.ScrollView
        onScroll={Animated.event(
          [{ nativeEvent: { contentOffset: { y: scrollY } } }],
          { useNativeDriver: true }
        )}
        contentInset={{ bottom: 50 + insets.bottom }}
        style={{
          flex: 1,
          backgroundColor: "white",
          marginTop: COLLAPSED_HEIGHT + EXPANDED_HEIGHT,
        }}
        showsVerticalScrollIndicator={false}
      >
        {* SCROLL VIEW CONTENT *}
      </Animated.ScrollView>
    </View>

The minimum height is the COLLAPSED_HEIGHT and the default height is the EXPANDED_HEIGHT.

0

There are 0 best solutions below