Search code examples
reactjsstyled-componentsreact-spring

Transform: Translate Animation not working


I am wanting to achieve a "blind effect" where clicking on a button will cause an overlay div to animate up so only a small portion shows at the top of the screen and it reveals a div below.

I am using gatsby, with react spring and styled components. I have set the "blind" up as a component as follows:-

const HeroWrapper = styled(animated.div)`
  background-color: blue;
  height: 100vh;
  width: 100vw;
  text-align: center;
  position: fixed;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-direction: column;
  z-index: 15;
`
const HeroTitle = styled.h1`
  margin: auto;
  color: whitesmoke;
`

const Hero = () => {
  const [isHeroOpen, setHeroOpen] = useState(true)
  const heroAnimation = useSpring({
    transform: isHeroOpen ? `translate3d(0,0,0)` : `translate3d(0, -85%, 0)`,
  })

  return (
    <HeroWrapper style={heroAnimation} onClick={() => setHeroOpen(!isHeroOpen)}>
      <HeroTitle>I am a Hero Blind</HeroTitle>
      <div style={{ paddingBottom: '40px' }}>
        <button type="button" onClick={() => setHeroOpen(!isHeroOpen)}>
          Click
        </button>
      </div>
    </HeroWrapper>
  )
}

However the animation does not work with the transform:translate. If I replace this with an animation on the background color...

    backgroundColor: isHeroOpen ? `#66666666` : `green`,

...it works fine so all is working with the state toggle.

Also if I amend the transform:translate in the developer tools it also works - so what am I doing wrong?

Many thanks


Solution

  • It was a hard one. Apparently you have to include the percent sign for the first translate too for react-spring to interpolate it properly.

    const heroAnimation = useSpring({
      transform: isHeroOpen ? `translate3d(0,0%,0)` : `translate3d(0,-85%,0)`
    });
    

    Here is a sandbox for it: https://codesandbox.io/s/focused-maxwell-1m8vq