Fabrizio Feitosa

Fabrizio Feitosa

Meu blog pessoal, onde compartilho conhecimento sobre desenvolvimento web e tecnologia em geral.


Voltar

Converter tags de imagem com arquivos SVG em tags SVG inline

Vamos aprender a converter tags de imagem com arquivos SVG em tags SVG inline para personalizar via CSS.


Se você sente a necessidade de transformar um SVG que está sendo usado via tag de imagem em um SVG inline, para personalizar ele a teu gosto via CSS, vou te ensinar um método muito prático para realizar isso.

Como eu cheguei nessa necessidade

Tinha uma página que funcionava como template, então o que mudava além do conteúdo era a cor de alguns textos, bordas, background e também ícones SVGs que vinham em tags de imagem. Como eu precisava fazer com que os ícone acompanhassem o tema, o modo como eles eram chamados não me permitia fazer isso.

Exemplo:

<img src="assets/images/calendario.svg" class="card-icon" id="calendario" />

Daí em meio as minhas pesquisas eu encontrei o seguinte código JS que realiza o que preciso:

const convertImages = (query, callback) => {
  const images = document.querySelectorAll(query);
 
  images.forEach((image) => {
    fetch(image.src)
      .then((res) => res.text())
      .then((data) => {
        const parser = new DOMParser();
        const svg = parser
          .parseFromString(data, "image/svg+xml")
          .querySelector("svg");
 
        if (image.id) svg.id = image.id;
        if (image.className) svg.classList = image.classList;
 
        image.parentNode.replaceChild(svg, image);
      })
      .then(callback)
      .catch((error) => console.error(error));
  });
};

O autor explica:

É uma função bastante simples que recebe uma consulta e um retorno de chamada como argumentos. Tudo o que você precisa fazer é chamar essa função com uma consulta pelas imagens que deseja converter e ela percorrerá cada uma delas Buscará o SVG e usará o DOMParser para extrair os dados SVG do arquivo. Depois disso ele copia os atributos id e class da imagem para a variável SVG e substitui a imagem pelos dados SVG.

Simples de entender, né? Além disso da para copiar mais propriedade se quiser, basta editar o código a seu gosto.

Uma sugestão minha

Quando usei pela primeira vez eu achei feio que enquanto o site carrega eu fico vendo a imagem lá e só depois é que ele converte. Então eu sugiro usar da seguinte forma:

Na imagem você coloca a URL sendo uma data, ficando data-src="URL", assim:

<img
  data-src="assets/images/calendario.svg"
  class="card-icon"
  id="calendario"
/>

Depois mudamos onde tem fetch(image.src) (a linha 5) para fetch(image.dataset.src), ficando assim:

const convertImages = (query, callback) => {
  const images = document.querySelectorAll(query);
 
  images.forEach((image) => {
    fetch(image.dataset.src)
      .then((res) => res.text())
      .then((data) => {
        const parser = new DOMParser();
        const svg = parser
          .parseFromString(data, "image/svg+xml")
          .querySelector("svg");
 
        if (image.id) svg.id = image.id;
        if (image.className) svg.classList = image.classList;
 
        image.parentNode.replaceChild(svg, image);
      })
      .then(callback)
      .catch((error) => console.error(error));
  });
};

Pronto! Você só verá o SVG quando o JS for executado.

Uma última coisa

Eu li comentários de pessoas que usaram esse código e relataram erro de CORS. Isso vai depende da fonte de onde vem a imagem. Eu puxei de uma API, então não enfrentei esse problema. Se alguém passar por isso e tiver uma solução é só me falar que eu atualizo aqui.


Fonte desse tutorial: https://dev.to/luisaugusto/how-to-convert-image-tags-with-svg-files-into-inline-svg-tags-3jfl