#01. 플러그인 설치
https://michalsnik.github.io/aos/ 에서 자세한 내용을 확인할 수 있다.
#02. 초기 구성
1. 라이브러리와 CSS 참조
useEffect()
가 필요하다
1
2
3
4
5
6
| import React, {memo, useEffect} from 'react';
import styled from 'styled-components';
import AOS from "aos";
import "aos/dist/aos.css";
|
2. 애니메이션이 적용될 박스의 스타일 정의
1
2
3
4
5
6
7
8
9
10
11
12
| const AosExContainer = styled.div`
.box {
width: 300px;
height: 200px;
font-size: 40px;
color: white;
background-color: #f60;
text-align: center;
line-height: 200px;
margin: 250px auto;
}
`;
|
3. [중요!!!] AOS
초기화
공식 레퍼런스를 확인하면 <body>
태그가 종료되기 전 AOS.init()
함수를 호출하라고 되어 있다.
이는 페이지가 로딩된 직후에 1회 호출해야 함을 의미한다.
동일한 효과를 내기 위해서 useEffect()
안에서 AOS.init()
를 호출한다.
1
2
3
| useEffect(() => {
AOS.init();
}, []);
|
4. AOS 글로벌 설정 옵션
AOS.init()
에 설정 객체를 전달하여 전역 설정을 변경할 수 있습니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| useEffect(() => {
AOS.init({
// 글로벌 설정
duration: 1000, // 기본 애니메이션 지속시간
easing: 'ease-in-out', // 기본 easing 함수
delay: 100, // 기본 지연시간
anchor_placement: 'top-bottom', // 기본 anchor placement
// 고급 설정
offset: 120, // 트리거 오프셋 (px)
once: false, // 한 번만 실행할지 여부 (true: 한번만, false: 반복)
mirror: false, // 스크롤 아웃시 애니메이션 역재생 여부
anchorPlacement: 'top-bottom', // 앵커 배치
// 반응형 설정
disable: false, // 조건부 비활성화
startEvent: 'DOMContentLoaded', // 시작 이벤트
// 디버깅
useClassNames: false, // CSS 클래스명 사용 여부
disableMutationObserver: false, // Mutation Observer 비활성화
debounceDelay: 50, // 디바운스 지연시간
throttleDelay: 99, // 스로틀 지연시간
});
}, []);
|
주요 옵션 설명
옵션 | 기본값 | 설명 |
---|
duration | 400 | 기본 애니메이션 지속시간 (ms) |
easing | ‘ease’ | 기본 easing 함수 |
once | false | true : 한 번만 실행, false : 스크롤시마다 실행 |
mirror | false | 스크롤 아웃시 애니메이션 역재생 여부 |
offset | 120 | 애니메이션 트리거 오프셋 (px) |
disable | false | 특정 조건에서 AOS 비활성화 |
반응형 설정 예시
1
2
3
4
5
6
7
8
9
10
11
| useEffect(() => {
AOS.init({
// 모바일에서는 AOS 비활성화
disable: window.innerWidth < 768,
// 또는 함수로 조건 설정
disable: function () {
return window.innerWidth < 768;
}
});
}, []);
|
#04. 실제 사용 예시
1. 기본 사용 방법
AOS에서 제공하는 기본 애니메이션들:
Fade animations
fade-up
- 아래에서 위로 페이드인fade-down
- 위에서 아래로 페이드인fade-left
- 오른쪽에서 왼쪽으로 페이드인fade-right
- 왼쪽에서 오른쪽으로 페이드인fade-up-right
- 왼쪽 아래에서 오른쪽 위로 페이드인fade-up-left
- 오른쪽 아래에서 왼쪽 위로 페이드인fade-down-right
- 왼쪽 위에서 오른쪽 아래로 페이드인fade-down-left
- 오른쪽 위에서 왼쪽 아래로 페이드인
Flip animations
flip-up
- 위쪽으로 뒤집기flip-down
- 아래쪽으로 뒤집기flip-left
- 왼쪽으로 뒤집기flip-right
- 오른쪽으로 뒤집기
Slide animations
slide-up
- 아래에서 슬라이드slide-down
- 위에서 슬라이드slide-left
- 오른쪽에서 슬라이드slide-right
- 왼쪽에서 슬라이드
Zoom animations
zoom-in
- 확대되며 나타남zoom-in-up
- 확대되며 위로 나타남zoom-in-down
- 확대되며 아래로 나타남zoom-in-left
- 확대되며 왼쪽으로 나타남zoom-in-right
- 확대되며 오른쪽으로 나타남zoom-out
- 축소되며 나타남zoom-out-up
- 축소되며 위로 나타남zoom-out-down
- 축소되며 아래로 나타남zoom-out-left
- 축소되며 왼쪽으로 나타남zoom-out-right
- 축소되며 오른쪽으로 나타남
조합 애니메이션 예시
1
2
3
4
| <div data-aos="fade-up">기본 페이드업</div>
<div data-aos="slide-right">오른쪽으로 슬라이드</div>
<div data-aos="zoom-in">확대되며 등장</div>
<div data-aos="flip-left">왼쪽으로 뒤집기</div>
|
2. 애니메이션 속성 설정
1
2
3
4
5
6
| <div data-aos="애니메이션이름"
data-aos-easing="가속도 옵션"
data-aos-duration="지속시간"
data-aos-delay="지연시간"
data-aos-anchor-placement="화면상의 위치"
data-aos-anchor="CSS선택자">
|
data-aos-easing
(가속도 옵션)
AOS에서 사용 가능한 easing 함수들:
기본 CSS Easing
linear
- 일정한 속도로 진행ease
- 느리게 시작 → 빨라짐 → 느리게 끝 (기본값)ease-in
- 느리게 시작해서 점점 빨라짐ease-out
- 빠르게 시작해서 점점 느려짐ease-in-out
- 느리게 시작 → 빨라짐 → 느리게 끝
AOS 확장 Easing
ease-in-back
/ ease-out-back
/ ease-in-out-back
- 뒤로 살짝 갔다가 진행ease-in-sine
/ ease-out-sine
/ ease-in-out-sine
- 부드러운 사인 곡선ease-in-quad
/ ease-out-quad
/ ease-in-out-quad
- 2차 곡선ease-in-cubic
/ ease-out-cubic
/ ease-in-out-cubic
- 3차 곡선ease-in-quart
/ ease-out-quart
/ ease-in-out-quart
- 4차 곡선ease-in-quint
/ ease-out-quint
/ ease-in-out-quint
- 5차 곡선
사용자 정의 베지어 곡선
1
| cubic-bezier(x1, y1, x2, y2)
|
예시:
1
2
3
| <div data-aos="fade-up" data-aos-easing="ease-in-out">기본 가속-감속</div>
<div data-aos="fade-up" data-aos-easing="ease-out-back">뒤로 튕기는 효과</div>
<div data-aos="fade-up" data-aos-easing="cubic-bezier(0.68, -0.55, 0.265, 1.55)">사용자 정의</div>
|
data-aos-anchor-placement
(화면상의 위치)
애니메이션이 트리거되는 요소의 위치와 뷰포트의 위치 조합을 설정합니다.
형식: 요소위치-뷰포트위치
요소 위치 옵션
top
- 요소의 상단center
- 요소의 중앙 (기본값)bottom
- 요소의 하단
뷰포트 위치 옵션
top
- 뷰포트의 상단center
- 뷰포트의 중앙bottom
- 뷰포트의 하단 (기본값)
사용 가능한 조합
값 | 설명 | 작동시점 |
---|
top-bottom | 요소 상단이 뷰포트 하단에 도달 | 요소가 화면에 막 나타날 때 |
top-center | 요소 상단이 뷰포트 중앙에 도달 | 요소가 화면 중앙까지 올라올 때 |
top-top | 요소 상단이 뷰포트 상단에 도달 | 요소가 화면 상단에 도달할 때 |
center-bottom | 요소 중앙이 뷰포트 하단에 도달 | 요소 절반이 화면에 나타날 때 |
center-center | 요소 중앙이 뷰포트 중앙에 도달 | 요소가 화면 정중앙에 올 때 |
center-top | 요소 중앙이 뷰포트 상단에 도달 | 요소 중앙이 화면 상단까지 올라올 때 |
bottom-bottom | 요소 하단이 뷰포트 하단에 도달 | 요소 전체가 화면에 나타날 때 |
bottom-center | 요소 하단이 뷰포트 중앙에 도달 | 요소 하단이 화면 중앙에 올 때 |
bottom-top | 요소 하단이 뷰포트 상단에 도달 | 요소 하단이 화면 상단까지 올라올 때 |
예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| <!-- 요소가 화면에 막 나타날 때 애니메이션 (기본값) -->
<div data-aos="fade-up" data-aos-anchor-placement="top-bottom">
일찍 시작
</div>
<!-- 요소가 화면 중앙에 올 때 애니메이션 -->
<div data-aos="fade-up" data-aos-anchor-placement="center-center">
중간에 시작
</div>
<!-- 요소 전체가 화면에 나타날 때 애니메이션 -->
<div data-aos="fade-up" data-aos-anchor-placement="bottom-bottom">
늦게 시작
</div>
<!-- 요소가 화면을 거의 벗어날 때 애니메이션 -->
<div data-aos="fade-up" data-aos-anchor-placement="bottom-top">
매우 늦게 시작
</div>
|
data-aos-anchor
(기준 요소 지정)
애니메이션 트리거의 기준이 되는 다른 요소를 CSS 선택자로 지정합니다.
기본적으로는 애니메이션이 적용되는 요소 자체가 기준이 되지만, 이 속성을 사용하면 다른 요소의 스크롤 위치를 기준으로 삼을 수 있습니다.
사용법
1
2
3
4
5
6
7
8
9
| <!-- 기준 요소 -->
<div id="trigger-element">기준이 되는 요소</div>
<!-- 실제 애니메이션이 적용되는 요소 -->
<div data-aos="fade-up"
data-aos-anchor="#trigger-element"
data-aos-anchor-placement="top-center">
다른 요소를 기준으로 애니메이션
</div>
|
실용적인 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| <!-- 헤더를 기준으로 사이드바 애니메이션 -->
<header id="main-header">메인 헤더</header>
<aside data-aos="slide-right"
data-aos-anchor="#main-header"
data-aos-anchor-placement="bottom-top">
헤더가 화면을 벗어날 때 나타나는 사이드바
</aside>
<!-- 섹션별로 순차적 애니메이션 -->
<section id="section1">
<h2 data-aos="fade-down">제목</h2>
<p data-aos="fade-up"
data-aos-anchor="#section1"
data-aos-anchor-placement="top-bottom"
data-aos-delay="200">
섹션이 나타날 때 지연된 애니메이션
</p>
</section>
|
data-aos-duration
(지속시간)
애니메이션이 완료되기까지 걸리는 시간을 밀리초(ms) 단위로 설정합니다.
- 기본값:
400ms
- 범위:
50ms
~ 3000ms
- 단위: 밀리초 (숫자만 입력)
1
2
3
4
5
6
7
8
9
10
11
| <!-- 빠른 애니메이션 (200ms) -->
<div data-aos="fade-up" data-aos-duration="200">빠른 효과</div>
<!-- 기본 애니메이션 (400ms) -->
<div data-aos="fade-up">기본 속도</div>
<!-- 느린 애니메이션 (1000ms) -->
<div data-aos="fade-up" data-aos-duration="1000">느린 효과</div>
<!-- 매우 느린 애니메이션 (2000ms) -->
<div data-aos="fade-up" data-aos-duration="2000">매우 느린 효과</div>
|
data-aos-delay
(지연시간)
애니메이션이 시작되기 전 대기하는 시간을 밀리초(ms) 단위로 설정합니다.
- 기본값:
0ms
(즉시 시작) - 범위:
0ms
~ 3000ms
- 단위: 밀리초 (숫자만 입력)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| <!-- 즉시 시작 -->
<div data-aos="fade-up">즉시 시작</div>
<!-- 200ms 후 시작 -->
<div data-aos="fade-up" data-aos-delay="200">조금 늦게 시작</div>
<!-- 500ms 후 시작 -->
<div data-aos="fade-up" data-aos-delay="500">늦게 시작</div>
<!-- 순차적 애니메이션 예시 -->
<div data-aos="fade-up" data-aos-delay="0">첫 번째 (즉시)</div>
<div data-aos="fade-up" data-aos-delay="100">두 번째 (100ms 후)</div>
<div data-aos="fade-up" data-aos-delay="200">세 번째 (200ms 후)</div>
<div data-aos="fade-up" data-aos-delay="300">네 번째 (300ms 후)</div>
|
복합 사용 예시
1
2
3
4
5
6
7
| <div data-aos="fade-up"
data-aos-easing="ease-out-back"
data-aos-duration="800"
data-aos-delay="200"
data-aos-anchor-placement="center-bottom">
부드럽게 튕기면서 0.8초 동안 0.2초 지연 후 나타남
</div>
|
#05. 전체 소스 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
| import React, {memo, useEffect} from 'react';
import styled from 'styled-components';
import AOS from "aos";
import "aos/dist/aos.css";
// 애니메이션을 적용할 박스
const AosExContainer = styled.div`
.box {
width: 300px;
height: 200px;
font-size: 40px;
color: white;
background-color: #f60;
text-align: center;
line-height: 200px;
margin: 250px auto;
}
`;
const AosEx = memo(() => {
useEffect(() => {
AOS.init();
}, []);
return (
<AosExContainer>
<h2>AosEx</h2>
<div className="box" data-aos="fade-zoom-in"
// 박스의 윗면이 화면 중앙에 왔을 때 작동
data-aos-anchor-placement="top-center"
data-aos-easing="ease-in-sine"
data-aos-duration="600">AOS</div>
<div className="box" data-aos="fade-left"
data-aos-anchor-placement="top-center"
data-aos-easing="ease-in-sine"
data-aos-duration="600">AOS</div>
<div className="box" data-aos="fade-right"
data-aos-anchor-placement="top-center"
data-aos-easing="ease-in-sine"
data-aos-duration="600">AOS</div>
<div id="example-anchor1">example-anchor1</div>
<div className="box" data-aos="fade-up"
// 지정된 id값을 갖는 요소가 화면에 등장한 시점에 작동
data-aos-anchor="#example-anchor1"
data-aos-easing="ease-in-sine"
data-aos-duration="600">AOS</div>
<div id="example-anchor2">
<div className="box" data-aos="fade-down"
data-aos-anchor="#example-anchor2"
data-aos-easing="ease-in-sine"
data-aos-duration="600">AOS</div>
</div>
</AosExContainer>
);
});
export default AosEx;
|
#06. 실용적인 팁과 주의사항
1. 성능 최적화
CSS will-change
속성 활용
1
2
3
| .aos-animate {
will-change: transform, opacity;
}
|
2. 접근성 (Accessibility) 고려
data-aos-once
속성은 애니메이션이 1회만 작동하게 한다.
키보드로 입력을 해야 하는 요소의 애니메이션이 반복 작동하여 입력을 불편하게 하는 상황을 방지한다.
1
2
3
4
| <!-- 포커스 가능한 요소는 애니메이션 후에도 접근 가능해야 함 -->
<button data-aos="fade-up" data-aos-once="true">
클릭 가능한 버튼
</button>
|
3. 반응형 디자인
1
2
3
4
5
6
7
8
9
10
| useEffect(() => {
const isMobile = window.innerWidth <= 768;
const isTablet = window.innerWidth <= 1024;
AOS.init({
duration: isMobile ? 300 : 600, // 모바일에서 더 빠른 애니메이션
offset: isMobile ? 50 : 120, // 모바일에서 더 작은 오프셋
once: isMobile, // 모바일에서는 한 번만 실행
});
}, []);
|
4. 디버깅 및 문제 해결
애니메이션이 작동하지 않을 때
1
2
3
4
5
6
7
8
9
10
11
12
| // 1. AOS 초기화 확인
console.log('AOS initialized:', AOS);
// 2. 요소 확인
useEffect(() => {
AOS.init();
// 개발 모드에서 디버깅 정보 출력
if (process.env.NODE_ENV === 'development') {
console.log('AOS elements:', document.querySelectorAll('[data-aos]'));
}
}, []);
|
스타일링 충돌 해결
1
2
3
4
5
6
7
8
| /* AOS 스타일과 충돌할 수 있는 CSS 주의 */
.my-element {
/* ❌ transform을 직접 설정하면 AOS와 충돌 */
/* transform: translateY(20px); */
/* ✅ 다른 속성 사용 */
margin-top: 20px;
}
|