Sombras Projetadas SVG
Aprenda sobre sombras projetadas, os elementos <defs> e <filter>. Veja exemplos de <feOffset>, <feGaussianBlur> e <feColorMatrix> em SVG.
Uma sombra projetada faz uma forma SVG parecer flutuar acima da página ao pintar uma cópia desfocada e deslocada da forma atrás dela. Em SVG, esse efeito é construído a partir de primitivos de filtro de baixo nível — pequenos blocos de construção como desfoque e deslocamento que você encadeia dentro de um elemento <filter>.
Quando usar filtros SVG versus CSS
Existem três maneiras de adicionar uma sombra, e elas não são intercambiáveis:
box-shadow(CSS) — funciona na caixa retangular de um elemento HTML/CSS. Ela não segue a forma de caminhos SVG, portanto, um triângulo ainda recebe uma sombra retangular. Ideal para caixas, cartões e botões.filter: drop-shadow()(CSS) — segue a forma pintada real (incluindo caminhos SVG e PNGs transparentes). É a maneira mais rápida de adicionar sombra a um SVG a partir de uma folha de estilos e tem amplo suporte. Use quando precisar apenas de uma sombra sem controle fino.- SVG
<filter>(este capítulo) — a opção mais poderosa. Você controla cada etapa (distância do deslocamento, raio de desfoque, cor da sombra, modo de mesclagem) e pode combinar vários primitivos. Use quando precisar de uma sombra colorida, uma sombra interna ou qualquer efeito além de um desfoque simples.
Este capítulo aborda a abordagem com <filter> SVG. Para outros efeitos de filtro, consulte Efeitos de Desfoque SVG e a Introdução aos Filtros SVG.
Descrição dos filtros SVG
Todos os filtros SVG são definidos dentro de um elemento <defs>. O elemento <defs> é uma forma abreviada de definitions (definições). Ele contém a definição de elementos específicos, como filtros. O elemento <filter> define um filtro SVG. Este elemento possui um atributo id (obrigatório) que identifica o filtro, o qual você referencia a partir de uma forma com filter="url(#id)".
Primitivos de filtro e entradas
Cada primitivo lê uma imagem de entrada e grava uma imagem de saída. Duas entradas especiais estão integradas:
SourceGraphic— a forma original com todas as suas cores.SourceAlpha— a mesma forma, mas usando apenas seu canal alpha (opacidade), de modo que resulta em uma silhueta preta sólida. Este é o ponto de partida usual para uma sombra, pois uma sombra deve ser uma cópia escura da forma, não uma cópia recolorida.
Você conecta os primitivos com dois atributos:
in— qual imagem este primitivo lê (por exemplo,SourceAlphaou um nome deresultde um primitivo anterior).result— um nome que você atribui à saída deste primitivo para que um primitivo posterior possa lê-la.
Os primitivos usados neste capítulo:
<feOffset>— desloca uma imagem pordx(horizontal) edy(vertical). Isso posiciona a sombra afastada da forma.<feGaussianBlur>— desfoca uma imagem. Seu atributostdDeviationdefine o raio de desfoque: valores maiores produzem uma sombra mais suave e ampla.<feColorMatrix>— transforma os valores RGBA de cada pixel, que é como você tinta uma sombra com uma cor personalizada.<feBlend>/<feMerge>— combinam duas imagens.<feBlend>empilha duas entradas (inein2) usando ummodecomonormal;<feMerge>camada qualquer número de entradas em ordem. Ambos são usados aqui para pintar o gráfico original sobre a sombra finalizada.
Para criar sombras projetadas, use o elemento <feOffset>. Você tira uma cópia do gráfico SVG, move-a no plano xy, depois a desfoca e então desenha o original por cima.
Exemplo do 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>No exemplo acima, o atributo id do elemento <filter> especifica um nome único para o filtro, e o atributo filter do elemento <rect> vincula o retângulo a esse filtro. <feOffset> copia SourceGraphic e move-o 30px para a direita e 30px para baixo (dx="30" dy="30"), salvando o resultado como offOut. <feBlend> então desenha o SourceGraphic original sobre offOut, de modo que você vê a forma com uma cópia deslocada de bordas nítidas atrás dela.
Exemplo do 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>Aqui, a cópia deslocada é desfocada com o elemento <feGaussianBlur>. Seu atributo stdDeviation especifica a quantidade de desfoque — aumente-o para uma sombra mais suave, diminua-o para uma sombra mais nítida. Como a entrada ainda é SourceGraphic, a cópia desfocada mantém as cores da forma, o que geralmente não é como uma sombra real se parece. O próximo exemplo corrige isso.
Exemplo de sombra preta (silhueta) com SourceAlpha:
Para tornar a sombra uma silhueta escura em vez de um clone desfocado da forma colorida, alimente <feOffset> com a entrada SourceAlpha em vez de SourceGraphic. SourceAlpha carrega apenas opacidade, portanto a cópia deslocada e desfocada resulta em preto sólido — exatamente como uma sombra deve ser.
<!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>Para tingir a sombra com uma cor personalizada, use o elemento <feColorMatrix>. Ele multiplica os valores de vermelho, verde, azul e alpha de cada pixel pelos números que você fornece, permitindo escurecer ou recolorir a cópia deslocada antes de desfocá-la.
Exemplo de coloração da sombra com <feColorMatrix>:
Na matriz abaixo, os canais vermelho, verde e azul são cada um escalado para 0.2 (os três primeiros valores diagonais), o que escurece a cópia deslocada para uma cor tênue, enquanto o canal alpha permanece em 1 (o quarto valor diagonal) para que a sombra mantenha a opacidade da forma. Altere os três valores 0.2 para tingir a sombra — por exemplo, um valor mais alto de vermelho produz uma sombra avermelhada.
<!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>O atalho <feDropShadow>
Encadear <feOffset>, <feGaussianBlur> e <feBlend> é verboso para um efeito tão comum. O primitivo <feDropShadow> agrupa os três em um único elemento e é suportado nos navegadores modernos. Você define o deslocamento com dx / dy, a suavidade com stdDeviation e a cor com flood-color (e opcionalmente flood-opacity).
Exemplo do 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>Isso produz o mesmo tipo de resultado que os exemplos com múltiplos primitivos acima, mas com uma única linha.
Capítulos SVG relacionados
- Efeitos de Desfoque SVG — usando
<feGaussianBlur>isoladamente. - Introdução aos Filtros SVG — visão geral do elemento
<filter>e dos primitivos. - Introdução ao SVG — primeiros passos com SVG em HTML.
- Referência SVG — lista completa de elementos e atributos SVG.