I filtri SVG permettono di modificare le caratteristiche grafiche di un'immagine input e di sostituire a quest'ultima l'immagine modificata. Dunque aggiungono funzionalità notevoli agli strumenti grafici classici dell'HTML: proveremo ad analizzarli con attenzione in due parti: la prima specifica sui filtri SVG e la seconda relativa ai filtri CSS.
Non riproporremo una descrizione analitica di tutti gli elementi e attributi che costituiscono la specifica del Filter Effects Module Level 1, ma ci limiteremo a fornire esempi che ne chiariscano il funzionamento.
Primi passi con i Filtri SVG
Un filtro SVG prende in input un elemento grafico (spesso è l'output di un altro filtro), e genera una grafica in uscita che viene sovrapposta al primo elemento.
È quindi possibile concatenare più filtri, in modo da ottenere effetti grafici complessi. La concatenazione avviene grazie al ricorso agli attributi in
, in2
e result
. Gli elementi grafici in entrata vengono specificati dagli attributi in
e in2
(nel caso di un secondo input). Questi possono assumere uno dei seguenti valori:
Attributo | Descrizione |
---|---|
SourceGraphic | questo valore crea un riferimento all'elemento grafico fornito in input all'elemento filter |
SourceAlpha | crea un riferimento all'elemento fornito in input all'elemento filter , ma prendendone solo il canale alpha |
BackgroundImage | crea un riferimento allo sfondo della filter region cui viene applicato il filtro |
BackgroundAlpha | esattamente come il valore precedente, con la differenza che utilizza solo il relativo canale alpha |
FillPaint | rappresenta il valore della proprietà fill dell'elemento cui viene applicato il filtro |
StrokePaint | rappresenta il valore della proprietà stroke dell'elemento cui viene applicato il filtro <filter-primitive-reference> crea un riferimento ad una filter primitive |
Facciamo un esempio:
<svg width="280" height="180">
<defs>
<filter id="blur" y="-10" x="-10" height="100" width="200">
<feGaussianBlur stdDeviation="5" in="SourceGraphic" />
</filter>
</defs>
<rect x="40" y="40" width="200" height="100"
style="stroke: none; fill: #6549FF; filter: url(#blur);" />
</svg>
L'elemento <feGaussianBlur>
è la filter primitive che genera un bordo sfumato attorno alla grafica in entrata. L'attributo stdDeviation
imposta il raggio di sfumatura, mentre la grafica in input è la stessa che viene passata all'elemento <filter>
(in="SourceGraphic"
). La risorsa viene assegnata al filtro creando un riferimento tramite l'attributo filter
(in questo caso si tratta dell'elemento <rect>
).
Se l'output di un filtro SVG viene usato come input di un altro filtro, allora il primo dovrà disporre di un attributo result
. Vediamo un esempio leggermente più complesso:
<svg width="280" height="180">
<defs>
<filter id="blur" y="-10" x="-10" height="100" width="200">
<feOffset in="SourceAlpha" dx="10" dy="5" result="offset" />
<feGaussianBlur in="offset" stdDeviation="5" result="blur"/>
<feMerge>
<feMergeNode in="blur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<rect x="40" y="40" width="200" height="100"
style="stroke: none; fill: #6549FF; filter: url(#blur);" />
</svg>
In questo esempio, abbiamo fatto ricorso a tre primitive: <feOffset>
genera uno scostamento della grafica in input; <feGaussianBlur>
genera una sfocatura dei bordi; <feMerge>
unisce due diversi livelli.
La risorsa in input è ancora l'elemento <rect>
, la sfocatura viene applicata dall'elemento <feOffset>
, mentre <feMerge>
unisce i livelli della primitiva <feGaussianBlur>
con la risorsa in input.
L'effetto è nella seguente immagine.
In questo caso si tratta di una semplice ombra proiettata dietro l'elemento <rect>
. È solo un semplicissimo esempio utile a spiegare la logica dei filtri, ma gli effetti possono essere di gran lunga più complessi.
Filter primitive
Le filter primitive sono gli elementi che controllano l'output di un filtro. La specifica ne fornisce 18: feSpotLight
, feBlend
, feColorMatrix
, feComponentTransfer
, feComposite
, feConvolveMatrix
, feDiffuseLighting
, feDisplacementMap
, feDropShadow
, feFlood
, feGaussianBlur
, feImage
, feMerge
, feMorphology
, feOffset
, feSpecularLighting
, feTile
, feTurbulence
.
Vediamo, con un esempio più avanzato, come sfruttare le primitive a disposizione.
Filtri avanzati
Prendendo spunto da un esempio di Dirk Weber, abbiamo creato un filtro avanzato sul seguente elemento <text>
:
<g class="filtered">
<text x="20" y="100">CSS & SVG</text>
</g>
Il primo passo sarà l'assegnazione degli stili generali dell'elemento <svg>
e dell'elemento <g>
che contiene il testo:
<defs>
<style type="text/css">
<![CDATA[
svg{
width: 800px;
height: 600px;
}
.filtered{
-webkit-filter: url(#filter);
filter: url(#filter);
font-family: Ubuntu, sans-serif;
fill: #0F2BAA;
font-size: 72px;
}
]]>
</style>
Il font Ubuntu è stato previamente incluso tramite un elemento link.
La proprietà filter
crea un riferimento all'elemento corrispondente filter#filter
.
Il passo successivo è la creazione di un filtro composto da svariate primitive.
<filter id="filter">
<feFlood flood-color="#004" result="color" />
<feTurbulence baseFrequency=".05,.004" top="-50%" type="fractalNoise" numOctaves="4" seed="0" result="texture_1" />
<feColorMatrix type="matrix" values="
0 0 0 0 0,
0 0 0 0 0,
0 0 0 0 0,
0 0 0 -1.2 1.1" in="texture_1" result="texture_2" />
<feMorphology operator="dilate" radius="4" in="SourceAlpha" result="dilate" />
<feConvolveMatrix order="8,8" divisor="1" kernelMatrix="
1 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1" in="dilate" result="matrix" />
<feOffset dx="4" dy="4" in="matrix" result="offset"/>
<feComposite operator="out" in="offset" in2="dilate" result="composite_1"/>
<feComposite in="color" in2="composite_1" operator="in" result="composite_2" />
<feMerge result="merge">
<feMergeNode in="composite_2" />
<feMergeNode in="SourceGraphic" />
</feMerge>
<feComposite in2="texture_2" in="merge" operator="in"/>
</filter>
<defs>
Analizziamo nel dettaglio:
Attributo | Descrizione |
---|---|
<feFlood> |
crea un rettangolo del colore e dell'opacità stabiliti dagli attributi flood-color e flood-opacity |
<feTurbulence> |
crea un'immagine utilizzando la funzione di disturbo Perlin, che permette di generare texture artificiali come nubi o marmo. Il doppio valore dell'attributo baseFrequency stabilisce la frequenza di disturbo sugli assi x e y. L'attributo type stabilisce il tipo di disturbo (fractalNoice o turbulence ), numOctaves stabilisce la finezza della grana della texture, mentre seed è un valore casuale che influenza il disturbo |
<feColorMatrix> |
applica una trasformazione matriciale al colore di ogni pixel della grafica in input |
<feMorphology> |
allarga o restringe la grafica in input |
<feConvolveMatrix> |
combina i pixel dell'immagine con i pixel circostanti, per creare effetti di sfumatura, affinamento, rilievo, smussatura, in base alla strattura della matrice impostata da kernelMatrix |
<feOffset> |
Sposta l'immagine in entrata in base ai valori degli attributi dx e dy . È utile per proiettare ombre |
<feComposite> |
Combina le due immagini in entrata, specificate dagli attributi in e in2 , in base al valore dell'attributo operator |
<feMerge> |
Colloca una sull'altra le immagini specificate dagli elementi <feMergeNode> . In pratica, unisce i livelli specificati in un unico livello, prima di mandare l'immagine a video |
Il risultato è apprezzabile nella figura che segue.
I vantaggi sono letteralmente infiniti. Uno su tutti è l'usabilità, come dimostrato dall'ultima immagine di questo articolo.
Un testo SVG filtrato rimane sempre un testo, permette la corretta indicizzazione delle pagine e può essere selezionato, copiato e incollato come qualsiasi testo HTML
Il codice utilizzato è allegato all'articolo.
Link utili