[React] CSS 애니메이션의 모든 것
💡 시작하기
디프만에서 프로젝트를 하다가 인터랙션을 구현하게 되었는데요. 하지만 애니메이션에 대해 구현해본 적이 거의 없는 저에게는 큰 도전이었어요. 이것저것 찾아보며 공부한 내용들을 정리해보려고 해요!
🎨 animation
CSS 애니메이션을 구현하기 위해 animation 속성을 사용할 수 있어요.
| 속성 | 설명 | 예시 |
|---|---|---|
animation-delay | 애니메이션의 시작시간을 지정 | animation-delay: 5s |
| 5초 뒤에 애니메이션 시작 | ||
animation-direction | 애니메이션이 종료되고 다시 처음부터 | |
| 시작할지 역방향으로 진행할지 지정 | animation-direction: reverse | |
| 애니메이션이 역방향으로 진행됨 | ||
animation-duration | 한 싸이클의 애니메이션이 | |
| 얼마에 걸쳐 일어날지 지정 | animation-duration: 5s | |
| 애니메이션이 5초 동안 진행됨 | ||
animation-iteration-count | 애니메이션이 몇 번 반복될지 지정. | |
| infinite로 지정하여 무한히 반복 가능 | animation-iteration-count: 2 | |
| 애니메이션 2번 반복 | ||
animation-name | 애니메이션의 중간 상태를 지정. | |
| @keyframes와 함께 사용 | animation-name: slideIn | |
| slideIn이라는 중간 상태 지정 | ||
animation-play-state | 애니메이션을 멈출지 | |
| 다시 시작할지 결정 | animation-play-state: running | |
| 애니메이션 다시 시작 | ||
animation-timing-function | 중간 상태의 전환을 | |
| 어떻게 할지 결정 | animation-timing-function: linear | |
| 애니메이션의 속도가 처음부터 끝까지 일정 | ||
animation-fill-mode | 애니메이션이 시작되기 전이나 | |
| 끝나고 난 후 어떤 값이 적용될지 지정 | animation-fill-mode: forwards | |
| 애니메이션이 끝난 후 그 지점에 그대로 위치 |
animation의 속성들은 각각 작성할 수도 있지만, 여러 속성의 값들을 한 번에 작성할 수도 있어요.
ex) animation: scaleAnimation 5s infinite
→ animation: {name} {duration} {iteration-count}
🔑 @keyframes
animation-name에서 사용하는 @keyframes가 있는데요.
애니메이션을 재생할 각 프레임의 스타일을 정의하는 것으로 from 속성이나 0% 속성에 설정한 스타일에서 출발해 to 속성이나 100% 속성에 설정한 스타일로 점차 바뀌면서 애니메이션이 재생돼요.
시작 지점과 끝 지점의 중간에 %를 통해 특정 시점의 상태도 지정할 수 있어요.
@keyframes scaleAnimation {
0% {
transform: translate(-50%, -50%) scale(0);
opacity: 100;
}
100% {
transform: translate(-50%, -50%) scale(2);
opacity: 0;
}
}
.firstWave {
animation: scaleAnimation 5s infinite;
}
실제 제가 작성한 코드를 예시로 가지고 왔어요.
@keyframes으로 만든 애니메이션에 네이밍(scaleAnimation)을 해주고
0%(시작 지점)의 상태와 100%(끝 지점)의 상태를 지정해주었어요.
🤔 transform, translate, transition
애니메이션에서 항상 제가 헷갈렸던 부분이 transform, translate, transition 이에요. 단어들이 너무 비슷하기도 해서 이왕 애니메이션에 정리한 김에 제대로 알아보고 싶었어요!
transform
transform : 요소에 회전, 크기 조절, 기울이기, 이동 효과를 부여할 수 있는 CSS 속성
CSS transform 속성 정리 (표)
| 속성 | 설명 | 예시 |
|---|---|---|
rotate(angle) | 2D 평면에서 요소를 회전 | transform: rotate(0.5turn); |
| (180도 회전) | ||
rotateX(angle) | X축 기준으로 회전 | transform: rotateX(10deg); |
| (X축 기준 10도 회전) | ||
rotateY(angle) | Y축 기준으로 회전 | transform: rotateY(10deg); |
| (Y축 기준 10도 회전) | ||
translate(x, y) | X, Y축으로 요소 이동 | transform: translate(12px, 50%); |
| (X축 12px, Y축 50% 이동) | ||
translateX(n) | X축 방향으로 이동 | transform: translateX(2em); |
| (X축 2em 이동) | ||
translateY(n) | Y축 방향으로 이동 | transform: translateY(2px); |
| (Y축 2px 이동) | ||
scale(x, y) | X, Y축 방향으로 크기 조절 | transform: scale(2, 0.5); |
| (X축 2배, Y축 0.5배) | ||
scaleX(n) | X축 크기 조절 | transform: scaleX(2); |
| (X축 2배) | ||
scaleY(n) | Y축 크기 조절 | transform: scaleY(0.5); |
| (Y축 0.5배) | ||
skew(x-angle, y-angle) | X, Y축 기준으로 요소 기울이기 | transform: skew(30deg, 20deg); |
| (X축 30도, Y축 20도 기울이기) | ||
skewX(angle) | X축 기준으로 요소 기울이기 | transform: skewX(30deg); |
| (X축 30도 기울이기) | ||
skewY(angle) | Y축 기준으로 요소 기울이기 | transform: skewY(1.07rad); |
| (Y축 1.07 라디안 기울이기) |
translate
translate : 요소를 화면의 특정 방향으로 이동시키는 CSS transform 속성
원래 위치를 기준으로 상대적으로 이동하며, position, margin, top/right/bottom/left 없이도 부드럽고 깔끔하게 위치를 조정할 수 있어요.
transform: translate(x, y)ex)transform: translate(50%, 100px)
transition
transition : 요소의 상태 변화를 부드럽게 하는 애니메이션 속성
원래 위치를 기준으로 상대적으로 이동하며, position, margin, top/right/bottom/left 없이도 부드럽고 깔끔하게 위치를 조정할 수 있어요.
| 속성 | 설명 | 예시 |
|---|---|---|
transition-property | 애니메이션 적용 대상 | transition-property: background-color, transform; |
transition-duration | 애니메이션 지속 시간 | transition-duration: 0.5s; |
transition-timing-function | 애니메이션 속도 조절 | transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55); |
transition-delay | 애니메이션 시작 전 지연 시간 | transition-delay: 2s; |
transition은animation과 마찬가지로 다중 속성을 적용할 수 있어요transition: [property] [duration] [timing-function] [delay];ex)transition: all 0.5s ease-in-out 2s;
animation vs transition
해당 내용들을 찾아보다가 animation과 transition이 단일 속성이나 사용법 등 거의 같다는 것을 알게 되었는데요. 둘이 무슨 차이점이 있길래 따로 쓰이는 건지 궁금해서 정리해봤어요.
| 속성 | 사용 목적 | 주요 특징 |
|---|---|---|
| transition | 상태 변화 시 부드럽게 이동 | 사용자가 트리거 (hover, 클릭 등) |
| animation | 독립적인 애니메이션 | 자동 실행 가능, 반복(loop) 가능 |
animation은 렌더링이 시작하자마자 시작되는 애니메이션의 속성들을 정의한 것이라면 transition은 어떠한 이벤트(hover, focus, …)가 발생했을 때 시작되는 애니메이션의 속성들을 정의한 거라고 볼 수 있어요.
한 줄 요약
- transform : 요소를 변형하는 CSS 속성
- translate : transform의 하위 기능으로, 요소를 X, Y, Z축 방향으로 이동
- transition : 요소의 속성이 변할 때 애니메이션의 효과를 부드럽게 적용함
.box {
transform: translateX(0);
transition: transform 0.3s ease-in-out;
}
.box:hover {
transform: translateX(50px);
}
종합해서 애니메이션을 만들어보아요
@keyframes scaleAnimation {
0% {
transform: translate(-50%, -50%) scale(0);
}
100% {
transform: translate(-50%, -50%) scale(2);
opacity: 0;
}
}
이 코드는 아까 위에서도 봤듯이 프로젝트에서 사용하는 애니메이션이에요. 원이 안에서 바깥으로 퍼지면서 점점 없어지는 파동 애니메이션을 구현하고 싶었어요.
그래서 @keyframes를 통해 위와 같이 시작 시점의 위치(translate)와 크기(scale), 끝 시점의 위치(translate)와 크기(scale)를 작성해서 점점 커지는 애니메이션을 만들 수 있도록 구현했어요.
또한 opacity 속성을 사용하여 점점 페이드 아웃이 되는 것처럼 보이도록 했어요.
.firstWave {
animation: scaleAnimation 4s infinite linear;
}
.secondWave {
animation: scaleAnimation 4s infinite linear;
animation-delay: 0.15s;
}
다음으로 animation을 사용하여 중간 속성을 정의해주는 name에 @keyframes를 통해 만든 애니메이션의 이름을 넣어주고, 이 애니메이션을 4초 동안 지속할 수 있도록 duration을 설정했어요.
애니메이션을 반복할 수 있도록 iteration-count 에는 infinite를 넣어주었으며, 애니메이션의 전환은 timing-function에 linear를 넣어 애니메이션의 속도가 모두 일정하도록 설정했어요.
또한 secondWave는 firstWave가 적용된 것보다 더 늦게 시작하여 파동이 추가적으로 생기는 것처럼 보여야 해요, 따라서 animation delay를 0.15s를 적용하였어요.
위와 같은 결과물이 완성되었어요 ☺️