Ombre SVG
Scopri le ombre, gli elementi <defs> e <filter>. Esempi degli elementi SVG <feOffset>, <feGaussianBlur> e <feColorMatrix>.
Un'ombra fa sembrare che una forma SVG galleggi sopra la pagina, disegnando una copia sfocata e spostata della forma dietro di essa. In SVG questo effetto si costruisce con primitive di filtro — piccoli mattoni come sfocatura e spostamento che si concatenano all'interno di un elemento <filter>.
Quando usare i filtri SVG rispetto a CSS
Esistono tre modi per aggiungere un'ombra, e non sono intercambiabili:
box-shadow(CSS) — agisce sul rettangolo di delimitazione di un elemento HTML/CSS. Non segue la forma dei percorsi SVG, quindi un triangolo ottiene comunque un'ombra rettangolare. Ideale per riquadri, schede e pulsanti.filter: drop-shadow()(CSS) — segue la forma effettivamente disegnata (inclusi i percorsi SVG e le PNG trasparenti). È il modo più rapido per applicare un'ombra a un SVG tramite foglio di stile ed è ampiamente supportato. Usalo quando hai bisogno di un'ombra semplice senza controllo fine.- SVG
<filter>(questo capitolo) — l'opzione più potente. Puoi controllare ogni passaggio (distanza di spostamento, raggio di sfocatura, colore dell'ombra, modalità di fusione) e combinare più primitive. Usalo quando hai bisogno di un'ombra colorata, un'ombra interna o qualsiasi effetto oltre una semplice sfocatura.
Questo capitolo illustra l'approccio con <filter> SVG. Per altri effetti di filtro, consulta Effetti di sfocatura SVG e l'Introduzione ai filtri SVG.
Descrizione dei filtri SVG
Tutti i filtri SVG sono definiti all'interno di un elemento <defs>. L'elemento <defs> è una forma abbreviata di definitions (definizioni). Contiene la definizione di elementi specifici come i filtri. L'elemento <filter> definisce un filtro SVG. Questo elemento ha un attributo id (obbligatorio) che identifica il filtro, a cui poi si fa riferimento da una forma con filter="url(#id)".
Primitive di filtro e input
Ogni primitiva legge un'immagine di input e scrive un'immagine di output. Due input speciali sono integrati:
SourceGraphic— la forma originale con tutti i suoi colori.SourceAlpha— la stessa forma ma che utilizza solo il canale alpha (opacità), quindi appare come una sagoma nera solida. Questo è il punto di partenza abituale per un'ombra, perché un'ombra dovrebbe essere una copia scura della forma, non una copia ricolorata.
Le primitive si collegano tra loro con due attributi:
in— quale immagine legge questa primitiva (es.SourceAlpha, o un nomeresultdi una primitiva precedente).result— un nome che assegni all'output di questa primitiva in modo che una primitiva successiva possa leggerlo.
Le primitive usate in questo capitolo:
<feOffset>— sposta un'immagine didx(orizzontale) edy(verticale). Posiziona l'ombra lontano dalla forma.<feGaussianBlur>— sfoca un'immagine. Il suo attributostdDeviationimposta il raggio di sfocatura: valori più grandi producono un'ombra più morbida e diffusa.<feColorMatrix>— trasforma i valori RGBA di ogni pixel, permettendo di tingere l'ombra di un colore personalizzato.<feBlend>/<feMerge>— combinano due immagini.<feBlend>sovrappone due input (inein2) usando unamodecomenormal;<feMerge>sovrappone un numero qualsiasi di input in ordine. Entrambi vengono usati qui per disegnare la grafica originale sopra l'ombra completata.
Per creare ombre, si usa l'elemento <feOffset>. Si prende una copia della grafica SVG, la si sposta nel piano xy, la si sfoca, e poi si disegna l'originale sopra.
Esempio dell'elemento SVG <feOffset>:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<svg width="150" height="150">
<defs>
<filter id="filter" x="0" y="0" width="150%" height="150%">
<feOffset result="offOut" in="SourceGraphic" dx="30" dy="30" />
<feBlend in="SourceGraphic" in2="offOut" mode="normal" />
</filter>
</defs>
<rect width="110" height="110" stroke="purple" stroke-width="5" fill="pink"
filter="url(#filter)" />
Sorry, your browser doesn't support inline SVG.
</svg>
</body>
</html>Nell'esempio sopra, l'attributo id dell'elemento <filter> specifica un nome univoco per il filtro, e l'attributo filter dell'elemento <rect> collega il rettangolo a quel filtro. <feOffset> copia SourceGraphic e lo sposta di 30px a destra e 30px verso il basso (dx="30" dy="30"), salvando il risultato come offOut. <feBlend> disegna poi il SourceGraphic originale sopra offOut, così si vede la forma con una copia spostata a bordi netti dietro di essa.
Esempio dell'elemento SVG <feGaussianBlur>:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<svg width="200" height="200">
<defs>
<filter id="filter" x="0" y="0" width="250%" height="250%">
<feOffset result="offOut" in="SourceGraphic" dx="30" dy="30" />
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="10" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
</defs>
<rect width="150" height="150" stroke="coral" stroke-width="5" fill="pink"
filter="url(#filter)" />
Sorry, your browser doesn't support inline SVG.
</svg>
</body>
</html>Qui la copia spostata viene sfocata con l'elemento <feGaussianBlur>. Il suo attributo stdDeviation specifica l'intensità della sfocatura — aumentalo per un'ombra più morbida, riducilo per una più nitida. Poiché l'input è ancora SourceGraphic, la copia sfocata mantiene i colori della forma, il che di solito non è realistico per un'ombra. L'esempio successivo risolve questo problema.
Esempio di ombra nera (sagoma) con SourceAlpha:
Per rendere l'ombra una sagoma scura invece di un clone sfocato della forma colorata, bisogna passare a <feOffset> l'input SourceAlpha invece di SourceGraphic. SourceAlpha contiene solo l'opacità, quindi la copia spostata e sfocata appare nera solida — esattamente come deve essere un'ombra.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<svg height="200" width="200">
<defs>
<filter id="filter" x="0" y="0" width="150%" height="150%">
<feOffset result="offOut" in="SourceAlpha" dx="15" dy="15" />
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="8" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
</defs>
<rect width="120" height="120" stroke="purple" stroke-width="5" fill="pink"
filter="url(#filter)" />
Sorry, your browser doesn't support inline SVG.
</svg>
</body>
</html>Per tingere l'ombra di un colore personalizzato, si usa l'elemento <feColorMatrix>. Moltiplica i valori rosso, verde, blu e alpha di ogni pixel per i numeri forniti, permettendo di scurire o ricolorare la copia spostata prima di sfocarla.
Esempio di colorazione dell'ombra con <feColorMatrix>:
Nella matrice seguente, i canali rosso, verde e blu sono scalati ciascuno a 0.2 (i primi tre valori diagonali), il che scurisce la copia spostata verso un colore tenue, mentre il canale alpha rimane a 1 (il quarto valore diagonale) in modo che l'ombra mantenga l'opacità della forma. Modifica i tre valori 0.2 per tingere l'ombra — per esempio, un valore rosso più alto produce un'ombra rossastra.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<svg height="200" width="200">
<defs>
<filter id="filter" x="0" y="0" width="150%" height="150%">
<feOffset result="offOut" in="SourceGraphic" dx="25" dy="25" />
<feColorMatrix result="matrixOut" in="offOut" type="matrix"
values="0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0 0 0 1 0" />
<feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="9" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
</defs>
<rect width="150" height="150" stroke="purple" stroke-width="5" fill="lightblue"
filter="url(#filter)" />
Sorry, your browser doesn't support inline SVG.
</svg>
</body>
</html>La scorciatoia <feDropShadow>
Concatenare <feOffset>, <feGaussianBlur> e <feBlend> è prolisso per un effetto così comune. La primitiva <feDropShadow> raggruppa tutti e tre in un unico elemento ed è supportata dai browser moderni. Si imposta lo spostamento con dx / dy, la morbidezza con stdDeviation e il colore con flood-color (e opzionalmente flood-opacity).
Esempio dell'elemento SVG <feDropShadow>:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<svg height="200" width="200">
<defs>
<filter id="shadow" x="-20%" y="-20%" width="150%" height="150%">
<feDropShadow dx="15" dy="15" stdDeviation="8" flood-color="purple" flood-opacity="0.5" />
</filter>
</defs>
<rect width="120" height="120" stroke="purple" stroke-width="5" fill="pink"
filter="url(#shadow)" />
Sorry, your browser doesn't support inline SVG.
</svg>
</body>
</html>Questo produce lo stesso tipo di risultato degli esempi con più primitive, ma con una singola riga.
Capitoli SVG correlati
- Effetti di sfocatura SVG — uso di
<feGaussianBlur>da solo. - Introduzione ai filtri SVG — panoramica dell'elemento
<filter>e delle primitive. - Introduzione a SVG — iniziare con SVG in HTML.
- Riferimento SVG — elenco completo degli elementi e degli attributi SVG.