[실전 프로젝트] animation 사용해서 Spinner 만들기(styled-component 자식 요소 선택하는 방법)
본문 바로가기
항해 중/8-13주차 실전 프로젝트

[실전 프로젝트] animation 사용해서 Spinner 만들기(styled-component 자식 요소 선택하는 방법)

by 은돌1113 2022. 1. 7.

스피너(Spinner)를 구현 했더니 → 로딩 이미지가 필요 해졌고 → 로딩 이미지만 있으면 정적으로 보여서 심심하기 때문에 → 동적으로 바꿔주기 위해서 애니메이션을 추가했다.

 

구현 과정

  • 스피너 틀을 잡아 주었다.
    import React from "react";
    import styled from "styled-components";
    
    const Test = (props) => {
      return (
        <>
          <Outter>스피너입니다.</Outter>
        </>
      );
    };
    
    const Outter = styled.div`
      height: ${(props) => props.height};
      background-image: url(${SpinnerImage});
      background-repeat: no-repeat;
      z-index: 1000000;
    `;
    
    export default Test;​
  • 스피너를 사용할 컴포넌트에서 import 해준다.
    import Spinner from "../components/Spinner";​

    JSX에서 삼항연산자(조건문)을 사용해서 데이터를 불러오기 전에 Spinner 컴포넌트를 보여준다.

  • 애니메이션을 적용해서 Zzz...를 동적으로 바꿔줬다.
    • 이때 keyframe을 사용하여 애니메이션 설정을 해줬다. (+ 투명도 설정, opacity)
        @keyframes jumb {
          from {
            opacity: 1;
          }
          to {
            opacity: 0;
          }
        }​
    • 이번 로딩 스피너에서는 div를 부모로 설정하고, label을 자식으로 설정해서 자식에 애니메이션을 설정했다.
        & > Label:nth-child(1) {
          animation: jumb 2s infinite;
          animation-delay: 0.1s;
        }
        & > Label:nth-child(2) {
          animation: jumb 2s infinite;
          animation-delay: 0.3s;
        }
        & > Label:nth-child(3) {
          animation: jumb 2s infinite;
          animation-delay: 0.5s;
        }
        & > Label:nth-child(4) {
          animation: jumb 2s infinite;
          animation-delay: 0.7s;
        }
        & > Label:nth-child(5) {
          animation: jumb 2s infinite;
          animation-delay: 0.9s;
        }
        & > Label:nth-child(6) {
          animation: jumb 2s infinite;
          animation-delay: 1.1s;
        }​
       이때 label 마다 딜레이(delay) 설정을 해줘야 해서 animation-delay 속성을 사용했고, 무한 반복 해야 하기 때문에 infinite 속성을 사용 해줬다.

      + styled-component에서 자식 요소 선택자 사용하는 방법
      & > Label:nth-child(1){
      
      }
      
      - &(자기 자신 속성 지정)
      - > (자식 요소 선택)
      - Label(자식 요소 태그)
      - :nth-child(몇번째 자식인 지 알려주는 숫자)

실행 영상

 

전체 코드

더보기
더보기
import React from "react";
import styled from "styled-components";

// --- images ---
import SpinnerImage from "../static/images/spinner/Spinner.svg";

const Spinner = (props) => {
  // --- jsx ---
  return (
    <>
      <Outter height={props.height}>
        <Loading>
          <label>Z</label>
          <label>z</label>
          <label>z</label>
          <label>.</label>
          <label>.</label>
          <label>.</label>
        </Loading>
      </Outter>
    </>
  );
};

// --- styled-components ---
const Outter = styled.div`
  height: ${(props) => props.height};
  background-image: url(${SpinnerImage});
  background-repeat: no-repeat;
  z-index: 1000000;
`;

const Loading = styled.div`
  top: 40vh;
  left: 165px;
  width: 53px;
  height: 18px;
  font-size: ${({ theme }) => theme.fontSizes.xl};
  font-weight: ${({ theme }) => theme.fontWeight.Bold};
  color: ${({ theme }) => theme.colors.white};
  position: absolute;

  & > Label:nth-child(1) {
    animation: jumb 2s infinite;
    animation-delay: 0.1s;
  }
  & > Label:nth-child(2) {
    animation: jumb 2s infinite;
    animation-delay: 0.3s;
  }
  & > Label:nth-child(3) {
    animation: jumb 2s infinite;
    animation-delay: 0.5s;
  }
  & > Label:nth-child(4) {
    animation: jumb 2s infinite;
    animation-delay: 0.7s;
  }
  & > Label:nth-child(5) {
    animation: jumb 2s infinite;
    animation-delay: 0.9s;
  }
  & > Label:nth-child(6) {
    animation: jumb 2s infinite;
    animation-delay: 1.1s;
  }

  @keyframes jumb {
    from {
      opacity: 1;
    }
    to {
      opacity: 0;
    }
  }
`;

export default Spinner;

댓글