Animação com Javascript

Exemplo de animação de caminho SVG com javascript.

by Alexandre Gomiero de Oliveira

HTML

<!-- Elemento SVG -->
<svg
   xmlns="http://www.w3.org/2000/svg"
   id="svgImg01"
   width="400"
   height="400"
   version="1.1">
     // conforme o padrão, não é mais necessário colocar type="text/ecmascript"
     <script><![CDATA[
        // Aqui, é possível colocar código javascript
     ]]></script>
     <g id="camada1">
        <rect id="box1" x="0" y="0" width="400" height="400" fill="rgb(191, 210, 243)" />
    </g>
</svg>
    
<!-- Painel de Controle -->
<div style="display: flex">
    <button id="btnInicio" type="button">Iniciar</button>
    <button id="btnPausar" type="button" style="margin-left: 10px;">Pausar</button>
    <button id="btnReset" type="button" style="margin-left: 10px;">Restaurar</button>
    <div style="display:flex; margin-left: 15px;">
        <input type="radio" name="tipo" checked="checked" onclick="trocaTimer();" /><span>Por Interval</span>
        <input type="radio" name="tipo" onclick="trocaTimer();" /><span>Por Frame</span>
    </div>
</div>

JavaScript

const svgns = 'http://www.w3.org/2000/svg';

var svgRef = null;
var pathRef = null;
var handleInterval = -1;
var handleFrame = -1;
var usarTimer = true;
var animacaoDesligada = true;
var reset_caminho = "";


// Renderiza a animação
function renderizar()
{
    var i = 0;
    var px = 0.0;
    var py = 0.0;
    var segmentos = pathRef.pathSegList;

    for (i=1; i<segmentos.numberOfItems; i++) {
        var vertice = segmentos.getItem(i);
        px = vertice.x;
        py = vertice.y;
        dx = Math.random()*2;
        dy = Math.random()*2;
        if (Math.random() < 0.5) {
          	px += (px+dx < 400) ? dx : -dx;
          	py += (py+dy < 400) ? dy : -dy;
        } else {
          	px -= (px-dx > 0) ? dx : -dx;
          	py -= (py-dy > 0) ? dy : -dy;
        }
        vertice.x = px;
        vertice.y = py;
    }
    return;
}

// Looping auxiliar para animação com requestAnimationFrame
var ultimoFrame = 0;
const numFrames = 24.70;
function loopingAnimacaoFrameComTempo(tempo)
{
    if ((tempo - ultimoFrame) > numFrames) {
        renderizar();
        ultimoFrame = tempo;
    };
    handleFrame = requestAnimationFrame(loopingAnimacaoFrameComTempo);
    return;
}

// Inicia a animação
function iniciaAnimacao()
{
    if (usarTimer) {
        // Animação por intervalo
        handleInterval = setInterval(renderizar, 300);
    } else {
        // Animação por frame

        // Atualiza ultimoFrame para permitir que o redesenho
        // ocorra na primeira chamada do render
        ultimoFrame = performance.now() - numFrames;
        handleFrame = requestAnimationFrame(loopingAnimacaoFrameComTempo);
    }
    animacaoDesligada = false;
}

// Desliga a animação
function pausaAnimacao()
{
    if (usarTimer) {
        // Animação por intervalo
        clearInterval(handleInterval);
        handleInterval = -1;
    } else {
        // Animação por frame
        cancelAnimationFrame(handleFrame);
        hanldeFrame = -1;
    }
    animacaoDesligada = true;
}

//...