Post

[React] AOS 플러그인 사용

스크롤 위치에 따라 요소를 등장시키는 플러그인

[React] AOS 플러그인 사용

#01. 플러그인 설치

https://michalsnik.github.io/aos/ 에서 자세한 내용을 확인할 수 있다.

1
$ yarn add 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,           // 스로틀 지연시간
    });
}, []);

주요 옵션 설명

옵션기본값설명
duration400기본 애니메이션 지속시간 (ms)
easing‘ease’기본 easing 함수
oncefalsetrue: 한 번만 실행, false: 스크롤시마다 실행
mirrorfalse스크롤 아웃시 애니메이션 역재생 여부
offset120애니메이션 트리거 오프셋 (px)
disablefalse특정 조건에서 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;
}
This post is licensed under CC BY 4.0 by the author.