본문 바로가기

FrontEnd

CSS 애니메이션 : Keyframe

반응형

CSS 키프레임 애니메이션은 @keyframes at-rule을 사용하여 선언됩니다.
한 세트의 CSS 선언에서 다른 세트로의 전환을 지정할 수 있습니다.
@keyframes slide-in {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0%);
  }
}

각 @keyframes 문에는 이름이 필요합니다!

이 경우 이름을 slide-in으로 지정했습니다.

이것을 전역 변수처럼 생각할 수 있습니다.

 

키프레임 애니메이션은 일반적이며 재사용할 수 있습니다.

animation 속성을 사용하여 특정 선택자에 적용할 수 있습니다.

  .box {
    animation: slide-in 1000ms;
  }

동일한 keyframe 선언에 여러 애니메이션을 적용할 수 있습니다.

  @keyframes drop-in {
    from {
      transform:
        rotate(-30deg) translateY(-100%);
      opacity: 0;
    }
    to {
      transform:
        rotate(0deg) translateY(0%);
      opacity: 1;
    }
  }

  .box {
    animation: drop-in 1000ms;
  }

타이밍 함수

transition과 마찬가지로 키프레임 애니메이션은 기본적으로 ease 타이밍 곡선을 사용하지만

우리가 재정의할 수 있습니다.

 

animation-timing-function 속성으로 이 작업을 수행할 수 있습니다.

<style>
  @keyframes drop-in {
    from {
      transform: translateY(-100%);
    }
    to {
      transform: translateY(0%);
    }
  }

  .box {
    animation: drop-in 1000ms;
    animation-timing-function: linear;
  }
</style>

반복

기본적으로 키프레임 애니메이션은 한 번만 실행되지만
animation-iteration-count 속성을 사용하여 이를 제어할 수 있습니다.
<style>
  @keyframes slide-in {
    from {
      transform: translateX(-100%);
      opacity: 0.25;
    }
    to {
      transform: translateX(0%);
      opacity: 1;
    }
  }

  .box {
    animation: slide-in 1000ms;
    animation-iteration-count: 3;
  }
</style>

이와 같이 정수를 지정하는 것은 다소 드뭅니다. 그러나 편리한 한 가지 특별한 값이 있습니다. 바로 무한입니다.
로딩 스피너를 만드는 데 사용할 수 있습니다.
  @keyframes spin {
    from {
      transform: rotate(0turn);
    }
    to {
      transform: rotate(1turn);
    }
  }
  
  .spinner {
    animation: spin 1000ms;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
  }

스피너의 경우 일반적으로 linear 타이밍 함수를 사용하여 모션이 일정하도록 하는 것이 좋습니다.

멀티 스텝 애니메이션

from 및 to 키워드 외에도 백분율을 사용할 수도 있습니다. 이를 통해 2개 이상의 단계를 추가할 수 있습니다.

백분율은 애니메이션의 진행 상황을 나타냅니다.

 

from은 0%를 위한  to는 100%를 위한 문법적 설탕입니다.

중요한 것은 타이밍 함수가 각 단계에 적용된다는 것입니다.

즉, 각 단계를 하나로 연결할 수 없습니다.

이는 Web Anination API를 사용하여 해결합니다.

<style>
  @keyframes fancy-spin {
    0% {
      transform: rotate(0turn) scale(1);
    }
    25% {
      transform: rotate(1turn) scale(1);
    }
    50% {
      transform: rotate(1turn) scale(1.5);
    }
    75% {
      transform: rotate(0turn) scale(1.5);
    }
    100% {
      transform: rotate(0turn) scale(1);
    }
  }
  
  .spinner {
    animation: fancy-spin 2000ms;
    animation-iteration-count: infinite;
  }
</style>

<img
  class="spinner"
  alt="Loading…"
  src="/cfj-mats/loader.svg"
/>

Loading…

 


핑퐁 애니메이션

커졌다 작아지는 박스를 아래와 같이 구현할 수 있습니다.

<style>
  @keyframes grow-and-shrink {
    0% {
      transform: scale(1);
    }
    50% {
      transform: scale(1.5);
    }
    100% {
      transform: scale(1);
    }
  }

  .box {
    animation: grow-and-shrink 4000ms;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in-out;
  }
</style>

<div class="box"></div>

animation-direction은 키프레임의 순서를 제어합니다.

기본값은 normal이며 지정된 기간 동안 0%에서 100%까지 증가합니다.

reverse는 100%에서 0%까지 감소합니다.

alternate  normal <-> reverse를 반복합니다

<style>
  @keyframes grow-and-shrink {
    0% {
      transform: scale(1);
    }
    100% {
      transform: scale(1.5);
    }
  }

  .box {
    animation: grow-and-shrink 2000ms;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
    animation-direction: alternate;
  }
</style>

<div class="box"></div>

Hello World...

단축 속성

.box {
  /*
  From this:
    animation: grow-and-shrink 2000ms;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
    animation-direction: alternate;
  ...to this:
  */
  animation: grow-and-shrink 2000ms ease-in-out infinite alternate;
}

순서는 중요하지 않습니다.
이것은 다른 속성이 다른 값을 받아들이기 때문에 작동합니다.
예를 들어 alternate는 유효한 타이밍 함수나 반복 횟수가 아니므로
브라우저는 이를 애니메이션 방향에 할당하려는 의도를 추론할 수 있습니다.
.box {
  /* This works: */
  animation: grow-and-shrink 2000ms ease-in-out infinite alternate;
  /* This also works! */
  animation: grow-and-shrink alternate infinite 2000ms ease-in-out;
}

예외가 있습니다. animation-delay는 지속 시간 이후에 와야 합니다.

두 속성이 동일한 값 유형(밀리초/초)을 사용하기 때문입니다.

단축 속성 작성 시 delay를 제외하는 것을 선호합니다.

.box {
  animation: grow-and-shrink 2000ms ease-in-out infinite alternate;
  animation-delay: 500ms;
}
 

 

반응형

'FrontEnd' 카테고리의 다른 글

CSS 애니메이션 : 성능  (0) 2022.06.26
CSS 애니메이션 : Keyframe 응용  (0) 2022.06.25
CSS 애니메이션 : Transition  (0) 2022.06.25
CSS 애니메이션 : Transforms  (0) 2022.06.25
Styled-Components(CSS-in-js) 잘 활용하기  (0) 2022.06.25