useModalTransition hook
This is a react hook for adding transition between an element on your page and an element in modal.
Features
- Based on the “flip animation technique”,
- Support react and nextjs,
- It's a hook, so there's no problem with the container ruining your style
- Use the Web Animations API (WAAPI),
- Lightweight,
- Wait until image in modal is loaded,
- Images in Modal height and width property can be set to “auto” (when “imgLoaded” added),
- Works with “srcset” and "sizes" (when “imgLoaded” added),
- Many configuration options,
- Tested in Cypress
Demo
https://use-modal-transition.vercel.app/
Setup
To run this project, install it locally using npm:
npm i use-modal-transition
Quick start
- Import the “useModalTransition” hook:
import useModalTransition from "use-modal-transition";
- Assign refs to the elements you want to animate.
const firstElemRef = useRef<HTMLDivElement>(null);
const modalElemRef = useRef<HTMLDivElement>(null);
<Modal isOpen={isOpen} onClose={onClose}>
<div ref={modalElemRef}></div>
</Modal>
<div ref={firstElemRef}></div>
- Create a state for the modal
const [isOpen, setIsOpen] = useState(false);
- Call the hook and pass the references and modal state
useModalTransition({
modalOpened: isOpen,
firstElemRef,
modalElemRef,
});
- Change the state onClick to start the animation.
return (
<>
<Modal isOpen={isOpen} onClose={onClose}>
<div
onClick={() => {
setIsOpen(false);
}}
ref={modalElemRef}>
</div>
</Modal>
<div
ref={firstElemRef}
onClick={() => {
setIsOpen(true);
}}>
</div>
</>
);
Usage details
Functions that hook returns
Hook returns a function called "restartAnimation", which can be used to restart the animation. A practical example of its usage is when you have a lightbox and you want to restart the animation each time you change a slide.
Examples on Codesandbox
Squares
https://codesandbox.io/p/devbox/squares-dm9f8w
Gallery
https://codesandbox.io/p/devbox/gallery-wf2r4t
Contact Button
https://codesandbox.io/p/devbox/contactbtn-rqgl9t
Possible problems
An element is being covered by others
Solution: use the callback functions (onOpenAnimationStart, onOpenAnimationEnd, onCloseAnimationStart, onCloseAnimationEnd) to change the “z-index” property during the animation.
Container with the overflow: "hidden" property covers an element
Solution: use the callback functions (onOpenAnimationStart, onOpenAnimationEnd, onCloseAnimationStart, onCloseAnimationEnd) to change the “overflow” property during the animation.
Sometimes the animation doesn't start(when use images)
Solution: When you use the images you have to pass the “imgLoaded” prop to hook.
Elements are distorted during the animation
Solution: Check that you are not animating any parent elements that are larger than the elements you want to animate. You can use the prop “pauseOnOpen” or “PauseOnClose”. During the animation the element should perfectly cover the element that is going to be under it.
The "restartAnimation" function is causing flickering.
Solution: Try calling the "restartAnimation" function in the "useLayoutEffect" hook.
About the flip animation technique
https://css-tricks.com/animating-layouts-with-the-flip-technique/