In questo articolo applichiamo alcuni effetti di animazione alla ormai classica hamburger menu icon realizzata con SVG. Il tutto mettendo insieme le tecniche discusse nel corso di questa guida.
Si è detto che l'icona hamburger rappresenta un menu che viene aperto e chiuso all'input dell'utente, più precisamente quando si verifica un evento click (o tap nelle periferiche mobili). L'icona può essere animata al passaggio di uno stato all'altro, in modo tale che l'utente capisca immediatamente cosa accadrà ad un ulteriore click (o tap).
Icona hamburger e icona a croce
Supponiamo di voler passare da un'icona all'altra animando gli elementi SVG della prima immagine in modo che, al click, vadano a comporre un simbolo di chiusura. Al click successivo, l'immagine torna al suo stato precedente.
Creiamo, quindi, la seguente grafica SVG:
<div class="icon">
<svg xmlns="http://www.w3.org/2000/svg" width="42px" height="42px">
<style>
<![CDATA[
svg {
background-color: #9F9;
-webkit-transition: all .5s;
transition: all .5s;
}
#top, #middle-up, #middle-down, #bottom {
fill:none;
stroke:#000000;
stroke-width:4;
stroke-linecap:round;
stroke-opacity:1;
stroke-dasharray:none
}
]]>
</style>
<line x1="8" y1="8" x2="34" y2="8" id="top" />
<line x1="8" y1="21" x2="34" y2="21" id="middle-down" />
<line x1="8" y1="21" x2="34" y2="21" id="middle-up" />
<line x1="8" y1="34" x2="34" y2="34" id="bottom" />
</svg>
</div>
Si noterà che sono stati inseriti quattro elementi line
, di cui due sovrapposti. Per animare questi elementi, ricorreremo ad una soluzione in puro CSS:
<div class="icon">
<svg xmlns="http://www.w3.org/2000/svg" width="42px" height="42px">
<style>
<![CDATA[
svg {
background-color: #9F9;
-webkit-transition: all .5s;
transition: all .5s;
}
.active svg{
background-color: #0F0;
}
#top, #middle-up, #middle-down, #bottom {
fill:none;
stroke:#000000;
stroke-width:4;
stroke-linecap:round;
stroke-opacity:1;
stroke-dasharray:none
}
#middle-up, #middle-down, #top, #bottom {
transition: transform .5s;
transform-origin: 21px 21px;
}
.active #middle-up {
transform: rotate(45deg);
}
.active #middle-down {
transform: rotate(-45deg);
}
.active #top {
transform: translate(200px);
}
.active #bottom {
transform: translate(-200px);
}
]]>
</style>
<line x1="8" y1="8" x2="34" y2="8" id="top" />
<line x1="8" y1="21" x2="34" y2="21" id="middle-down" />
<line x1="8" y1="21" x2="34" y2="21" id="middle-up" />
<line x1="8" y1="34" x2="34" y2="34" id="bottom" />
</svg>
</div>
Grazie alla proprietà transform, abbiamo animato sia l'elemento svg
, di cui abbiamo cambiato il colore di sfondo, sia ognuno degli elementi line
, selezionati in base al relativo id
.
I segmenti esterni vengono spostati al di fuori della porzione visibile dell'immagine, mentre i due segmenti centrali vengono ruotati di 90°.
Possiamo assegnare la proprietà transform
a qualunque elemento, in modo da creare animazioni composte. Aggiungiamo, ad esempio, la rotazione vista nella lezione precedente:
div.icon {
width: 42px;
height: 42px;
margin: 20px;
-webkit-transition: transform .3s;
transition: transform .3s;
}
.icon.active {
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
}
Una volta assegnata la classe active
al div
che ospita l'icona, anche questa potrà essere animata, in modo da ottenere contemporaneamente lo spostamento degli elementi line
e la rotazione dell'icona, come mostrato nell'immagine che segue.
Aggiunta di elementi
Possiamo fare anche di più. Ad esempio, è possibile creare e animare un percorso, in modo da disegnare nuovi elementi con la prima animazione, o cancellarli con l'animazione inversa.
Nel prossimo esempio vedremo come disegnare un cerchio intorno all'icona di chiusura. Non si ricorrerà ad un elemento circle
, ma ad un elemento path
(per convertire un cerchio in un percorso, può essere utile questo comodo strumento online).
Una volta disponibile il percorso, si può disegnare il tratto grazie all'animazione della proprietà stroke-dashoffset
, come più dettagliatamente illustrato in questo precedente capitolo. Ecco il codice completo:
<div class="icon">
<svg xmlns="http://www.w3.org/2000/svg" width="42px" height="42px">
<style>
<![CDATA[
svg {
background-color: #2F2;
-webkit-transition: all .5s;
transition: all .5s;
}
.active svg{
background-color: #F22;
}
#top, #middle-up, #middle-down, #bottom {
fill:none;
stroke:#000000;
stroke-width:4;
stroke-linecap:round;
stroke-opacity:1;
stroke-dasharray:none
}
#circle{
fill: none;
stroke: #000;
stroke-width:3.2;
stroke-dashoffset: 120;
stroke-dasharray: 120;
}
#middle-up, #middle-down, #top, #bottom {
transition: transform .5s;
transform-origin: 21px 21px;
}
#circle {
transition: all .5s;
}
.active #middle-up {
transform: rotate(45deg);
}
.active #middle-down {
transform: rotate(-45deg);
}
.active #top {
transform: translate(200px);
}
.active #bottom {
transform: translate(-200px);
}
.active #circle{
stroke-dashoffset: 0;
}
]]>
</style>
<line x1="8" y1="8" x2="34" y2="8" id="top" />
<line x1="8" y1="21" x2="34" y2="21" id="middle-down" />
<line x1="8" y1="21" x2="34" y2="21" id="middle-up" />
<line x1="8" y1="34" x2="34" y2="34" id="bottom" />
<path id="circle" d="M3,21a18,18 0 1,0 36,0a18,18 0 1,0 -36,0" />
</svg>
</div>
Il risultato è nell'ultima gif di questo articolo.