1

I need to animate selected tab icon and I use reanimated 2 to achieve that. below is the concept of my custom bottom tab bar: enter image description here

as you can see the third tab is currently selected, my goal is to position the selected tab icon 15px to the left (I mean translateX to the value of -15) and after selecting another tab the Icon of previous tab will go back to the center (translateX to the 0). I tried some ways but no luck, here is what I implemented so far:


    const animateIcon = useAnimatedStyle(() => {
        return {
            transform: [
                {
                    translateX: withSpring(-15),
                },
            ],
        };
    });


const renderButtons = useMemo(() => {
        return tabs.map((tab: {name: string; id: number}) => { // a map over tabs array which has object's of each tab name and date
            return (
                <Box
                    key={tab.id}
                    alignItems='center'
                    flexDirection='column'
                    style={styles.overlay}
                >
                    <TouchableWithoutFeedback
                        onPress={() => onPress(tab.name, tab.id)}
                        style={styles.button}
                    >
                        <AnimatedBox style={[tab.id === currentRouteIndex ? animateIcon : null]}> //here I animate the icon if id of the tab is the same as current selected tab
                            <Home fill={'#000'} size={20} />
                        </AnimatedBox>
                    </TouchableWithoutFeedback>
                </Box>
            );
        });
    }, [animateIcon, onPress, styles.button, styles.overlay, tabs]);

can anyone give me a hint on this? above method doesn't work and it cause weird behavior

Ash Archin
  • 421
  • 9
  • 21

1 Answers1

0

At first you need to have a sharedValue or derivedValue that will trigger the animation from 0 to -15px an viceversa.

Then you can create a component to handle the animation:

export function AnimatedIcon({ children, focused } : { children: React.ReactNode; focused: number })  {
 const translate = useDerivedValue(() => {
  return withTiming(focused, { duration: 500 });
 });

 const rStyle = useAnimatedStyle(() => {
 const translateX = interpolate(translate.value, [0, 1], [0, -15]);

 return {
   transform: [{ translateX }],
 };
});

return <Animated.View style={rStyle}>{children}</Animated.View>;
bbernag
  • 143
  • 5