필자는 Github Pages를 통한 개인 소개 페이지 개발에 한창이었는데, 화면 전환과 애니메이션 효과를 하나도 사용할 줄 몰라서 각종 예제들을 접하며 css를 통한 transition과 animation 구현을 학습했습니다. 학습한 것을 개인 페이지에 적용하는 과정에서, 스타일시트에 keyframe을 정의하고 html 요소에 적용하는 방식으로는 화면 전환 효과를 구현하기 매우 어렵고 직관적이지 않다는 점을 깨달았습니다.
구글 교수님을 통해 여러 블로그들을 찾아본 결과, 자바스크립트로 Element에 직접 animation을 걸 수 있다는 것을 알게 되었습니다.
Use CSS when you have smaller, self-contained states for UI elements.
Use JavaScript when you need significant control over your animations.
출처: https://web.dev/css-vs-javascript/ 1)
비교적 규모가 작고 self-contained states를 핸들링하여 애니메이션을 추가하는 경우에는 css로, 비교적 규모가 크고 복잡한 애니메이션을 추가하는 경우에는 javascript로 구현하라고 하네요. 여기서 self-contained state는 hover이나 active와 같은 css 가상 선택자로 핸들링 할 수 있는 state를 말하는 것 같습니다(개인적인 견해입니다).
Element에 애니메이션을 추가하는 메소드는 다음과 같습니다.
Element.animate(keyframes, options)
Element.animate는 keyframes, options라는 매개 변수를 갖는 메소드입니다.
keyframes는 스타일시트에 정의하는 keyframes와 동일하게, 애니메이션의 변화를 핵심적인 여러 개의 프레임(Key Frame)으로 나눠 정의한 형태입니다.
다음의 예시를 통해 알아봅시다.
@keyframes animation_1 {
from {
opacity: 0;
}
50% {
opacity: .2;
}
to {
opacity: 1;
transform: translate(100px,0);
}
}
위에서 정의한 keyframes인 animation_1을 자바스크립트로 작성하면 아래와 같습니다.
let keyframes = [
{opacity: 0},
{opacity: 0.2},
{opacity: 1, transform: "translate(100px, 0)"}
]
opacity가 0에서 0.2, 1로 변화하고, x의 양의 방향으로 100px 이동하는 keyframes를 정의하는 예시였습니다. 이와같이 css에서 정의한 keyframes는 javascript에서도 거의 동일하게 사용할 수 있습니다.
또 다른 형태로도 정의가 가능한데, Element.animate의 keyframes의 인자로 Array가 아닌 Object를 전달하는 형태입니다.
let keyframes = {
opacity: [0, 0.2, 1], //0%: 0, 50%: 0.2, 100%: 1
transform: ["translate(100px, 0)"] //0%: 움직임 없음 100%: 100px만큼 x방향 이동
}
이와 같이 keyframes를 '변화되는 속성': ['값1', '값2', '값3'...]으로 정의할 수도 있습니다. 이때 변화되는 속성의 값들은 각 속성마다 독립적으로 변합니다.
options는 easing function, delay, fill-mode 등 애니메이션을 적용할 때 keyframes 외에 필요한 속성들을 담는 객체입니다.
example이라는 id를 가진 element에 여러 속성을 정의하고, 위에서 만들었던 animation_1이라는 keyframes를 적용하는 예제를 통해 알아봅시다.
#example {
animation-name: animation_1;
animation-delay: 1.3s;
animation-duration: 2s;
animation-timing-function: ease-in;
animation-iteration-count: infinite;
animation-fill-mode: forwards;
}
animation_1을 여러 속성에 따라 #example에 적용한 모습입니다. 여기서 표현된 속성들을 자바스크립트로 작성하면 다음과 같습니다.
let options = {
delay: 1300,
duration: 1000,
easing: "ease-in",
iterations: Infinity,
fill: "forwards"
}
keyframes와 달리 options 객체에 포함되는 key와 value가 css와는 조금 다릅니다. 시간과 관련된 값들(duration, delay)은 ms단위로 변환됩니다. 이외에도 다른 속성들을 확인하려면 여기를 참조해주세요.
위에서 설명한 keyframes, options를 토대로 #example이라는 요소에 적용하면 다음과 같습니다.
let keyframes = [
{opacity: 0},
{opacity: 0.2},
{opacity: 1, transform: "translate(100px, 0)"}
];
let options = {
delay: 1300,
duration: 1000,
easing: "ease-in",
iterations: Infinity,
fill: "forwards"
};
document.querySelector("#example").animate(keyframes, options);
css의 keyframe 정의를 이용하여 화면 전환을 구현하려던 필자에게 편리함을 주었던 메소드입니다. 애니메이션을 정의하여 특정한 클래스에 적용해놓고 애니메이션을 적용하려는 Element에 해당 클래스를 적용하는 방식으로도 화면 전환을 구현할 수 있었지만, 개인적으로 자바스크립트를 통해 직접 애니메이션을 적용하는 방식이 훨씬 편리하고 직관적이라고 느껴졌습니다.
다음에 더 좋은 글로 찾아뵙겠습니다.
1) 본 포스트는 Mozilla Developer Network 문서를 참조하여 작성했습니다.
2) 필자가 비전문가인 탓에 포스트에 각종 오류나 실수가 있을 수 있습니다. 이러한 경우에 cla6shade@gmail.com으로 제보해주시면 감사하겠습니다.