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.

1 curtida

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

2 curtidas

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.

1 curtida

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

1 curtida

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

Grato
Rafael Ruscher