How can i control Offset in Reactnative Animation?

Viewed 37

I made some code based on your lecture.

When onPanResponderRelease is executed, if dx<-50, goLeft.start() is used to move toValue: -200.

I also refreshed the position using position.flattenOffset(); In onPanResponderGrant, I saved the position value using setOffset.

However, when goLeft.start() is executed and the tovalue has shifted by -200 and the card is touched again, onPanResponderGrant starts at -200 but ,the position is set to -400 and the card starts at an entirely different position.

How can I fix the code so that after goLeft.start() is executed, the touch will start at -200?

this is my code

import React, { useRef, useState } from "react";
import { Animated, PanResponder, Text, View } from "react-native";
import styled from "styled-components/native";
import { Ionicons } from "@expo/vector-icons";
import icons from "./icons";

const Container = styled.View`
  flex: 1;
  justify-content: center;
  align-items: center;
  background-color: #00a8ff;
`;

const Card = styled(Animated.createAnimatedComponent(View))`
  background-color: white;
  width: 100px;
  height: 100px;
  justify-content: center;
  align-items: center;
  border-radius: 12px;
  box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
  position: absolute;
`;

const Btn = styled.TouchableOpacity`
  margin: 0px 10px;
`;

const BtnContainer = styled.View`
  flex-direction: row;
  flex: 1;
`;

const CardContainer = styled.View`
  flex: 3;
  justify-content: center;
  align-items: center;
`;

export default function App() {
  const [left, setLeft] = useState(false);
  // Values
  const position = useRef(new Animated.Value(0)).current;

  // Animations
  const goCenter = Animated.spring(position, {
    toValue: 0,
    useNativeDriver: true,
  });
  const goLeft = Animated.spring(position, {
    toValue: -200,
    tension: 5,
    useNativeDriver: true,
    restDisplacementThreshold: 100,
    restSpeedThreshold: 100,
  });
  const goRight = Animated.spring(position, {
    toValue: 500,
    tension: 5,
    useNativeDriver: true,
  });

  // Pan Responders
  const panResponder = useRef(
    PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onPanResponderGrant: () => {
        console.log("Grant", position._value);
        position.setOffset(position._value);
        position.flattenOffset();

        // position.addListener(() => {});
      },

      onPanResponderMove: (_, { dx }) => {
        console.log("Move:", dx);

        position.addListener(() => {});

        position.setValue(dx);

        // position.addListener(() => {});
      },

      onPanResponderRelease: (_, { dx }) => {
        console.log("Release:", dx);
        if (dx < -30) {
          console.log("!!!");
          goLeft.start();
          position.flattenOffset();
        } else {
          position.flattenOffset();
        }
      },
    })
  ).current;

  position.addListener(() => console.log("p:", position));

  // State
  const [index, setIndex] = useState(0);
  const onDismiss = () => {
    // position.setValue(-100);
    // Animated.timing(position, { toValue: -60, useNativeDriver: true }).start();
  };
  const closePress = () => {
    console.log("222");
    goLeft.start(onDismiss);
  };
  const checkPress = () => {
    console.log("111");
    goRight.start(onDismiss);
  };

  return (
    <Container>
      <CardContainer>
        <Card
          {...panResponder.panHandlers}
          style={{
            transform: [{ translateX: position }],
          }}
        >
          <Ionicons color="#192a56" size={98} />
        </Card>
      </CardContainer>
      <BtnContainer>
        <Btn onPress={closePress}>
          <Ionicons name="close-circle" color="white" size={58} />
        </Btn>
        <Btn onPress={checkPress}>
          <Ionicons name="checkmark-circle" color="white" size={58} />
        </Btn>
      </BtnContainer>
    </Container>
  );
}
0 Answers
Related