애니메이션
기술 선택
애니메이션은 애플리케이션을 더욱 생동감 있게 만드는 데 흔히 사용됩니다. 최신 브라우저는 CSS 애니메이션을 잘 지원하며, 빠르고 효율적인 JavaScript 기반 애니메이션을 제공하는 다양한 라이브러리도 존재합니다. 또한 최신 기술을 활용하고 싶다면 곧 출시될 Web Animations API와 polyfill을 고려해볼 수도 있습니다.
Mithril.js는 자체적인 애니메이션 API를 제공하지 않지만, 다른 옵션들을 통해 풍부하고 복잡한 애니메이션을 구현하기에 충분합니다. 특히 Mithril.js는 애니메이션 구현이 까다로운 특정 상황에서 작업을 더 쉽게 만들어주는 훅을 제공합니다.
요소 생성 시 애니메이션
요소가 생성될 때 CSS를 사용하여 애니메이션을 적용하는 것은 간단합니다. CSS 클래스에 애니메이션을 일반적인 방식으로 추가하기만 하면 됩니다.
.fancy {
animation: fade-in 0.5s;
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
var FancyComponent = {
view: function () {
return m('.fancy', 'Hello world');
},
};
m.mount(document.body, FancyComponent);
요소 제거 시 애니메이션
요소를 제거하기 전에 애니메이션을 적용할 때는 애니메이션이 완료될 때까지 요소 제거를 지연해야 하는 문제가 발생합니다. Mithril.js는 제거를 지연시킬 수 있는 onbeforeremove
훅을 제공하여 이 문제를 해결합니다.
opacity
를 1에서 0으로 페이드 아웃하는 exit
애니메이션을 만들어 보겠습니다.
.exit {
animation: fade-out 0.5s;
}
@keyframes fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
이제 앞선 섹션에서 만든 FancyComponent
를 토글하는 컴포넌트를 만들어 보겠습니다.
var on = true;
var Toggler = {
view: function () {
return [
m(
'button',
{
onclick: function () {
on = !on;
},
},
'Toggle'
),
on ? m(FancyComponent) : null,
];
},
};
다음으로, 제거될 때 페이드 아웃되도록 FancyComponent
를 수정해 보겠습니다.
var FancyComponent = {
onbeforeremove: function (vnode) {
vnode.dom.classList.add('exit');
return new Promise(function (resolve) {
vnode.dom.addEventListener('animationend', resolve);
});
},
view: function () {
return m('.fancy', 'Hello world');
},
};
vnode.dom
은 컴포넌트의 루트 DOM 요소(<div class="fancy">
)를 가리킵니다. 여기서는 classList
API를 사용하여 <div class="fancy">
에 exit
클래스를 추가합니다.
그런 다음 animationend
이벤트가 발생할 때 resolve되는 Promise를 반환합니다. onbeforeremove
에서 Promise를 반환하면 Mithril.js는 Promise가 resolve될 때까지 기다린 다음 요소를 제거합니다. 이 경우 종료 애니메이션이 완료될 때까지 기다립니다.
Toggler
컴포넌트를 마운트하여 진입 및 퇴장 애니메이션이 모두 작동하는지 확인할 수 있습니다.
m.mount(document.body, Toggler);
onbeforeremove
훅은 DOM에서 요소가 제거되어 parentNode
를 잃게 되는 경우에만 실행됩니다. 이는 의도된 동작이며, 페이지의 모든 가능한 퇴장 애니메이션이 경로 변경 시 실행되는 것을 방지하여 사용자 경험을 개선합니다. 종료 애니메이션이 실행되지 않는다면, 애니메이션 코드가 호출되도록 트리 상단에 onbeforeremove
핸들러를 연결해야 합니다.
성능
애니메이션을 만들 때 최신 브라우저에서 하드웨어 가속을 통해 더 나은 성능을 얻을 수 있도록 opacity
및 transform
CSS 규칙만 사용하는 것이 좋습니다. top
, left
, width
, height
속성에 애니메이션을 적용하는 것보다 성능이 훨씬 좋습니다.
또한 box-shadow
규칙과 :nth-child
와 같은 선택자는 리소스 소모가 큰 옵션이므로 피하는 것이 좋습니다. box-shadow
애니메이션을 적용하려면, box-shadow
스타일을 가상 요소에 적용하고 해당 요소의 투명도를 조절하는 방식을 고려해볼 수 있습니다. 비용이 많이 들 수 있는 다른 요소로는 크기가 크거나 동적으로 크기가 조정되는 이미지와 position
값이 다른 겹치는 요소(예: 고정 요소 위에 절대 위치 요소)가 있습니다.