Como instanciar arquivo SVG externo na folha html

Feliz Natal a todos galera do bem.

Eu quero colocar o código de imagem svg num arquivo externo e instanciá-lo no html semelhante ao que fazemos com imagens jpg por exemplo.

Se fizer isso com a tag funciona, o html exibe a imagem, mas aí o JS não consegue mais acessar o código para animar a imagem.

Alguma dica?

É com a mesma tag img.

Boa noite. Eu já havia tentado isso, então mudei o texto da minha publicação detalhando isso.

Pode mostrar os trechos de código onde coloca o svg com o img e o trecho do Js?

1 curtida
<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tecnica-06 Circulo de progresso com SVG</title>

    <style>
        body {
            margin: 0;
            padding: 0;
            display: flex;
            align-items: center;
            justify-content: center;
            background-color: #171626;
        }
        svg {
            width: 100px;
            height: 100px;
            position: absolute;
            border: 1px solid black;
            top: 330px;
        }
        .fundo {
            position: absolute;
            fill: none;
            stroke: url(#grad2);
            stroke-width: 25;
            stroke-dasharray: 450;
            stroke-dashoffset: 280;
        }
        .prog {
            position: absolute;
            fill:none;
            stroke: url(#grad1);
            stroke-width: 25;
            stroke-dasharray: 450; /* tamanho do preenchimento vs tamanho do espaço */
            stroke-dashoffset: var(--value); /* 450=0° x 280=90° - para um raio de 63 */
            /*animation: anim 5s linear forwards;*/
        }
        /*
        @keyframes anim {
            100% {
                stroke-dashoffset: 280;
            }
        }
        */
    </style>

</head>
<body>


<svg class="mini-circBarr">
    <defs>
        <radialGradient id="grad2" r="60%" fx="50%" fy="50%"> 
            <stop offset="50%" stop-color="#171626" />
            <stop offset="100%" stop-color="#403f56" />
        </radialGradient>
        <radialGradient id="grad1" r="60%" fx="50%" fy="50%"> 
            <stop offset="40%" stop-color="transparent" />
            <stop offset="100%" stop-color="cornflowerblue" />
          </radialGradient>
    </defs>
    <circle class="fundo" cx="50%" cy="50%" r="36" />
    <circle class="prog" cx="50%" cy="50%" r="36" style="--value:450"/>
</svg>


<script>

    let rotor = 450 , chron = 1 //, e = 0
    let circulo = document.getElementsByClassName("prog")[0]
    //let legenda = document.getElementsByTagName("h1")

    function somar(){
        circulo.setAttribute("style", "--value:" + rotor)
        if(rotor >= 281){
            rotor--
            setTimeout("somar()", chron)                
        } else{
            voltar()
        }
    }

    function voltar(){
        circulo.setAttribute("style", "--value:" + rotor)
        if(rotor <= 449){
            rotor++
            setTimeout("voltar()", chron)
        } else{
            somar()
        }
    }


    Window.onload = somar()

</script>


</body>
</html>

Pronto, está todo aí. Só mandar o navegador abrir que já roda. Como pode ver, o código da imagem fica todo dentro do html o que é absurdamente inconveniente ao criar repetidas imagens na tela.

Bom dia Ruscher. Feliz ano novo.

Eu participei dessa live, fiz algumas perguntas pra vc sobre esse projetinho meu lá também.

Bom dia.
Você testou o código? Viu se dá pra jogar o código do SVG pra um arquivo externo?

Eu pesquisei um pouco sobre.
Você tem que separar os arquivos para cada responsável.
Tipo html ter só html, js só js e css só css.
Pelo o que eu pesquisei dá pra ficar instanciando os círculos através do JS. Já eu mando um exemplo.

Deu para colocar o arquivo svg separado, fiz meio com pressa e não corrigi a animação, ai ce arruma ai

html

<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Instanciar Círculos via JS</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="progress-container" id="progressContainer"></div>
<script src="js/script.js"></script>
</body>
</html>

css

body {
    margin: 0;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #171626;
}
svg {
    width: 100px;
    height: 100px;
    position: absolute;
    border: 1px solid black;
    top: 330px;
}
.fundo {
    position: absolute;
    fill: none;
    stroke: url(#grad2);
    stroke-width: 25;
    stroke-dasharray: 450;
    stroke-dashoffset: 280;
}
.prog {
    position: absolute;
    fill:none;
    stroke: url(#grad1);
    stroke-width: 25;
    stroke-dasharray: 450; /* tamanho do preenchimento vs tamanho do espaço */
    stroke-dashoffset: var(--value); /* 450=0° x 280=90° - para um raio de 63 */
    /*animation: anim 5s linear forwards;*/
}
/*
@keyframes anim {
    100% {
        stroke-dashoffset: 280;
    }
}
*/
.progress-container {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    justify-content: center;
}
.mini-circBarr {
    width: 150px; /* Tamanho do círculo */
    height: 150px;
}

js

// Array com configurações para os círculos
const circulosConfig = [
    { valorInicial: 450, valorFinal: 300 },
    { valorInicial: 400, valorFinal: 250 },
    { valorInicial: 350, valorFinal: 200 },
    { valorInicial: 300, valorFinal: 150 },
];

// Função para criar elementos de círculos dinamicamente
function criarCirculoSVG(config) {
    // Cria uma tag <img> para o arquivo SVG
    const img = document.createElement("img");
    img.src = "img/mini-circBarr.svg"; // Caminho do arquivo SVG
    img.alt = "Circular Progress Bar";
    img.classList.add("mini-circBarr");

    // Adiciona um atributo personalizado para controlar o valor
    img.dataset.valorInicial = config.valorInicial;
    img.dataset.valorFinal = config.valorFinal;

    return img;
}

// Função para animar o valor dos círculos
function animarCirculo(img) {
    let rotor = parseInt(img.dataset.valorInicial);
    const valorFinal = parseInt(img.dataset.valorFinal);

    function aumentar() {
        img.style.setProperty("--value", rotor);
        if (rotor > valorFinal) {
            rotor--;
            setTimeout(aumentar, 10);
        } else {
            diminuir();
        }
    }

    function diminuir() {
        img.style.setProperty("--value", rotor);
        if (rotor < parseInt(img.dataset.valorInicial)) {
            rotor++;
            setTimeout(diminuir, 10);
        } else {
            aumentar();
        }
    }

    aumentar();
}

// Função para inicializar o sistema
function inicializarCirculos() {
    const container = document.getElementById("progressContainer");

    // Cria os círculos e os adiciona ao contêiner
    circulosConfig.forEach((config) => {
        const circulo = criarCirculoSVG(config);
        container.appendChild(circulo);

        // Inicia a animação de cada círculo
        animarCirculo(circulo);
    });
}

// Inicia o sistema ao carregar a página
window.onload = inicializarCirculos;

svg

<svg xmlns="http://www.w3.org/2000/svg" class="mini-circBarr" viewBox="0 0 100 100">
    <defs>
        <radialGradient id="grad2" r="60%" fx="50%" fy="50%">
            <stop offset="50%" stop-color="#171626" />
            <stop offset="100%" stop-color="#403f56" />
        </radialGradient>
        <radialGradient id="grad1" r="60%" fx="50%" fy="50%">
            <stop offset="40%" stop-color="transparent" />
            <stop offset="100%" stop-color="cornflowerblue" />
        </radialGradient>
    </defs>
    <circle class="fundo" cx="50" cy="50" r="36" fill="url(#grad2)" />
    <circle class="prog" cx="50" cy="50" r="36" fill="url(#grad1)" />
</svg>

Estrutura do projeto

index.html
css(pasta)
js(pasta)
img(pasta)

dentro de css tem o style.css, js tem o script.js, img tem o mini-circBarr.svg

Se tiver script no svg não, mas se for o svg puro ele funcionar com

Grato
Rafael Ruscher