Framer motion에서 scroll animation 기능은 스크롤과 연동된 애니메이션을 구현할 수 있도록 도와준다. 크게는 (1) scroll-linked animation (스크롤 진행에 따라 애니메이션이 직접적으로 연동되는 방식)과 (2) scroll-triggered animation (요소가 뷰포트에 들어오간 나갈 때 애니메이션이 트리거 되는 방식)으로 나눈다.
Scroll-linked animation
scroll-linked animation 은 useScroll 훅을 통해서 스크롤과 연동된 애니메이션을 구현한다.
- scrollX / scrollY : 페이지의 수평 및 수직 스크롤 위치를 픽셀 단위로 반환한다.
- scrollXProgress / scrollYProgress : 페이지의 수평 및 수직 위치를 0과 1 사이의 값으로 반환한다.
1. useScroll에서 기능을 가져온다.
아래 예제에서는 scrollYProgress (수직 위치를 0과 1 사이의 값으로 반환) 을 가져왔다. 0은 페이지의 최상단, 1은 페이지의 최하단을 의미한다.
import { useScroll } from "framer-motion";
const Scrollexample = () => {
const {scrollYProgress} = useScroll();
}
export default Scrollexample;
2. scrollYProgress로 애니메이션을 적용한다.
scrollYProgress를 사용하여 motion.div의 scaleX 프로퍼티를 조정하면, 페이지 스크롤에 따라 프로그레스 바의 길이가 변하도록 설정할 수 있다.
import { useScroll, motion } from "framer-motion";
import styles from "./css/Scrollexample.module.css"
const Scrollexample = () => {
const { scrollYProgress } = useScroll();
return (
<div className={styles.container}>
<motion.div style={{ scaleX: scrollYProgress }} className={styles.bar} />
</div>
)
}
export default Scrollexample;
만약 전체적인 스크롤이 아니라, 특정 요소의 스크롤 위치를 추적해서 해당하는 애니메이션을 적용하고 싶으면 ref와 함께 사용하면 된다. useRef를 정의하고, useScroll을 useRef를 사용하여 정의한다.
import { useScroll, motion } from "framer-motion";
import { useRef } from "react";
export default function Comp01() {
const scrollRef = useRef(null);
const { scrollXProgress } = useScroll({ container: scrollRef });
return (
<div>
<motion.div style={{ scaleX: scrollXProgress, height: "300px", backgroundColor: "lightgray" }} />
<div ref={scrollRef} style={{ width: "800px", overflowX: "scroll" }}>
<div style={{ width: "200vw", height: "300px", background: "lightblue" }}/>
</div>
</div>
)
}
scroll-triggered animation
요소가 뷰포트에 들어오간 나갈 때 애니메이션이 트리거 되는 방식으로 whileInView를 통해 이러한 애니메이션을 만들 수 있다.
속성 | 설명 |
whileInView | 요소가 뷰포트에 있을 때 애니메이션 정의 |
viewport | 뷰포트를 정의하는 옵션 (뷰포트의 크기나 위치를 조정) |
onViewportEnter(entry) | 요소가 뷰포트에 들어올 때 호출되는 함수 |
onViewportLeave(entry) | 요소가 뷰포트를 벗어날 때 호출되는 함수 |
viewport 속성에 사용되는 옵션
옵션 | 설명 |
once | 요소가 뷰포트에 들어올 때 애니메이션을 한 번만 실행할지를 결정 |
root | 뷰포트를 기준으로 할 요소를 지정 |
margin | 뷰포트와 요소 간의 간격을 설정 (기본값 : "0px") |
amount | 요소가 뷰포트에 얼마나 들어와야 애니메이션을 트리거할지를 정의 (기본값: "some") amount의 경우에는 데스크탑 기준이기때문에 반응형 웹에서는 사용이 제대로 안된다. |
import { motion } from "framer-motion";
import './css/Comp01.css';
export default function Comp01() {
return (
<div className="container">
{/* 첫 번째 요소 */}
<motion.div
className="box"
initial={{ opacity: 0, scale: 0.5 }}
whileInView={{ opacity: 1, scale: 1 }}
viewport={{ once: true }} // 애니메이션을 한 번만 실행
transition={{ duration: 0.5 }}
>
<h2>첫 번째 요소</h2>
</motion.div>
{/* 두 번째 요소 */}
<motion.div
className="box"
initial={{ opacity: 0, x: -100 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ margin: "0px 0px -50% 0px" }} // 하단에서 -50% 지점에서 애니메이션 시작
transition={{ duration: 0.5 }}
>
<h2>두 번째 요소</h2>
</motion.div>
{/* 세 번째 요소 */}
<motion.div
className="box"
initial={{ opacity: 0, y: 100 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ amount: 0.5 }} // 요소의 50%가 보일 때 애니메이션 시작
transition={{ duration: 0.5 }}
>
<h2>세 번째 요소</h2>
</motion.div>
</div>
);
}
만약 전체적인 스크롤이 아니라, 특정 요소의 스크롤 위치를 추적해서 해당하는 애니메이션을 적용하고 싶으면 ref와 함께 사용하면 된다. useRef를 정의하고, viewport={{root : ref변수명}} 으로 속성을 정의하면 된다.
'Frontend > - Framer motion' 카테고리의 다른 글
Framer motion : useAnimationFrame에 대해서 (0) | 2024.10.19 |
---|---|
Framer motion : useInView 에 대해서 (4) | 2024.10.19 |
Framer motion : useTime & useAnimate에 대해서 (1) | 2024.10.06 |
Framer motion : Motion Value에 대해서 (1) | 2024.10.06 |
Framer motion : Layout Animation에 대해 알아보자 (0) | 2024.09.28 |
Framer motion : 제스처(Gestures)에 대해서 (2) drag, pan (0) | 2024.09.28 |
Framer motion : 제스처(Gestures)에 대해서 (1) hover, focus, tap (1) | 2024.09.28 |
Framer motion : variants에 대해서 (0) | 2024.09.24 |