Background Image Parallax
➡️ Live Demo
import { motion, useScroll, useTransform } from 'framer-motion';
import Image from 'next/image';
import Background from '../../../public/background-2.jpg';
export default function Intro() {
const { scrollYProgress } = useScroll({
offset: ['start start', 'end start'],
}); // 🚧 offset 활용
// 🚧 스크롤의 진행률(0과 1 사이의 값)은 0vh에서 150vh 사이의 값으로 변환되어 translateY 값으로 사용
const y = useTransform(scrollYProgress, [0, 1], ['0vh', '150vh']);
return (
<div className='h-screen overflow-hidden'>
<motion.div style={{ y }} className='relative h-full bg-fuchsia-50'>
<Image src={Background} alt='image' fill className='object-cover' />
</motion.div>
</div>
);
}
export default function Home() {
// 🚧 자연스러운 스크롤 효과를 내기 위한 코드
useEffect(() => {
const lenis = new Lenis();
function raf(time: number) {
lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
}, []);
return (
<main className='relative h-svh '>
<Intro />
<Description />
<Section />
<div className='h-screen'></div>
</main>
);
}
export default function Section() {
const container = useRef(null);
const { scrollYProgress } = useScroll({
target: container,
offset: ['start end', 'end start'],
});
const y = useTransform(scrollYProgress, [0, 1], ['-10%', '10%']); // translateY
return (
<div
ref={container}
style={{ clipPath: 'polygon(0% 0, 100% 0%, 100% 100%, 0 100%)' }}
className='h-screen overflow-hidden relative flex items-center justify-center'
>
<div
className='relative z-10 p-20 mix-blend-difference text-white w-full h-full
flex flex-col justify-between'
>
<p className='uppercase mix-blend-difference w-[50vw] text-[2vw] self-end'>
Beauty and quality need the right time to be conceived and realised even in a world that is in too much of a hurry.
</p>
<p className='text-[5vw] mix-blend-difference uppercase'>Background Parallax</p>
</div>
<div className='fixed top-[-10vh] left-0 h-[120vh] w-full'>
<motion.div className='relative h-full w-full' style={{ y }}>
<Image src={Background} alt='' fill className='object-cover' />
</motion.div>
</div>
</div>
);
}
Last updated