Created
April 11, 2023 00:32
-
-
Save dikaio/c52ca7919a4ca54b2ef152218e7e6f27 to your computer and use it in GitHub Desktop.
Simple Fade in Fade out navigation menu using framer motion
This file contains hidden or 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
| "use client" | |
| import { useEffect } from "react" | |
| import Link from "next/link" | |
| import { | |
| motion, | |
| useMotionTemplate, | |
| useMotionValue, | |
| useScroll, | |
| useTransform, | |
| } from "framer-motion" | |
| import Logo from "@/components/logo" | |
| let clamp = (number, min, max) => Math.min(Math.max(number, min), max) | |
| function useBoundedScroll(bounds) { | |
| let { scrollY } = useScroll() | |
| let scrollYBounded = useMotionValue(0) | |
| let scrollYBoundedProgress = useTransform(scrollYBounded, [0, bounds], [0, 1]) | |
| useEffect(() => { | |
| return scrollY.onChange((current) => { | |
| let previous = scrollY.getPrevious() | |
| let diff = current - previous | |
| let newScrollYBounded = scrollYBounded.get() + diff | |
| scrollYBounded.set(clamp(newScrollYBounded, 0, bounds)) | |
| }) | |
| }, [bounds, scrollY, scrollYBounded]) | |
| return { scrollYBounded, scrollYBoundedProgress } | |
| } | |
| export default function Header() { | |
| let { scrollYBoundedProgress } = useBoundedScroll(400) | |
| let scrollYBoundedProgressThrottled = useTransform( | |
| scrollYBoundedProgress, | |
| [0, 0.75, 1], | |
| [0, 0, 1] | |
| ) | |
| return ( | |
| <motion.header | |
| style={{ | |
| height: useTransform(scrollYBoundedProgressThrottled, [0, 1], [80, 50]), | |
| backgroundColor: useMotionTemplate`rgb(255 255 255 / ${useTransform( | |
| scrollYBoundedProgressThrottled, | |
| [0, 1], | |
| [1, 0.1] | |
| )})`, | |
| }} | |
| className="fixed inset-x-0 flex h-20 shadow backdrop-blur-md" | |
| > | |
| <div className="flex items-center justify-between w-full px-8 mx-auto"> | |
| <motion.p | |
| style={{ | |
| scale: useTransform( | |
| scrollYBoundedProgressThrottled, | |
| [0, 1], | |
| [1, 0.8] | |
| ), | |
| }} | |
| className="flex items-center text-xl font-semibold uppercase origin-left" | |
| > | |
| <Link href="/" className="items-center hidden space-x-2 md:flex"> | |
| <Logo className="text-slate-600 h-28" /> | |
| </Link> | |
| </motion.p> | |
| <motion.nav | |
| style={{ | |
| opacity: useTransform( | |
| scrollYBoundedProgressThrottled, | |
| [0, 1], | |
| [1, 0] | |
| ), | |
| }} | |
| className="flex space-x-4" | |
| > | |
| <a href="#">News</a> | |
| <a href="#">Sports</a> | |
| <a href="#">Culture</a> | |
| </motion.nav> | |
| </div> | |
| </motion.header> | |
| ) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment