Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get point's y coordinate on svg path

I guess I need to add some explanation, that I want to ask this question, because too short question doesn't quality standards... funny...

So, here is the question: How I can get the 'y' coordinate of the point on svg path at a specific 'x' coordinate?

like image 653
El Kopyto Avatar asked Mar 25 '14 11:03

El Kopyto


2 Answers

Well this is not straightforward, because a path could have multiple points with the specified x coordinate.

There is no built-in function in the SVG DOM to do this. One solution is to step along the path segments and do the maths yourself.

Alternatively, there is a built in function on SVGPathElement called getPointAtLength(len). You pass in a length along the path and it will return the x,y coords at that point. You could step along the path length and work out where the x coordinate crosses your desired x. You can get the path length from the SVGPathElement.getTotalLength() function. It's a bit of a kludge and you have to be careful you don't miss points where the curve bends near your x. But it should work.

See here for more information on these functions.

like image 58
Paul LeBeau Avatar answered Nov 02 '22 00:11

Paul LeBeau


I was working on a similar problem and Paul's answer really helped me.

Just to further illustrate @Paul LeBeau's answer, here is a little demo:

let path = document.getElementById("path");
let svg = document.getElementById("svg");

// The first important function getTotalLength
let totalLength = path.getTotalLength();
let intersections = 27;

for(var i = 0; i <= intersections; i ++){
  let distance = i * 1/intersections * totalLength;
  
  // The second important function getPointAtLength
  let point = path.getPointAtLength(distance);
  addCircleToSVG(point.x, point.y);
  addTextToSVG(point.x, point.y);
}

function addCircleToSVG(x, y){
  let circle = document.createElementNS("http://www.w3.org/2000/svg",'circle');
  circle.setAttribute("cx", x);
  circle.setAttribute("cy", y);
  circle.setAttribute("r", "5");
  circle.setAttribute("fill", "#8888ff");
  svg.appendChild(circle);
}

function addTextToSVG(x, y){
  let text = document.createElementNS("http://www.w3.org/2000/svg",'text');
  text.setAttribute("x", x + 10);
  text.setAttribute("y", y);
  text.setAttribute("fill", "orange");
  text.innerHTML = Math.round(y);
  svg.appendChild(text);
}
svg{
  width:auto;
  height: auto;
}
<svg id="svg" viewBox="0 0 1184.25 455.99">
  <path id="path" class="st0" d="M0.18,455.53c0,0,73-311,128-311s86,276,122,287s52-22,112-25s114,16,146,18s34,20,64,16s45-144,93-133
	s55-21,88-17s58,151,85,149s103-13,128-8s48-21,85-19c37,2,133,43,133,43" fill="#666666"/>
</svg>
like image 34
Djave Avatar answered Nov 02 '22 01:11

Djave