2

I have just started using react-native-reanimated. And I would like to use reanimated v2 apis (newer ones).

Here, in this example, there is a considerable performance drop using interpolateNode and interpolate

Here's the example

import * as React from 'react';
import { Text, View, StyleSheet, Dimensions, Image } from 'react-native';
import Constants from 'expo-constants';
import Animated, {
  useSharedValue,
  useAnimatedScrollHandler,
  Extrapolate,
  useAnimatedStyle,
  interpolate,
  interpolateNode,
} from "react-native-reanimated";

export const HEADER_IMAGE_HEIGHT = Dimensions.get("window").width / 3

const styles = StyleSheet.create({
  image: {
    position: "absolute",
    top: 0,
    left: 0,
    width: '100%',
    resizeMode: "cover",
  },
});

const IMAGE_URI = 'https://i.pinimg.com/originals/a4/1a/e5/a41ae5ff09234422737d3899cc895184.jpg'

const touchX = 100;

const heightInputRange = [-touchX, 0];
const heightOutputRange = [HEADER_IMAGE_HEIGHT + touchX, HEADER_IMAGE_HEIGHT];
const heightAnimConfig = {
  extrapolateRight: Extrapolate.CLAMP,
}

const topInputRange = [0, touchX];
const topOutputRange = [0, -touchX];
const topAnimConfig = {
  extrapolateLeft: Extrapolate.CLAMP,
}

export default function App() {
  // const scrollY = useSharedValue(0)

  // const scrollHandler = useAnimatedScrollHandler({
  //   onScroll: (e) => {
  //     scrollY.value = e.contentOffset.y;
  //   },
  // });

  // const animStyles = useAnimatedStyle(() => {
  //   return {
  //     height: interpolate(scrollY.value, heightInputRange, heightOutputRange),
  //     top: interpolate(scrollY.value, topInputRange, topOutputRange),
  //   }
  // })

  const scrollY = new Animated.Value(0);
  const scrollHandler = Animated.event([
    {
      nativeEvent: {
        contentOffset: {
          y: scrollY
        }
      }
    }
  ])
  const animStyles = {
    height: interpolateNode(scrollY, { 
      inputRange: heightInputRange,
      outputRange: heightOutputRange,
      extrapolateRight: Extrapolate.CLAMP,
    }),
    top: interpolateNode(scrollY, { 
      inputRange: topInputRange,
      outputRange: topOutputRange,
      extrapolateLeft: Extrapolate.CLAMP,
    }),
  }

  return (
    <View style={{ flex: 1 }}>
      <Animated.Image
        style={[styles.image, animStyles]}
        source={{ uri: IMAGE_URI }}
      />

      <Animated.ScrollView
        scrollEventThrottle={1}
        style={StyleSheet.absoluteFill}
        onScroll={scrollHandler}
      >
        <View style={{ height: HEADER_IMAGE_HEIGHT + 200 }} />
        {Array.from({ length: 50 }).map((v, idx) => {
          return (
            <View key={idx}>
              <Text>{idx}</Text>
            </View>
          )
        })}
      </Animated.ScrollView>
    </View>
  );
}

You could check up the snack here :- https://snack.expo.io/@sapien/tactless-orange.

Questions :-

  1. What is the difference between interpolate and interpolateNode?
  2. How to choose between using either of them?
  3. Why is one much performant than the other?
Prateek Thapa
  • 4,829
  • 1
  • 9
  • 23

1 Answers1

0
  1. React Native Reanimated version 1 used interpolate. Since they wanted you to be able to use old API (backwards compatibility, etc), in version 2, they introduced interpolateNode.
  2. interpolateNode has a much better performance than interpolate.
  3. because interpolateNode is newer. They used a lot of different stuff to make it work better.
Aria Bagheri
  • 1
  • 1
  • 1