Come la proprietà transition, animation permette di variare progressivamente, in un dato intervallo temporale, il valore di una o più proprietà CSS. È possibile, così, generare uno spostamento da una posizione ad un'altra, cambiare una forma o un colore, nascondere o rendere visibili gli elementi, ecc.
La differenza fondamentale rispetto a transition è che animation permette un controllo più avanzato del passaggio da uno stato all'altro.
animation è lo short-hand delle seguenti proprietà:
Proprietà | Descrizione |
---|---|
animation-delay |
imposta l'intervallo di tempo che intercorre tra il momento del caricamento dell'elemento e l'avvio dell'animazione |
animation-direction |
imposta il senso e la ripetizione dell'animazione |
animation-duration |
stabilisce l'intervallo di tempo necessario a completare un ciclo dell'animazione |
animation-iteration-count |
stabilisce il numero di ripetizioni |
animation-name |
imposta il nome dell'animazione, come definito dalla regola @keyframes |
animation-play-state |
permettere di mettere in pausa e di riprendere l'animazione |
animation-timing-function |
stabilisce la funzione di accelerazione |
animation-fill-mode |
stabilisce i valori applicati dall'animazione prima e dopo la sua esecuzione |
Come anticipato nel capitolo precedente, non tutte le proprietà supportate dagli elementi SVG possono essere animate. Aggiungiamo che il supporto di alcune proprietà animabili è ancora carente, come nel caso delle funzioni translate
, translateX
e translateY
. Le incongruenze, bene evidenziate in questo articolo di CSS-Tricks, sono risolvibili al momento solo ricorrendo a librerie JavaScript, come GSAP, oppure agli elementi e attributi SMIL.
SVG e la proprietà animation
La proprietà animation
non ci aiuta, dunque, per particolari tipi di animazioni. Tuttavia, il supporto dei browser è abbastanza esteso e vale dunque la pena approfittare delle funzionalità offerte per generare animazioni leggere e di facile realizzazione.
Nell'esempio che segue, vedremo come animare un'immagine vettoriale composta da diversi elementi.
Alcuni elementi dell'immagine SVG saranno animati con il ricorso alla proprietà animation
L'immagine sarà incorporata nel documento HTML grazie ad un elemento object, come mostrato nel seguente codice:
<div id="wrapper">
<object type="image/svg+xml" id="paesaggio" data="paesaggio.svg">
<div>SVG magic</div>
</object>
</div>
Il file paesaggio.svg è stato generato con Inkscape e ottimizzato con SVG Editor, un ottimo tool online gratuito. L'ottimizzazione, seppur non necessaria, permette di ridurre le dimensioni dei file e di ottenere un mark-up molto più leggibile rispetto all'output predefinito dei programmi di grafica vettoriale. È bene, però, verificare con attenzione se il processo di ottimizzazione abbia compromesso alcune caratteristiche dell'immagine.
Non riportiamo l'intero codice SVG, rinviando per questo al file allegato. Evidenziamo solo gli elementi animati. Per prima cosa, il simbolo SVG utilizzato come sole (il file originale è disponibile su WikiMedia), che sarà animato con un effetto di rotazione costante. Quello che segue è un frammento del mark-up ottimizzato (nell'allegato il codice completo):
<g id="svglogo">
<g id="g16" style="stroke-width:38.00999832;stroke:#000">
<g id="svgstar" transform="translate(160,240)">
<path ... />
<use ... />
<use ... />
<use ... />
</g>
</g>
<use xlink:href="#svgstar" height="300" width="300" y="0" x="0" />
</g>
Dopo la struttura, la presentazione:
#svglogo {
-webkit-transform-origin: 160px 240px;
transform-origin: 160px 240px;
-webkit-animation: rotatesvglogo 12s linear infinite;
animation: rotatesvglogo 12s linear infinite;
}
@-webkit-keyframes rotatesvglogo { 100% { -webkit-transform: rotate(360deg); } }
@keyframes rotatesvglogo { 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } }
Come chiarito nel capitolo precedente, l'origine delle coordinate degli oggetti SVG è collocata nell'angolo superiore sinistro dell'elemento svg
. Per questo motivo, il centro della rotazione dovrà corrispondere alle coordinate del centro dell'oggetto, stabilite dalla proprietà transform
dell'elemento g#svgstar
.
Passiamo all'animazione. La regola @keyframes
stabilisce il nome dell'animazione e i valori iniziali e finali delle proprietà da animare. In questo esempio, viene indicato solo il valore finale della proprietà transform
.
Infine, la proprietà animation
stabilisce le caratteristiche dell'animazione. I parametri passati ad animation
stabiliscono il nome (come impostato da @keyframes
), la durata, la funzione di timing e il numero di ripetizioni.
Se non abbiamo commesso errori, avremo un sole vettoriale in rotazione perpetua.
Cambiamenti di colore e visibilità
Seguendo la stessa logica, abbiamo animato l'immagine di una nuvola, che cambierà gradatamente colore da bianco a grigio, per poi tornare al bianco. La nuvola iniziale è generata da una serie di elementi path raggruppati. Anche in questo caso mostriamo solo un frammento del codice:
<g id="cloud" transform="matrix(2.4142133,0,0,2.0828837,-363.00602,-1331.824)">
<path ... />
<path ... />
<path ... />
...
</g>
L'elemento g#cloud
viene animato dalle seguenti dichiarazioni:
#cloud {
-webkit-animation: animatecloud 5s ease-in-out 2 alternate;
animation: animatecloud 5s ease-in-out 2 alternate;
fill: #ffffff;
fill-opacity: 1;
}
@-webkit-keyframes animatecloud { 100% { fill: #AAAAAA; } }
@keyframes animatecloud { 100% { fill: #AAAAAA; } }
Il colore iniziale, bianco, è stato assegnato al selettore #cloud
dalla proprità fill
. Il valore finale del colore sarà, invece, stabilito dalla regola @keyframes
.
L'animazione animatecloud
dura 5 secondi (da bianco a grigio), secondo una funzione di timing ease-in-out
, e in senso prima diretto, poi inverso (alternate). In pratica, l'immagine impiegherà 5 secondi per diventare grigia ed altri 5 per tornare bianca.
Ora il tocco conclusivo. Nel momento in cui la nuvola diventa grigia, facciamo comparire un fulmine. Quello che segue è il mark-up dell'immagine:
<g id="lightning" transform="translate(320,-700)">
<path d="m190 20-30 0-50 60 30 0-40 50 30 0-60 90 120-110-40 0 40-50-30 0z" transform="translate(0,812.36218)"/>
</g>
Per apprezzare la diversa modalità di utilizzo delle animazioni, abbiamo utilizzato lo shorthand con il prefisso -webkit-
e le singole proprietà, invece, secondo la specifica:
#lightning {
-webkit-animation: blink 100ms linear 5 4850ms;
animation-name: blink;
animation-duration: 150ms;
animation-timing-function: linear;
animation-iteration-count: 5;
animation-delay: 4850ms;
fill: #ffe843;
fill-opacity: 0;
}
@-webkit-keyframes blink { 100% { fill-opacity: 1; } }
@keyframes blink { 100% { fill-opacity: 1; } }
Il fulmine non sarà inizialmente visibile (fill-opacity: 0
). dopo 4850ms di attesa (animation-delay
) sarà avviata un'animazione della durata di 150ms (animation-duration
) che sarà ripetuta 5 volte.
L'effetto finale sarà un lampeggio rapido della durata di 650ms.
La gif che segue mostra l'effetto finale.
Il codice completo è disponibile in allegato.
Conclusioni e riferimenti
Se per movimenti ed animazioni complesse è ancora necessario il ricorso a SMIL o a librerie JavaScript, per diagrammi ed animazioni semplici come quelle dell'esempio qui descritto, non occorre altro che un mark-up ben strutturato e poche dichiarazioni CSS.
In questo capitolo si è fatto riferimento alle seguenti risorse: