React native shaking pin view when pin incorrect

928 views Asked by At

i am trying to implement a feature when user enters the wrong password the 4 small circles shake to the right and left.

I created an animation component to test my code and it was working but now my problem is how do i apply it only when the password is incorrect?

Currently when i enter an incorrect password nothing happens. What i expect is for the view to move horizontally.


const shake = new Animated.Value(0.5);

const [subtle,setSubtle]=useState(true);
const [auto,setAuto]=useState(false);

const translateXAnim = shake.interpolate({
  inputRange: [0, 1],
  outputRange: [subtle ? -8 : -16, subtle ? 8 : 16],
});

const getAnimationStyles = () => ({
  transform: [
    {
      translateX: translateXAnim,
    },
  ],
});

const runAnimation = () => {
  Animated.sequence([
    Animated.timing(shake, {
      delay: 300,
      toValue: 1,
      duration: subtle ? 300 : 200,
      easing: Easing.out(Easing.sin),
      useNativeDriver: true,
    }),
    Animated.timing(shake, {
      toValue: 0,
      duration: subtle ? 200 : 100,
      easing: Easing.out(Easing.sin),
      useNativeDriver: true,
    }),
    Animated.timing(shake, {
      toValue: 1,
      duration: subtle ? 200 : 100,
      easing: Easing.out(Easing.sin),
      useNativeDriver: true,
    }),
    Animated.timing(shake, {
      toValue: 0,
      duration: subtle ? 200 : 100,
      easing: Easing.out(Easing.sin),
      useNativeDriver: true,
    }),
    Animated.timing(shake, {
      toValue: 0.5,
      duration: subtle ? 300 : 200,
      easing: Easing.out(Easing.sin),
      useNativeDriver: true,
    }),
  ]).start(() => {
    if (auto) runAnimation();
  });
};

const stopAnimation = () => {
 shake.stopAnimation();
};

const handleConfirm = async()=>{  
      const result = await authApi();
  
      if(!result.ok) {
      setAuto(true)
      setSubtle(true)
      runAnimation()
      stopAnimation()

      return setLoginFailed(true);
      }
  
      setLoginFailed(false);
      };

return(

<Animated.View style={[getAnimationStyles()]}>

        <View style={styles.circleBlock}> 
         {
           password.map(p=>{
             let style =p != ''?styles.circleFill
               : styles.circle
            
            return <View style={style}></View>
           })
         }
          </View>

          </Animated.View>
1

There are 1 answers

0
Lakshman Kambam On BEST ANSWER

issue is that you didn't use useRef() for

const shake = new Animated.Value(0.5);

should be

const shake = useRef(new Animated.Value(0.5)).current;

useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component.

https://reactjs.org/docs/hooks-reference.html#useref

enter image description here

made separate expo snack with same input and output range values for animation shake effect. check it out.

Expo: https://snack.expo.io/@klakshman318/runshakeanimation