Last active
July 6, 2022 23:12
-
-
Save yaboynoem/4a8203e69a01912f623c94ce1f8ad3c1 to your computer and use it in GitHub Desktop.
animated hamburger icon using react and framer motion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import styled from "styled-components" | |
export const SHamburgerContainer = styled.div` | |
position: relative; | |
` | |
export const SHamburgerBox = styled.div` | |
display: flex; | |
flex-direction: column; | |
justify-content: center; | |
align-items: center; | |
gap: 4px; | |
border-radius: 5px; | |
cursor: pointer; | |
height: 40px; | |
opacity: 1; | |
overflow: hidden; | |
width: 40px; | |
` | |
export const SHamburgerPatty = styled.div` | |
width: 22.5px; | |
height: 3px; | |
border-radius: 25px; | |
margin: 0; | |
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { ReactElement } from "react" | |
import { motion } from "framer-motion" | |
import { useSelector } from "react-redux" | |
//Constants | |
import { EColor } from "Constants/Colors" | |
//Stores | |
import { store } from "Stores" | |
import { setIsSideBarOpen } from "Stores/App/Creators" | |
//Styles | |
import { SHamburgerBox, SHamburgerContainer, SHamburgerPatty } from "./Hamburger.styles" | |
//Types | |
import { TRootState } from "Types/GlobalTypes" | |
const Hamburger: React.FC = (): ReactElement => { | |
//react-redux selector | |
const { darkMode, isSideBarOpen } = useSelector((state: TRootState) => state.app) | |
return ( | |
<SHamburgerContainer> | |
<SHamburgerBox | |
as={motion.div} | |
animate={{ | |
//Changes the color of the hamburger depending on the darkMode | |
backgroundColor: darkMode ? EColor.CONTAINER_DARK : EColor.CONTAINER, | |
border: `2px solid ${darkMode ? EColor.CONTAINER : EColor.CONTAINER_DARK}`, | |
}} | |
onClick={() => store.dispatch(setIsSideBarOpen(!isSideBarOpen))} | |
> | |
<SHamburgerPatty | |
as={motion.div} | |
style={{ | |
//Sets the transform-origin of the patty to the center right of itself | |
originX: "right", | |
originY: "center", | |
}} | |
animate={{ | |
//Changes the color of the patty depending on the darkMode | |
backgroundColor: darkMode ? EColor.CONTAINER : EColor.CONTAINER_DARK, | |
//The actual animation when clicking on the burger | |
y: isSideBarOpen ? 8 : 0, | |
width: isSideBarOpen ? 12 : 22.5, | |
marginLeft: isSideBarOpen ? 11.5 : 0, | |
rotate: isSideBarOpen ? 45 : 0, | |
//Transition delays based on isSideBarOpen value | |
transition: { | |
y: { | |
duration: 0.25, | |
type: "spring", | |
delay: isSideBarOpen ? 0 : 0.25, | |
}, | |
width: { | |
duration: 0.25, | |
type: "spring", | |
delay: isSideBarOpen ? 0.25 : 0, | |
}, | |
marginLeft: { | |
duration: 0.25, | |
type: "spring", | |
delay: isSideBarOpen ? 0.25 : 0, | |
}, | |
rotate: { | |
duration: 0.25, | |
type: "spring", | |
delay: isSideBarOpen ? 0.25 : 0, | |
}, | |
}, | |
}} | |
/> | |
<SHamburgerPatty | |
as={motion.div} | |
animate={{ | |
//Middle patty will only animate the color change | |
backgroundColor: darkMode ? EColor.CONTAINER : EColor.CONTAINER_DARK, | |
}} | |
/> | |
{/* Opposite animation of the top patty line */} | |
<SHamburgerPatty | |
as={motion.div} | |
style={{ | |
originX: "right", | |
originY: "center", | |
}} | |
animate={{ | |
backgroundColor: darkMode ? EColor.CONTAINER : EColor.CONTAINER_DARK, | |
y: isSideBarOpen ? -8 : 0, | |
width: isSideBarOpen ? 12 : 22.5, | |
marginLeft: isSideBarOpen ? 11.5 : 0, | |
rotate: isSideBarOpen ? -45 : 0, | |
transition: { | |
y: { | |
duration: 0.25, | |
type: "spring", | |
delay: isSideBarOpen ? 0 : 0.25, | |
}, | |
width: { | |
duration: 0.25, | |
type: "spring", | |
delay: isSideBarOpen ? 0.25 : 0, | |
}, | |
marginLeft: { | |
duration: 0.25, | |
type: "spring", | |
delay: isSideBarOpen ? 0.25 : 0, | |
}, | |
rotate: { | |
duration: 0.25, | |
type: "spring", | |
delay: isSideBarOpen ? 0.25 : 0, | |
}, | |
}, | |
}} | |
/> | |
</SHamburgerBox> | |
</SHamburgerContainer> | |
) | |
} | |
export default Hamburger |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment