interpolateNode vs interpolate: interpolate вызывает рывки при анимации высоты, а interpolateNode - нет

Я только начал использовать react-native-reanimated. И я хотел бы использовать reanimated v2 apis (более новые).

Здесь, в этом примере, наблюдается значительное падение производительности при использовании и

Вот пример

      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>
  );
}

Вы можете проверить закуски здесь: - https://snack.expo.io/@sapien/tactless-orange .

Вопросов :-

  1. В чем разница между interpolate а также interpolateNode?
  2. Как выбрать между использованием любого из них?
  3. Почему один эффективнее другого?

1 ответ

  1. React Native Reanimated версии 1 использовал интерполяцию. Поскольку они хотели, чтобы вы могли использовать старый API (обратная совместимость и т. Д.), В версии 2 они представили interpolateNode.
  2. interpolateNode имеет гораздо лучшую производительность, чем interpolate.
  3. потому что interpolateNode новее. Они использовали много разных вещей, чтобы это работало лучше.