interpolateNode 与 interpolate : interpolate 在动画高度时会导致卡顿,而 interpolateNode 不会

问题描述

我刚刚开始使用 react-native-reanimated。我想使用 reanimated v2 api(较新的)。

这里,在这个例子中,使用 interpolateNodeinterpolate

示例如下

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. interpolateinterpolateNode 有什么区别?
  2. 如何选择两者之一?
  3. 为什么一个比另一个更高效?

解决方法

  1. React Native Reanimated 版本 1 使用了插值。由于他们希望您能够使用旧 API(向后兼容等),因此在版本 2 中,他们引入了 interpolateNode。
  2. interpolateNode 的性能比 interpolate 好得多。
  3. 因为 interpolateNode 较新。他们使用了很多不同的东西来让它更好地工作。