본문 바로가기

개발

React에서 애니메이션 만들어 사용하기 (with. Hooks)

애니메이션은 웹 개발에서 중요한 요소 중 하나입니다. 애니메이션은 사용자의 관심을 끌고, 인터랙션을 증진시키고, 정보 전달을 돕습니다. 애니메이션을 구현하는 방법은 다양하지만, 이 글에서는 React 훅스와 CSS 키프레임(keyframes)을 조합하여 애니메이션을 구현하는 방법에 대해 알아보겠습니다.

 

React 훅스와 CSS 키프레임의 조합

React 훅스와 CSS 키프레임을 조합하여 애니메이션을 구현하는 방법은 다음과 같습니다.

React 훅스를 사용하여 컴포넌트의 상태를 관리하고, 상태에 따라 애니메이션을 실행할지 여부를 결정합니다.

CSS 키프레임을 사용하여 애니메이션의 시작과 끝 상태를 정의하고, 애니메이션의 속도와 타이밍 등을 조절합니다.

컴포넌트의 클래스 이름(class name)이나 인라인 스타일(inline style)을 상태에 따라 변경하여, CSS 키프레임에 정의된 애니메이션을 적용합니다.

 

로딩 애니메이션 만들기

React 훅스와 CSS 키프레임의 조합으로 애니메이션을 구현하는 예제로, 로딩 애니메이션을 만들어보겠습니다. 로딩 애니메이션은 데이터를 불러오거나 처리하는 동안 사용자에게 진행 상황을 보여주는 애니메이션입니다. 로딩 애니메이션은 다양한 형태가 있지만, 이 예제에서는 Google과 비슷한 동그라미 네 개가 순차적으로 커지고 작아지는 애니메이션을 만들어보겠습니다.

 

SVG로 그래픽 만들기

먼저, 로딩 애니메이션에 사용할 그래픽을 SVG로 만들어보겠습니다. SVG는 Scalable Vector Graphics의 약자로, 벡터 기반의 그래픽을 정의하는 XML 형식의 마크업 언어입니다. SVG는 HTML 문서에 직접 삽입할 수 있으며, CSS와 자바스크립트로 스타일과 애니메이션을 적용할 수 있습니다.

 

로딩 애니메이션에 사용할 그래픽은 동그라미 네 개로 구성되어 있습니다. 각 동그라미는 SVG의 요소로 만들 수 있습니다. 요소는 다음과 같은 속성을 가집니다.

- cx: 원의 중심의 x 좌표

- cy: 원의 중심의 y 좌표

- r: 원의 반지름

- fill: 원의 채우기 색상

 

SVG의 요소는 다음과 같은 속성을 가집니다.

- viewBox: SVG 그래픽의 크기와 위치를 정의하는 값으로, min-x min-y width height 형식으로 작성합니다.

- width: SVG 그래픽의 너비

- height: SVG 그래픽의 높이

다음은 로딩 애니메이션에 사용할 그래픽을 SVG로 만든 코드입니다.

<svg viewBox="0 0 150 33.2" width="180" height="150">
  <circle cx="16.1" cy="16.6" r="16.1" fill="#527abd" />
  <circle cx="55.2" cy="16.6" r="16.1" fill="#de4431" />
  <circle cx="94.3" cy="16.6" r="16.1" fill="#f4b61a" />
  <circle cx="133.4" cy="16.6" r="16.1" fill="#009e52" />
</svg>

 

React 훅스로 상태 관리하기

다음으로, React 훅스를 사용하여 로딩 애니메이션의 상태를 관리해보겠습니다. 로딩 애니메이션은 다음과 같은 상태를 가집니다.

- 로딩 중인지 여부를 나타내는 loading 상태

- 애니메이션을 실행할 동그라미의 인덱스를 나타내는 index 상태 loading 상태는 불리언 값으로, 로딩 중이면 true, 아니면 false입니다. index 상태는 숫자 값으로, 0부터 3까지의 값을 가집니다. 각 값은 동그라미 네 개 중 하나를 의미합니다.

 

React 훅스에서 상태를 관리하려면, useState 훅을 사용합니다. useState 훅은 다음과 같은 구조로 사용합니다.

const [state, setState] = useState(initialState);

다음으로는 로딩 애니메이션에 사용할 상태를 관리하는 예제입니다.

import React, { useState } from 'react';

const Loader = () => {
  // loading 상태를 관리합니다.
  const [loading, setLoading] = useState(true);

  // index 상태를 관리합니다.
  const [index, setIndex] = useState(0);

  // 나머지 코드 생략
};

