Skip to content

Instantly share code, notes, and snippets.

@dikaio
Created April 11, 2023 00:32
Show Gist options
  • Select an option

  • Save dikaio/c52ca7919a4ca54b2ef152218e7e6f27 to your computer and use it in GitHub Desktop.

Select an option

Save dikaio/c52ca7919a4ca54b2ef152218e7e6f27 to your computer and use it in GitHub Desktop.
Simple Fade in Fade out navigation menu using framer motion
"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