Skip to content Skip to sidebar Skip to footer

Moving SVG Path Through Points

it might seem weird but i would like to move some SVG path through a fixed point. I get how we can animate a dot through a path with and I'm trying to get the

Solution 1:

The main idea is that I'm changing the value of the viewBox attribute of the svg element while I'm changing the postion of the circle on the path. This is giving the illusion that the path is moving not the dot.

I'm using an input type range to move the circle.

The start variable represents the point where the path is starting (d="M315,443...) and also the initial position of the dot: <circle cx="315" cy="443".

Please read the comments in the code.

let lengthChemin = chemin.getTotalLength();
// the starting point of the circle on the path
let start={x:315,y:443}

//while moving the thumb of the slider
control.addEventListener("input", ()=>{
  // get the actual value of the input
  let val = parseInt(control.value);
  //get the new position of the circle on the path
  let pos = chemin.getPointAtLength(lengthChemin*val/100);
  //update the circle's position
  updateElement({cx:pos.x, cy:pos.y}, circle)
  //update the viewBox value
  theSVG.setAttribute("viewBox",`${pos.x - start.x} ${pos.y - start.y} 1306 600`)
})


function updateElement(o, element) {
  for (var name in o) {
    if (o.hasOwnProperty(name)) {
      element.setAttributeNS(null, name, o[name]);
    }
  }
  return element;
}
<input id="control" type="range" min="0" max="100" value="0" />

<svg id="theSVG" viewBox="0 0 1306 600">

  <g transform="translate(0,-250)">
    <path id="chemin" stroke="red" stroke-width="3" fill="none"  d="M315,443l13-11h13l13-2h9l7.5,1.5h10l8-4l4-5l15,5l10,4h12h16l16-2l4-1h11h9l8-6h6l8-2l5-3l4-2l5-4l3-3v-4l4-3
                    l5-1h11c0,0,0,0,2,0s12,0,12,0l6,3l3,4l4,4l6,2c0,0,1,0,3-1s6-3,6-3l3-2l5,1h6l8,3l8,1c0,0,4,1,5,1s9,0,9,0l7,1h9h5l6-2l4-1l4-3
                    l5-2l6-4l4-5l4-4l2-5c0,0,1-2,1-4s0-5,0-5v-4c0,0,4,3,4,3l7,2l5,3l6,1l11,2l8,2l7,5l10,2c3-3,6-5,6-5l4-3l4-2l4,2l4-1l-2-6l5-5
                    c0,0,8,3,8,0s4-6,4-6l6-4l3-4l6-6c0,0,0-3-2-7s-5-8-5-8s-2-5-3-9s-4-9-4-11s2-6,1-8s-5-7-5-7v-8l-1-7v-5l-8-11">
    </path>
    
    <circle id="circle" cx="315" cy="443" r="10"/>
  </g>
  
  
</svg>

Observation: I'm translating the group with the path and the circle ONLY because I want it to be visible when you run the snippet. You can remove this.


Solution 2:

const path = document.getElementById('chemin')
const svg = document.getElementById("mySVG");
const rect = svg.getAttribute('viewBox').split(' ');

const cx = rect[2]/2;
const cy = rect[3]/5; // Should be /2 (to not be out of small view field here)

const circle = svg.querySelector('circle');
circle.setAttribute('cx', cx);
circle.setAttribute('cy', cy);

const intersections = 30;
const timeStep = 500;

const points = [];

for(let i=0; i <= intersections; i++){
    points.push(path.getPointAtLength((path.getTotalLength()/intersections)*i));
}

points.forEach((p,i) => {
    setTimeout(() => {movePath(p)}, timeStep*i);
})

function movePath(point){
    path.setAttribute('transform', `translate(${cx-point.x}, ${cy-point.y})`);
}
<div class="svgDiv">
    <svg version="1.1" id="mySVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
        x="0px" y="0px" viewBox="0 0 1306 989" style="enable-background:new 0 0 1306 989;" xml:space="preserve">
        <style type="text/css">
            .st1 {
                fill: #fff;
                stroke: #000000;
                stroke-width: 3;
                stroke-miterlimit: 10;
            }

            .st2 {
                fill: none;
                stroke: #ff0000;
                stroke-width: 8;
                stroke-miterlimit: 10;
                stroke-linecap: round;
            }
        </style>
        <g>
            <path id="chemin" class="st2" d="M315,443l13-11h13l13-2h9l7.5,1.5h10l8-4l4-5l15,5l10,4h12h16l16-2l4-1h11h9l8-6h6l8-2l5-3l4-2l5-4l3-3v-4l4-3
                    l5-1h11c0,0,0,0,2,0s12,0,12,0l6,3l3,4l4,4l6,2c0,0,1,0,3-1s6-3,6-3l3-2l5,1h6l8,3l8,1c0,0,4,1,5,1s9,0,9,0l7,1h9h5l6-2l4-1l4-3
                    l5-2l6-4l4-5l4-4l2-5c0,0,1-2,1-4s0-5,0-5v-4c0,0,4,3,4,3l7,2l5,3l6,1l11,2l8,2l7,5l10,2c3-3,6-5,6-5l4-3l4-2l4,2l4-1l-2-6l5-5
                    c0,0,8,3,8,0s4-6,4-6l6-4l3-4l6-6c0,0,0-3-2-7s-5-8-5-8s-2-5-3-9s-4-9-4-11s2-6,1-8s-5-7-5-7v-8l-1-7v-5l-8-11">
            </path>
        </g>
        <circle cx="0" cy="0" r="5" fill="#8888ff"></circle>
    </svg>
</div>

Post a Comment for "Moving SVG Path Through Points"