css 키프레임으로 애니메이션 사용하기

/* 동그라미가 커지고 작아지는 애니메이션을 정의합니다. */
@keyframes scale {
  from {
    transform: scale(1);
  }
  to {
    transform: scale(1.5);
  }
}

/* 동그라미에 애니메이션을 적용합니다. */
.circle {
  animation: scale 0.5s ease-in-out infinite alternate;
}

/* 첫 번째 동그라미는 0초, 두 번째 동그라미는 0.1초, 세 번째 동그라미는 0.2초, 네 번째 동그라미는 0.3초 뒤에 애니메이션이 시작됩니다. */
.circle:nth-child(1) {
  animation-delay: 0s;
}

.circle:nth-child(2) {
  animation-delay: 0.1s;
}

.circle:nth-child(3) {
  animation-delay: 0.2s;
}

.circle:nth-child(4) {
  animation-delay: 0.3s;
}

 

React 훅스와 CSS 키프레임을 연결하기

마지막으로, React 훅스와 CSS 키프레임을 연결하여 로딩 애니메이션을 완성해보겠습니다. React 훅스와 CSS 키프레임을 연결하는 방법은 다음과 같습니다.

- 컴포넌트의 클래스 이름(class name)이나 인라인 스타일(inline style)을 상태에 따라 변경하여, CSS 키프레임에 정의된 애니메이션을 적용합니다.

- useEffect 훅을 사용하여 컴포넌트가 마운트(mount)되거나 업데이트(update)될 때마다, 상태를 변경하는 로직을 실행합니다.

 

useEffect 훅은 컴포넌트의 생명주기에 따라 부수 효과(side effect)를 수행할 수 있게 해주는 훅입니다. 부수 효과란 컴포넌트 외부에 영향을 주거나 받는 작업을 말합니다. 예를 들어, 데이터 불러오기, 타이머 설정, DOM 조작 등이 있습니다.

useEffect 훅은 다음과 같은 구조로 사용합니다.

useEffect(() => {
  // 부수 효과를 수행하는 함수
}, [dependencies]);

다음으로는 훅스와 css 키프레임을 연결해보겠습니다.

import React, { useState, useEffect } from 'react';

const Loader = () => {
  // loading 상태를 관리합니다.
  const [loading, setLoading] = useState(true);

  // index 상태를 관리합니다.
  const [index, setIndex] = useState(0);

  // 컴포넌트가 마운트되면, 3초 후에 loading 상태를 false로 변경합니다.
  useEffect(() => {
    setTimeout(() => {
      setLoading(false);
    }, 3000);
  }, []);

  // loading 상태가 true이면, 0.4초마다 index 상태를 1씩 증가시킵니다.
  // index 상태가 3이면, 다시 0으로 초기화합니다.
  useEffect(() => {
    if (loading) {
      const timer = setInterval(() => {
        setIndex((prevIndex) => (prevIndex === 3 ? 0 : prevIndex + 1));
      }, 400);
      return () => clearInterval(timer);
    }
  }, [loading]);

  // loading 상태에 따라, SVG 요소의 클래스 이름을 변경합니다.
  // loading 상태가 true이면, circle 클래스를 적용하고, index 상태와 일치하는 동그라미에 active 클래스를 추가합니다.
  // loading 상태가 false이면, circle 클래스를 제거합니다.
  return (
    <svg viewBox="0 0 150 33.2" width="180" height="150">
      <circle
        className={loading ? `circle ${index === 0 ? 'active' : ''}` : ''}
        cx="16.1"
        cy="16.6"
        r="16.1"
        fill="#527abd"
      />
      <circle
        className={loading ? `circle ${index === 1 ? 'active' : ''}` : ''}
        cx="55.2"
        cy="16.6"
        r="16.1"
        fill="#de4431"
      />
      <circle
        className={loading ? `circle ${index === 2 ? 'active' : ''}` : ''}
        cx="94.3"
        cy="16.6"
        r="16.1"
        fill="#f4b61a"
      />
      <circle
        className={loading ? `circle ${index === 3 ? 'active' : ''}` : ''}
        cx="133.4"
        cy="16.6"
        r="16.1"
        fill="#009e52"
      />
    </svg>)};
    
    export default Loader;

 

이상으로 React 훅스와 CSS 키프레임을 조합하여 로딩 애니메이션을 구현하는 방법에 대해 알아보았습니다. 감사합니다!