Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Position an object along a path in SVG

Tags:

svg

I have an ellipse in SVG.

<ellipse cx="960" cy="600" rx="700" ry="480"/>

It is possible to draw the same shape in a <path> if needed.

Is it possible to precisely position an object (e.g. a circle) along this path, with an angle or a percentage of the path ?

like image 333
Zofren Avatar asked Oct 12 '25 01:10

Zofren


1 Answers

You can use the getPointAtLength() method to get the position of a point on a path. If you want to use percents you need to calculate the length of the path (using the getTotalLength() method)

//the total length of the ellipse path
let ellTotalLength = ell.getTotalLength();
// the percentage as the input type range value 
let perc = itr.value / 100;



function setPosition(perc){
//the distance on the path where to place the little circle
let dist = ellTotalLength * perc; 
//get the position of a point at the distance dist on the path 
let point = ell.getPointAtLength(dist);
// set the values of the cx and cy attributes of the little circle
circ.setAttributeNS(null, "cx", point.x);
circ.setAttributeNS(null, "cy", point.y);  
}


setPosition(perc)

itr.addEventListener("input",()=>{
  perc = itr.value / 100;
  setPosition(perc)
})
svg{border:solid; width:300px;}
ellipse{fill:none;stroke:black;stroke-width:5px}
<p><input id="itr" type="range" value="70" /></p>
<svg viewBox="0 0 2000 1200">
  <ellipse id="ell" cx="960" cy="600" rx="700" ry="480" />
  <circle id="circ" r="30" fill="red" />
</svg>

UPDATE

The OP is commenting:

I should have warned that I can't use any javascript, I'm looking for a pure SVG solution. Sorry for that.

Next comes a demo where I'm using SVG animations to move the little circle over the ellipse. I've transformed the ellipse in a path and I'm animating the small circle over the ellipse using <animateMotion> the animation has a duration of 10s but stops after 3 seconds which means that the circle is stopping at 30% length. If you need this to happen instantly you may use a very short duration - for example dur=".1s" end=".03s".

I hope this is what you need.

<svg viewBox="-1000 -600 2000 1200">
<path id="path" d="M-700,0 a700,480 0 1,1 1400,0a700,480 0 1,1 -1400,0" style="stroke: #00f;stroke-width:20; fill: none;">
</path>
 <circle r="20" fill="red" id="circ">
 <animateMotion begin="0s" dur="10s" end="3s" rotate="auto" fill="freeze" >
 <mpath xlink:href="#path"></mpath>
 </animateMotion>
 </circle>
</svg>
like image 182
enxaneta Avatar answered Oct 14 '25 22:10

enxaneta