Animation does not work properly in react native

801 views Asked by At

I tried making a carousel by watching a tutorial but I cannot get it to work for an event driven animation. Instead of animating it just updates the position to new location.

This does not happen if I use only one type of animation for transition, mentioning just one value to transform rotate instead of passing an expression.

what it looks like

what it should look like

const cards = ["tomato", "teal", "pink"]
const alpha = Math.PI/6

const Trans = () => {
const value = React.useRef(new Animated.Value(0)).current
const [toggled, setToggled] = React.useState(false)

const animationFn = () => {
    Animated.spring(value, {
        toValue: 1,
        friction: 10,
        useNativeDriver: true
    }).start()
    setToggled(toggled => !toggled)
}

const rotateOpen = (rotate) => {
    return value.interpolate({       
        inputRange: [0, 1],
        outputRange: ['0rad', `${rotate}rad`]
    })
}

const rotateClose = (rotate, maxValues) => {
    return value.interpolate({       
        inputRange: [0, 1],
        outputRange: [`${maxValues}rad`, `${rotate}rad`]
    })
}

return(
    <>
    {cards.map((card, index) => {
        const rotate = toggled ? (index - 1) * alpha : 0
        const maxValues = (index-1) * alpha
        return (
            <Animated.View key={card} style={{transform: [
                {translateY: -50},
                {translateX: -100},                 
                {rotate: !toggled ? rotateOpen(rotate) : rotateClose(rotate, maxValues) },                        
                {translateX: 100},                  
            ], borderRadius: 15, position: 'absolute', backgroundColor: card, height: 100, width: 200}} />
        )
    })}

  
    <View style={{paddingTop: 100}}>
        <TouchableOpacity onPress={() => { animationFn() }}>
        <Text style={{fontSize: 30}}>  Animate </Text>
        </TouchableOpacity>
    </View>
    </>
)
}
1

There are 1 answers

0
Garrett McCullough On BEST ANSWER

Your interpolation values shouldn't change between the open and close functions. The animation library knows that when you go from 0 to 1, you're rotating the block "out" and then when you go from 1 back to 0, you're applying the same interpolation in reverse

so this code appears to work correctly for me:

const Trans = () => {
  const value = React.useRef(new Animated.Value(0)).current;
  const [toggled, setToggled] = React.useState(false);

  useEffect(() => {
    Animated.spring(value, {
      toValue: toggled ? 0 : 1,
      friction: 10,
      useNativeDriver: false,
    }).start();
  }, [toggled, value]);

  return (
    <>
      {cards.map((card, index) => {
        const rotate = (index - 1) * alpha;

        return (
          <Animated.View
            key={card}
            style={{
              transform: [
                { translateY: -50 },
                { translateX: -100 },
                {
                  rotate: value.interpolate({
                    inputRange: [0, 1],
                    outputRange: ['0rad', `${rotate}rad`],
                  }),
                },
                { translateX: 100 },
              ],
              borderRadius: 15,
              position: 'absolute',
              backgroundColor: card,
              height: 100,
              width: 200,
            }}
          />
        );
      })}

      <View style={{ paddingTop: 100 }}>
        <TouchableOpacity
          onPress={() => {
            setToggled(!toggled);
          }}>
          <Text style={{ fontSize: 30 }}> Animate </Text>
        </TouchableOpacity>
      </View>
    </>
  );
};