77 lines
2.9 KiB
TypeScript
77 lines
2.9 KiB
TypeScript
'use client'
|
|
|
|
import { motion, useScroll, useTransform } from 'framer-motion'
|
|
import { useRef } from 'react'
|
|
|
|
export default function ScrollReveal() {
|
|
const containerRef = useRef<HTMLDivElement>(null)
|
|
|
|
const { scrollYProgress } = useScroll({
|
|
target: containerRef,
|
|
offset: ["start start", "end end"]
|
|
})
|
|
|
|
// Text Animations - Sharp movement
|
|
const topTextY = useTransform(scrollYProgress, [0.1, 0.5], [0, -400])
|
|
const bottomTextY = useTransform(scrollYProgress, [0.1, 0.5], [0, 400])
|
|
|
|
// Video Animations - Sharp appearing.
|
|
// We use opacity as a "switch" at 0.1 to keep it hidden until then.
|
|
const videoVisible = useTransform(scrollYProgress, [0, 1], [0, 1])
|
|
const videoScale = useTransform(scrollYProgress, [0, 0.8], [0, 1])
|
|
const videoWidth = useTransform(scrollYProgress, [0, 0.8], ["20vw", "100vw"])
|
|
const videoHeight = useTransform(scrollYProgress, [0, 0.8], ["10vh", "100vh"])
|
|
const videoBorderRadius = useTransform(scrollYProgress, [0.6, 0.9], ["40px", "0px"])
|
|
|
|
return (
|
|
<section ref={containerRef} className="h-[300vh] relative bg-[#FAF7F0] z-60">
|
|
<div className="sticky top-0 h-screen w-full flex items-center justify-center overflow-hidden">
|
|
|
|
{/* TEXT MASK CONTAINER */}
|
|
<div className="absolute inset-0 z-30 flex items-center justify-center pointer-events-none">
|
|
<div className="h-[400px] w-full flex items-center justify-center overflow-hidden">
|
|
<motion.div className="text-center w-full">
|
|
<motion.h2
|
|
style={{ y: topTextY }}
|
|
className="text-7xl md:text-[140px] font-medium text-[#1A1A1A] leading-[0.8] mb-12"
|
|
>
|
|
Stay bliss
|
|
</motion.h2>
|
|
<motion.h2
|
|
style={{ y: bottomTextY }}
|
|
className="text-7xl md:text-[140px] font-medium text-[#1A1A1A] leading-[0.8]"
|
|
>
|
|
Enjoy more
|
|
</motion.h2>
|
|
</motion.div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* EXPANDING VIDEO CONTAINER */}
|
|
<motion.div
|
|
style={{
|
|
width: videoWidth,
|
|
height: videoHeight,
|
|
scale: videoScale,
|
|
borderRadius: videoBorderRadius,
|
|
opacity: videoVisible, // Use as an on/off switch instead of a slow fade
|
|
zIndex: 10
|
|
}}
|
|
className="relative bg-black overflow-hidden flex items-center justify-center"
|
|
>
|
|
<div className="relative w-full h-full">
|
|
<iframe
|
|
className="absolute inset-x-0 w-full h-[140%] -top-[20%] pointer-events-none"
|
|
src="https://www.youtube.com/embed/-A4UceF6QpE?autoplay=1&mute=1&loop=1&playlist=-A4UceF6QpE&controls=0&showinfo=0&rel=0&iv_load_policy=3&modestbranding=1"
|
|
allow="autoplay; encrypted-media"
|
|
allowFullScreen
|
|
/>
|
|
<div className="absolute inset-0 z-10" />
|
|
</div>
|
|
</motion.div>
|
|
|
|
</div>
|
|
</section>
|
|
)
|
|
}
|