SVG a CSS měly být ♥. V tomto tutoriálu se naučíme nakreslit jednoduchý tvar SVG a animovat tah tohoto tvaru, abychom vytvořili načítací spinner.
Pro zjednodušení stylování budeme psát v SCSS.

Kód HTML/SVG je jednoduchý; naším cílem je nakreslit 40px široký kruh. Jedinými atributy jsou zde souřadnice x a y (počáteční bod) a poloměr.
Abychom zohlednili tloušťku tahu při jeho pozdějším přidání, bude poloměr r 18, nikoliv 20.
<svg class="spinner">
<circle cx="20" cy="20" r="18"></circle>
</svg>

Stylizace SVG
Jako vždy chceme nejprve definovat model boxu. Protože pracujeme s formátem SVG, patří k němu viewBox a jeho souřadnice x a y.
ViewBox definuje hranice, do kterých bude náš kruh vykreslen.
$spinnerSize: 40;svg.spinner {
width: $spinnerSize + px;
height: $spinnerSize + px;
x: 0px; y: 0px;
viewBox: 0 0 $spinnerSize $spinnerSize;
}
Na kruh použijeme styly tahu a průhlednou výplň. Tím se kolem cesty kruhu vytvoří obrys. Tento tah budeme animovat, abychom vytvořili náš spinner.
svg.spinner {
... circle {
fill: transparent;
stroke: #0ac8a6;
stroke-width: 4;
stroke-linecap: round;
}
}

Spinner získává tvar, ale před animací musíme použít ještě několik stylů. Efekt „rostoucí a zatahující se“ vytvoříme pomocí širokého tahu pomlčky. Tah se ‚posune‘ kolem kruhové dráhy zvětšením posunu mezi pomlčkami.
Pro vytvoření širokého tahu pomlčky použijeme vlastnost stroke-dasharray. Jejím nastavením na hodnotu π × poloměr vytvoříme pomlčku o délce rovné obvodu kružnice. Prozatím se bude zobrazovat jako plná čára.
svg.spinner {
... circle {
...
stroke-dasharray: (3.14 * $spinnerSize);
}
}
Nakonec musíme nastavit vlastnosti transform-origin a animace. Nastavení transform-origin na střed kruhu zajistí, že se bude otáčet rovnoměrně. Vlastnost animace bude používat název animace spinneru, který budeme dále klíčovat.
svg.spinner {
... circle {
...
transform-origin: (0.5px * $spinnerSize) (0.5px * $spinnerSize) 0;
animation: spinner 4s linear infinite;
}
}
Klíčování animace
Předtím jsme nastavili tah na pomlčku o délce rovné obvodu. Nyní můžeme animovat odsazení této pomlčky, abychom ji „odsunuli“ z dráhy kruhu.
Osazení můžeme upravit pomocí vlastnosti stroke-dashoffset. Zvětšením odsazení se pomlčka stáhne, zatímco jeho zmenšením naroste zpět podél dráhy kruhu.

Takže jsme animovali tah podél dráhy kruhu – to byla ta těžší část. Ale jako načítání spinneru není zatahování tahu úplně to, o co nám jde. Chceme, aby to vypadalo, že dochází k neustálému postupu – abychom vytvořili iluzi, že se tah stále pohybuje „vpřed“.
Jak toho můžeme dosáhnout? Otáčením kruhu v průběhu animace tahu.
@keyframes spinner {
0% {
...
transform: rotate(0deg);
} 50% {
...
transform: rotate(540deg);
} 100% {
...
transform: rotate(1080deg);
}
}

Přibližujeme se, ale zdá se, že se točení zpomaluje. K tomu dochází, když se tah pohybuje proti směru otáčení. Můžeme tomu čelit tím, že se v první polovině animace budeme otáčet více.
@keyframes spinner {
0% {
...
transform: rotate(0deg);
} 50% {
...
transform: rotate(720deg);
} 100% {
...
transform: rotate(1080deg);
}
}
V příkladu níže jsou dva spinnery:
- První má stávající rovnoměrnou rychlost otáčení (nebrání „zpomalení“).
- Druhý využívá rychlejší otáčení v první polovině animace.
Přidal jsem několik červených značek jako reference pro rychlost, kterou se spinner otáčí.

Vidíte, že druhý spinner je mnohem plynulejší. Zdá se totiž, že se pohybuje rovnoměrnější rychlostí. Na závěr zvýšíme rychlost zkrácením doby trvání vlastnosti animace.

Další čtení
- MDN animation
- MDN stroke-dasharray
- MDN stroke-dashoffset
.