[Just Site] 9. 살며시 내려오는 애니메이션 만들기 (CSS)

2022. 2. 20. 16:24프로젝트/Just Site

728x90

간단한 MBTI 사이트를 만들고 있는데, 'LU42'사이트를 보니까 사소한 애니메이션이 많았다.

그동안은 회사 내부적으로 사용하는 프로그램이라서 애니메이션이나 시각 효과를 쓸 일이 적었는데,

이제는 많이 사용하게 될 것 같아서 공부해봤다.

 

LU42

LU42는 나만의 새로운 표현방법을 찾는 공간입니다. 당신을 빛나게 해줄 브랜드들을 만나보세요.

www.lu42.co.kr


animation의 구조 살펴보기

 

animation - CSS: Cascading Style Sheets | MDN

animation CSS 속성은 다수의 스타일을 전환하는 애니메이션을 적용합니다. animation-name (en-US), animation-duration, animation-timing-function (en-US), animation-delay, animation-iteration-count (en-US), animation-direction, anima

developer.mozilla.org

애니메이션 속성은 다음 하위 속성들을 합친거다.

/* duration | timing-function | delay |
iteration-count | direction | fill-mode | play-state | name */

animation: 3s ease-in 1s 2 reverse both paused slidein;

animation-duration: /* 작동 시간. 예) 0s; 1s; */
animation-timing-function: /* 배속 변경) ease; ease-out; */
animation-delay: /* 대기 시간. 예) 0s; 1s; */
animation-iteration-count: /* 반복 시간. 예) 1; 1.5; 5; infinite; */
animation-direction: /* 정방향 / 역방향. 예) normal; reverse; alternate; */
animation-fill-mode: /* 실행 전, 후에 스타일 적용 방식. 예) none; forwards; backwards; */
animation-play-state: /* 진행 / 정지. 예) paused; running; */
animation-name: /* 애니메이션 이름. 본인의 커스텀하게 지은 이름 */

하위 속성만 따로 지정해도 된다.
단, 순서가 바뀌면 안 된다.


나만의 애니메이션 만들기

우선 animation-name에 해당하는 부분을 만들어야 한다.
어떻게 시작해서 어떻게 끝나는지, 중간에 어떤 상태로 가는지 등을 정한다.

우리는 @keyframes 키워드를 이용해 지정해보자.

@keyframes down {
  from {
    transform: translate(0, -20px);
    opacity: 0;
  }

  to {
    transform: translate(0, 0);
    opacity: 1;
  }
}

from이 시작 상태, to가 종료 상태다.

즉, y가 -20px이고 opacity가 0인 상태에서 시작해서,
y가 0이고 opaciry가 1인 상태로 끝나는 거다.

이런 식으로 위에서 아래로 내려온다.


animation 적용하기

하지만 @keyframes 선언만으로는 적용이 되진 않는다.
방식을 만든것 뿐이지, 이 방식으로 움직이라고 하진 않았다.

animation 속성으로 적용해주자.

.result_ani {
  /* animation: duration / timing-function / name */
  animation: 1.3s ease-in down;
}

진행 시간, 타이밍, 이름을 지정해 주었다.
이 이름 (name)에 해당하는게 아까 만들었던 @keyframes의 이름이다.

<h1 class="result_ani result__head">당신의 MBTI는</h1>
<img class="result_ani result__image" src={getTypeImage(result)} />
<h2 class="result_ani result__body">{result} 입니다.</h2>
<button class="result_ani result__button" onClick={handleShare}>공유하기</button>
<button class="result_ani result__button" onClick={handleReset}>다시하기</button>

(React라 순수 HTML과 약간 다르다. 알아서 보자.)

@keyframes down {
  from {
    transform: translate(0, -20px);
    opacity: 0;
  }

  to {
    transform: translate(0, 0);
    opacity: 1;
  }
}

.result_ani {
  animation: 1.3s ease-in down;
}

.result__head {

}

.result__image {
  animation-delay: .1s;
}

.result__body {
  animation-delay: .2s;
}

.result__button {
  animation-delay: .3s;
  display: block;
  width: 60%;
  height: 60px;
  margin: 10px auto;
}

이렇게 각 요소마다 delay를 줘서 순서대로 내려오게 했다.


처음에 안 보이게 하기

이렇게 설정하면 위의 gif처럼 초기 상태가 보인다.

그렇다고 opacity를 0으로 주면, 애니메이션이 끝난 다음에 안 보이게 된다.

그래서 있는 키워드가 animation-fill-mode다.

 

animation-fill-mode - CSS: Cascading Style Sheets | MDN

animation-fill-mode CSS 속성은 CSS 애니메이션이 실행 전과 후에 대상에 스타일을 적용하는 방법을 지정합니다.

developer.mozilla.org

forwards는 애니메이션 종료 상태를 그대로 적용하기,
backwards는 애니메이션 시작 상태를 스타일로 적용하는 것이다.

우리는 종료 상태 (opacity: 1)을 유지하고 싶으니까,
animation-fill-mode를 설정해보자.
그리고 처음에 보이지 않게 opacity는 0으로 한다.

.result_ani {
  opacity: 0;
  animation: 1.3s ease-in down;
  animation-fill-mode: forwards;
}