Motion: Trying to re-create a thing from react-spring...

Created on 2 Sep 2019  路  3Comments  路  Source: framer/motion

Hi all,

Not a feature request, per se, but a question:

I have a modal window that animates in and out of view with a toggle button, and I'm not sure how to do this with framer-motion. The user clicks a button and opens the modal, which then moves and scales and fades in, then when the user clicks the button again, it does the reverse. I'm using the useTransition hook from react-spring currently, but I'm not sure what would be the appropriate technique to use in framer-motion.

Here is my react-spring transition, for reference:

return (
    <Fragment>

      <FormContainer ref={joinRef}>

        {!isToggled ?
          (
            <JoinButton onClick={toggle}>Promo</JoinButton>
          ) : (
            <JoinButton onClick={toggle}>Close</JoinButton>
          )
        }

        {transition.map(({ item, key, props: fade }) => (
          item 
          &&
          <Form key={key} style={fade} name="contact-form" method="POST" data-netlify="true">
            <input type="hidden" name="contact-form" value="contact"/>
            <Message>
              Don鈥檛 miss out on a chance to win your next exotic getaway! Enter now!
            </Message>
            <Label>Name : <Input name="name" type="text"/></Label>   
            <Label>Email : <Input name="email" type="email"/></Label>
            <Label>Number : <Input name="phone" type="tel"/></Label>
            <SubmitButton
              whileHover={{ scale: 1.1 }}
              whileTap={{ scale: 0.9 }}
              type="submit"
            >
              Submit
            </SubmitButton>
            <DownArrow />
          </Form>
        ))}

      </FormContainer>

    </Fragment>
  )

...which works as I would expect.

I'm doing the following right now with framer motion, and the initial animation works, but the exit animation does not work:

return (
    <Fragment>
      <FormContainer ref={joinRef}>
        {!isToggled ?
          (
            <JoinButton onClick={toggle}>Promo</JoinButton>
          ) : (
            <JoinButton onClick={toggle}>Close</JoinButton>
          )
        }
        {isToggled &&
          <AnimatePresence>
            <Form
              initial={{ opacity: 0, transition: { duration: 1 }}}
              animate={{ opacity: 1, transition: { duration: 1 }}}
              exit={{ opacity: 0, transition: { duration: 1 }}}
              name="contact-form"
              method="POST"
              data-netlify="true"
            >
              <input type="hidden" name="contact-form" value="contact"/>
              <Message>
                Don鈥檛 miss out on a chance to win your next exotic getaway! Enter now!
              </Message>
              <Label>Name : <Input name="name" type="text"/></Label>   
              <Label>Email : <Input name="email" type="email"/></Label>
              <Label>Number : <Input name="phone" type="tel"/></Label>
              <SubmitButton
                whileHover={{ scale: 1.1 }}
                whileTap={{ scale: 0.9 }}
                type="submit"
              >
                Submit
              </SubmitButton>
              <DownArrow />
            </Form>
          </AnimatePresence>
        }
      </FormContainer>
    </Fragment>
  )

Any advice that could be given would be great, thank you :-)

feature

Most helpful comment

Try

<AnimatePresence>
{isToggled &&
            <Form

All 3 comments

Try

<AnimatePresence>
{isToggled &&
            <Form

ok, that worked alright, but I noticed that animations aren't so smooth in chrome and Firefox, but nice and buttery in safari, prolly a separate issue, but any thoughts as to why?

Also, is there a way to specify different variables for different media query breakpoints? i need the modal to come from the bottom right in mobile and the bottom left on desktop.

I'm sure there's hooks that can provide breakpoint data that you could use to set initial={{ x: isMobile ? 0:'calc(100vw)' }} - that sort of thing.

I've also found that Safari animation performance tends to be better. With opacity elements it tends to be relative to the physical size of the animating element. If there's a difference in perf between React Spring and Framer Motion I'd be surprised but interested to see sandboxes demonstrating this.

Was this page helpful?
0 / 5 - 0 ratings