Framer motion prevent children from parent's animation

3.7k Views Asked by At

I got a problem with framer-motion. I have modal with overlay and I want to overlay have a fading in animation but modal-container (his child element) to have and scale animation (from 1px width and height to 100vh and 100vw). I would like to prevent somehow overlay from scaling and just change his opacity by animation. Do you have any ideas on how to prevent child from parent's animation?

I'm framer-motion very beginner so sorry for probably shitty code :D

my code:

<motion.div
        layout
        data-isOpen={isOpen}
        className="parent"
        ref={modalRef}
      >
          <ModalContainer
            initial={{opacity:0}}
            animate={animate}
          >
            <div className="w-100 d-flex justify-content-end">
              <Close
                onClick={() => {
                  closeModal();
                  clearAllBodyScrollLocks(modalRef);
                }}
                xmlns="http://www.w3.org/2000/svg"
                viewBox="0 0 20.39 20.39"
              >
                <title>close</title>
                <line
                  x1="16.39"
                  y1="16.39"
                  x2="4"
                  y2="4"
                  fill="none"
                  stroke="#000000"
                  strokeLinecap="round"
                  strokeMiterlimit="10"
                  strokeWidth="1"
                />
                <line
                  x1="4"
                  y1="16.39"
                  x2="16.39"
                  y2="4"
                  fill="none"
                  stroke="#000000"
                  strokeLinecap="round"
                  strokeMiterlimit="10"
                  strokeWidth="1"
                />
              </Close>
            </div>
            {children}
          </ModalContainer>
      </motion.div>

parent class :

.parent{
  width: 1px;
  height: 1px;
  position: absolute;
  justify-content: center;
  align-items: center;
  overflow: auto;
  border-radius: 2%;
}

.parent[data-isOpen="true"] {
  display: block;
  background-color: rgba(0,0,0,0.3);
  margin: auto;
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 0;
  left:0;
  z-index:2;
  border-radius: 2%;
  padding: 4rem 0;
}

disclaimer: if you have any other idea how to make it better, please tell me (i have only just one requirement to make modal-container scaling from button, which opens modal. I mean it grows from his center to position fixed)

Thanks for help

1

There are 1 best solutions below

2
On

If you're asking how to not have the overlay scale, then you just need to apply the scaling animation to the ModalContainer element, instead of the parent. But in that case, the modal will still fade in since its parent element is fading in. Is that what you want?

I think your solution will be to not have the modal be a child of the overlay. That way you can animate the opacity of the overlay, and the scale of the modal without either affecting the other.

If you want to keep them in the same component (you probably do), you could just have them both be siblings of the same parent element.

Structurally, something like this:

<div>
    <Overlay animate={{opacity: isOpen ? 1 : 0}} />
    <Modal animate={{scale: isOpen ? 1 : 0}} />
</div>