React native swipe animation not working and no error

270 views Asked by At

I'm using a swipe animation, the same one that is being used in apps like tinder. The animation used to work in a Class component and in JSX but I had to change it to a function with hooks in TSX for a project. Now the animation Doensn't work anymore but it also doesn't give a error. I guess I'm missing some code that is necessary to let it work or it also can be something with the Panresponder. But I absolutely got no clue.

Thanks in advance.

    const SCREEN_HEIGHT = Dimensions.get('window').height
    const SCREEN_WIDTH = Dimensions.get('window').width
    
    const { width, height } = Dimensions.get('screen')
    const thumbMeasure = (width - 48 - 32) / 3
    
    
    const MyComponent = (props: { index: any }) => {
      const [imagesData, setImagesData] = useState<Images[]>([])
      console.clear()
      console.log('Images data:', imagesData)
    
      useEffect(() => {
        LogBox.ignoreLogs(['Animated: `useNativeDriver`']);
    }, [])
    
      useEffect(() => {
        axios
          .get<Images[]>('https://api.thecatapi.com/v1/images/search?breed_ids=beng&include_breeds=true')
          .then((response: AxiosResponse) => {
            setImagesData(response.data)
          })
      }, [])
      const position = new Animated.ValueXY()
      const [index, setIndex] = useState(props.index || 0)
      const [panResponder, setPanResponder] = useState<any>()
    
      const rotate = position.x.interpolate({
        inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
        outputRange: ['-30deg', '0deg', '10deg'],
        extrapolate: 'clamp',
      })
    
      const rotateAndTranslate = {
        transform: [{
          rotate: rotate
        },
        ...position.getTranslateTransform()
        ]
      }
    
      const likeOpacity = position.x.interpolate({
        inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
        outputRange: [0, 0, 1],
        extrapolate: 'clamp',
      })
      const dislikeOpacity = position.x.interpolate({
        inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
        outputRange: [1, 0, 0],
        extrapolate: 'clamp',
      })
    
      const nextCardOpacity = position.x.interpolate({
        inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
        outputRange: [1, 0, 1],
        extrapolate: 'clamp',
      })
      const nextCardScale = position.x.interpolate({
        inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
        outputRange: [1, 0.8, 1],
        extrapolate: 'clamp',
      })
    
      useEffect(() => {
          setPanResponder(  PanResponder.create({
          onStartShouldSetPanResponder: (_evt, _gestureState) => true,
          onPanResponderMove: (_evt, gestureState) => {
            position.setValue({ x: gestureState.dx, y: gestureState.dy })
          },
          onPanResponderRelease: (_evt, gestureState) => {
            if (gestureState.dx > 120) {
              Animated.spring(position, {
                toValue: { x: SCREEN_WIDTH + 100, y: gestureState.dy },
                useNativeDriver: true,
              }).start(() => {
                setIndex( () => {
                  position.setValue({ x: 0, y: 0 })
                  return index + 1
                })
              })
            } else if (gestureState.dx < -120) {
              Animated.spring(position, {
                toValue: { x: -SCREEN_WIDTH - 100, y: gestureState.dy },
                useNativeDriver: true,
              }).start(() => {
                setIndex( () => {
                  position.setValue({ x: 0, y: 0 })
                  return index + 1
                })
              })
            } else {
              Animated.spring(position, {
                toValue: { x: 0, y: 0 },
                friction: 4, useNativeDriver: true,
              }).start()
            }
          },
        }))
      }, [])
    
      const Users = () => {
        return imagesData.map((item, i) => {
            if (i < index) {
              return null
            } else if (i == index) {
              return (
                <Animated.View
                  {...panResponder.panhandlers}
                  key={item.id}
                  style={[
                    rotateAndTranslate,
                    {
                      height: SCREEN_HEIGHT - 120,
                      width: SCREEN_WIDTH,
                      padding: 10,
                      position: 'absolute',
                    },
                  ]}
                >
                  <Animated.View
                    style={{
                      opacity: likeOpacity,
                      transform: [{ rotate: '-30deg' }],
                      position: 'absolute',
                      top: 50,
                      left: 40,
                      zIndex: 1000,
                    }}
                  >
                    <Text
                      style={{
                        borderWidth: 1,
                        borderColor: 'green',
                        color: 'green',
                        fontSize: 32,
                        fontWeight: '800',
                        padding: 10,
                      }}
                    >
                      LIKE
                    </Text>
                  </Animated.View>
    
                  <Animated.View
                    style={{
                      opacity: dislikeOpacity,
                      transform: [{ rotate: '30deg' }],
                      position: 'absolute',
                      top: 50,
                      right: 40,
                      zIndex: 1000,
                    }}
                  >
                    <Text
                      style={{
                        borderWidth: 1,
                        borderColor: 'red',
                        color: 'red',
                        fontSize: 32,
                        fontWeight: '800',
                        padding: 10,
                      }}
                    >
                      NOPE
                    </Text>
                  </Animated.View>
    
                  <Image
                    style={{ height: '86%', width: null, borderRadius: 10 }}
                    source={{ uri: `${item.url}` }}
                  />
                   <View style={{backgroundColor: '',  color: 'black', fontSize: 20, fontWeight: '800',  position: 'absolute', bottom: 95, right: 40, zIndex: 1000, width: '85%', height: '20%', borderRadiusTop: 20, }}>
                  <Text style={{ color: 'white', fontSize: 32, fontWeight: '800' }}>
                    {item.breeds[0].name}
                  </Text>
                  <Text style={{ color: 'white', fontSize: 18, fontWeight: '600' }}>
                  {item.breeds[0].origin}
                  </Text>
                  <View style={styles.iconen}>
                    <Ionicons style={styles.icon} name="timer" />
                    <Text style={styles.subtitle}>{item.breeds[0].life_span}</Text>
                    <Ionicons style={styles.icon} name="barbell-outline" />
                    <Text style={styles.subtitle}>{item.breeds[0].weight.metric}</Text>
                    <Ionicons style={styles.icon} name="earth" />
                    <Text style={styles.subtitle}>{item.breeds[0].country_code}</Text>
                  </View>
                  </View>
                </Animated.View>
              )
            } else {
              return (
                <Animated.View
                  key={item.id}
                  style={[
                    {
                      opacity: nextCardOpacity,
                      transform: [{ scale: nextCardScale }],
                      height: SCREEN_HEIGHT - 120,
                      width: SCREEN_WIDTH,
                      padding: 10,
                      position: 'absolute',
                    },
                  ]}
                >
                  <Animated.View
                    style={{
                      opacity: 0,
                      transform: [{ rotate: '-30deg' }],
                      position: 'absolute',
                      top: 50,
                      left: 40,
                      zIndex: 1000,
                    }}
                  >
                    <Text
                      style={{
                        borderWidth: 1,
                        borderColor: 'green',
                        color: 'green',
                        fontSize: 32,
                        fontWeight: '800',
                        padding: 10,
                      }}
                    >
                      LIKE
                    </Text>
                  </Animated.View>
    
                  <Animated.View
                    style={{
                      opacity: 0,
                      transform: [{ rotate: '30deg' }],
                      position: 'absolute',
                      top: 50,
                      right: 40,
                      zIndex: 1000,
                    }}
                  >
                    <Text
                      style={{
                        borderWidth: 1,
                        borderColor: 'red',
                        color: 'red',
                        fontSize: 32,
                        fontWeight: '800',
                        padding: 10,
                      }}
                    >
                      NOPE
                    </Text>
                  </Animated.View>
    
                  <Image
                    style={{ height: '86%', width: null, borderRadius: 10 }}
                    source={{ uri: `${item.url}` }}
                  />
                </Animated.View>
              )
            }
          })
          .reverse()
      }
    
      return (
        <View>
          <View>
          {Users()}
          </View>
          <View style={{ height: SCREEN_HEIGHT - 80 }}>
            <ButtonVote />
          </View>
        </View>
      )
    }
0

There are 0 answers