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 pathlet start={x:315,y:443}

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


functionupdateElement(o, element) {
  for (var name in o) {
    if (o.hasOwnProperty(name)) {
      element.setAttributeNS(null, name, o[name]);
    }
  }
  return element;
}
<inputid="control"type="range"min="0"max="100"value="0" /><svgid="theSVG"viewBox="0 0 1306 600"><gtransform="translate(0,-250)"><pathid="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><circleid="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);
})

functionmovePath(point){
    path.setAttribute('transform', `translate(${cx-point.x}, ${cy-point.y})`);
}
<divclass="svgDiv"><svgversion="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"><styletype="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><pathid="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><circlecx="0"cy="0"r="5"fill="#8888ff"></circle></svg></div>

Post a Comment for "Moving Svg Path Through Points"