tabs icon indicating copy to clipboard operation
tabs copied to clipboard

feat: pass current opacity to renderIcon prop in CrossFadeIcon

Open yassinecc opened this issue 6 years ago • 2 comments

Motivation

I was trying to animate a bottom tab bar in the same fashion as the Google Play Store app does. My plan was to use Lottie animations with react-navigation's createBottomTabBar.

const ActiveLottie = props => {
  const lottieRef = React.useRef();
  if (lottieRef.current) {
    lottieRef.current.play();
  };
  return <LottieView ref={lottieRef} source={require("./lottie.json")} speed={1} loop={false} />;
};

const InactiveLottie = props => {
  const lottieRef = React.useRef();
  if (lottieRef.current) {
    lottieRef.current.play();
  };
  return <LottieView ref={lottieRef} source={require("./lottie.json")} speed={-1} loop={false} />;
};

const tabIcons= {
  "Home": ({ focused }) => (focused ? <ActiveLottie/> : <InactiveLottie/>),  
  "Settings": ({ focused }) => <SettingsIcon focused={focused} />,  
  "Profile": ({ focused }) => <ProfileIcon focused={focused} />,  
}

const TabNavigator = createBottomTabNavigator({
  Home: HomeScreen,
  Settings: SettingsScreen,
  Profile: ProfileScreen,
}, { defaultNavigationOptions: ({ navigation }) => ({
  tabBarIcon: tabIcons[navigation.state.routeName]
  })
});

However, the active -> inactive tab animation for say tab A was playing when I was switching between tabs B and C, and I found out that although CrossFadeIcon renders both active and inactive tab icons with a different opacity, the Lottie view only accepts opacity as part of its own style and is not affected by its parent opacity.

This PR exposes the opacity applied by CrossFadeIcon to each tab icon child to fine-tune rendering logic on the client side.

Test plan

From the code above, change the behaviour of the Lottie components:

const ActiveLottie = props => {
  const lottieRef = React.useRef();
  React.useEffect(() => {
    if (props.currentOpacity === 1 && lottie.current) {
      lottie.current.play();
    }
  }, [currentOpacity]);
  return <LottieView ref={lottieRef} source={require("./lottie.json")} speed={1} loop={false} />;
};

const InactiveLottie = props => {
  const lottieRef = React.useRef();
  React.useEffect(() => {
    if (props.currentOpacity === 1 && lottie.current) {
      lottie.current.play();
    }
  }, [currentOpacity]);
  return <LottieView ref={lottieRef} source={require("./lottie.json")} speed={-1} loop={false} />;
};

yassinecc avatar Nov 17 '19 20:11 yassinecc

@satya164 @osdnk 🙏

yassinecc avatar Nov 28 '19 11:11 yassinecc

Maybe @ahmedu007?

yassinecc avatar Dec 10 '19 18:12 yassinecc