Media query based React Spring animations/transitions

803 views Asked by At

I've got this React Spring transition working nicely:

const Nav = () => {

  const[showMenu, setShowMenu] = useState(false)

  const navbgTransitions = useTransition(showMenu, null, {

      //FROM
      from: { 
        opacity: 1, position:'absolute', transform: 'translateX(225px)', 
      },

      //ENTER
      enter: { 
        opacity: 1, transform: 'translateX(0)'
      },

      //LEAVE
      leave: item => async (next, cancel) => {
        await new Promise(resolve => setTimeout(resolve, 500));
        await next({ opacity: 1, transform: 'translateX(225px)' })
      },
      
  })

})


return (
      <>
          {
            navbgTransitions.map(({ item, key, props }) =>
              item && 
              <animated.div key={key} style={props} className="background">
                <ul>
                    <Link onClick={() => setShowMenu(false)} to="/" exact><li>Home</li></Link>
                    <Link onClick={() => setShowMenu(false)} to="/about"><li>About</li></Link>
                    <Link onClick={() => setShowMenu(false)} to="/work"><li>Work</li></Link>
                    <Link onClick={() => setShowMenu(false)} to="/hire"><li>Hire Me</li></Link>
                </ul>
              </animated.div>
            )
          }

      </>
  );

export default Nav;

I've decided that I'd really like the animation to work differently on smaller devices. I was wondering, is there a way I can duplicate const navbgTransitions then wrap seperate React media queries around them and set the from, enter, and leave animations to play out differently depending on the viewport width?

I've done as much research as I can based on my understanding of React/Javascript and at the moment I'm tempted to switch over to react-transition-group as (from what I've read) this allows for stylesheet based animations.

I'm new to React so a bit of guidance would be greatly appreciated!

1

There are 1 answers

0
henrik hildebrand On BEST ANSWER

Yes, useMediaQuery from Material-ui can be used to determine the viewport width accordingly,

const matches = useMediaQuery('(min-width:600px)');

matches can then be used in your defined states for the transition to, for instance, use translateY on mobile devices instead of translateX (or whatever you want it to do for you),

from: { 
        opacity: 1, 
        position:'absolute', 
        transform: matches ? 'translateX(225px)' : 'translateY(50px)', 
      },