Animace
Volba technologie
Animace často slouží k oživení uživatelského rozhraní aplikací. Současné prohlížeče mají dobrou podporu pro CSS animace a existují různé knihovny, které poskytují rychlé animace založené na JavaScriptu. K dispozici je také připravované Web API a polyfill, pokud chcete používat nejnovější technologie.
Mithril.js neposkytuje vlastní API pro animace, protože dostupné možnosti jsou více než dostačující pro vytváření bohatých a komplexních animací. Mithril.js však nabízí háčky, které usnadňují práci ve specifických případech, kde je tradičně obtížné animace implementovat.
Animace při vytváření elementu
Animovat element pomocí CSS při jeho vytvoření je velmi jednoduché. Stačí přidat animaci do CSS třídy:
.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);
Animace při odstraňování elementu
Problém s animováním elementu před jeho odstraněním spočívá v tom, že je nutné počkat na dokončení animace, než jej lze skutečně odstranit. Mithril.js nabízí háček onbeforeremove
, který umožňuje pozdržet odstranění elementu.
Vytvořme animaci exit
, která postupně zprůhlední element změnou opacity
z 1 na 0.
.exit {
animation: fade-out 0.5s;
}
@keyframes fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
Nyní vytvořme jednoduchou komponentu, která zobrazuje a skrývá komponentu FancyComponent
, kterou jsme vytvořili v předchozí sekci:
var on = true;
var Toggler = {
view: function () {
return [
m(
'button',
{
onclick: function () {
on = !on;
},
},
'Toggle'
),
on ? m(FancyComponent) : null,
];
},
};
Upravme FancyComponent
tak, aby se při odstranění vytratila:
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
odkazuje na kořenový DOM element komponenty (<div class="fancy">
). Používáme zde classList API k přidání třídy exit
do <div class="fancy">
.
Poté vracíme Promise, který se vyřeší po aktivaci události animationend
. Pokud vrátíme promise z onbeforeremove
, Mithril.js počká, až se promise vyřeší, a teprve poté element odstraní. V tomto případě čeká na dokončení animace exit.
Funkčnost animací enter i exit můžeme ověřit instalací komponenty Toggler
:
m.mount(document.body, Toggler);
Háček onbeforeremove
se spouští pouze na elementu, který ztratí svého parentNode
, když se element odpojí od DOM. Toto chování je záměrné a má zabránit potenciálně rušivému uživatelskému zážitku, kdy by se při změně routy spustila každá animace exit na stránce. Pokud se vaše animace exit nespouští, ujistěte se, že handler onbeforeremove
připojíte co nejvýše ve stromu komponent, abyste zajistili, že se váš animační kód spustí.
Výkon
Při vytváření animací se doporučuje používat pouze CSS pravidla opacity
a transform
, protože ty mohou být hardwarově akcelerovány moderními prohlížeči a poskytují lepší výkon než animování vlastností top
, left
, width
a height
.
Doporučuje se také vyhnout se pravidlu box-shadow
a selektorům jako :nth-child
, protože se jedná o výpočetně náročné operace. Pokud chcete animovat box-shadow
, zvažte umístění pravidla box-shadow
na pseudo element a animujte opacity tohoto elementu. Mezi další náročné operace patří velké nebo dynamicky škálované obrázky a překrývající se elementy s různými hodnotami position
(např. absolutně umístěný element nad pevným elementem).