Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG API: length of a single segment

Tags:

javascript

svg

Is it possible to get the length of a single segment (from anchor to anchor) in an SVG path with the Javascript API?

like image 539
Wray Bowling Avatar asked Feb 04 '14 22:02

Wray Bowling


2 Answers

I made some uncluttered version of Francis Hemsher solution. Here's the full source code:

function getSegmentLengths(path) {
  let segList = path.pathSegList;

  // temporary path for computing segments
  let lengthPath = document.createElementNS("http://www.w3.org/2000/svg", 'path');
  let lastLength = 0;
  let segLengths = [];

  for(let i = 0; i < segList.numberOfItems; i += 1) {
    let segObj = segList.getItem(i);
    lengthPath.pathSegList.appendItem(segObj);
    let currentLength = lengthPath.getTotalLength();
    let segmentLength = currentLength - lastLength;
    segLengths.push({
      currentLength,
      segmentLength,
      type: segObj.pathSegTypeAsLetter
    });
    lastLength = currentLength;
  }

  return segLengths;
}

Important NOTE: To make it fully working in current version of Chrome (60), you have to use pathseg polyfill.

See my sample on Code Pen.

like image 110
bez997 Avatar answered Oct 15 '22 10:10

bez997


Create a pseudo path from the path points and read its total Length as each segment is added. Then do the math for each segment length

Below is an example:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Path Segment Length</title>
  <script type="text/javascript" src="http://www.svgDiscovery.com/bowser.js"></script>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body style='padding:10px;font-family:arial'>
<center>
<h4>Path Segment Length</h4>
(This example tested in: IE11/CH31/FF23)

<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'>
<center>SVG API: length of a single segment</center>
Create a pseudo path from the path points and read its total Length as each segment is added. Then do the math for each segment length
</div>
<div id="svgDiv" style='background-color:lightblue;width:400px;height:400px;'>
<svg id="mySVG" width="400" height="400">
<path id="myPath" fill="yellow" stroke="black" stroke-width="2" d="M 144.99 81.411 Q 93.5233 122.822 165.695 164.233 Q 220.897 230.491 242.969 164.233 Q 294.436 122.822 222.264 81.411 Q 167.062 15.1534 144.99 81.411" />
<path id="lengthPath" fill="none" />
</svg>
</div>
SVG Path Segment Lengths:<div id=pathSegLengthDiv></div>
  <br />SVG Source:<br />
<textarea id=svgSourceValue style='font-size:110%;font-family:lucida console;width:90%;height:200px'></textarea>
 <br />Javascript:<br />
<textarea id=jsValue style='border-radius:26px;font-size:110%;font-weight:bold;color:midnightblue;padding:16px;background-color:beige;border-width:0px;font-size:100%;font-family:lucida console;width:90%;height:400px'></textarea>
</center>
<div id='browserDiv' style='padding:3px;position:absolute;top:5px;left:5px;background-color:gainsboro;'></div>
<script id=myScript>
function pathSegLengths(path)
{
    var segList=path.pathSegList
    var segs=segList.numberOfItems
    var pathSegsLen=""
    var d=""
    for(var k=0;k<segs;k++)
    {
        var segObj=segList.getItem(k)
        d+=segObj.pathSegTypeAsLetter

        if(segObj.x2 && segObj.y2)
        {
            var x2 = segObj.x2
            var y2 = segObj.y2
            d+=x2+" "+y2+" "
        }
        if(segObj.x1 && segObj.y1)
        {
            var x1 = segObj.x1
            var y1 = segObj.y1
            d+=x1+" "+y1+" "
        }
        if(segObj.x && segObj.y )
        {
            var x = segObj.x
            var y = segObj.y
            d+=x+" "+y+" "
        }

        lengthPath.setAttribute("d",d)
        pathSegsLen+="Total Length @ segment "+ k+"="+lengthPath.getTotalLength()+"</br>"
    }

    pathSegLengthDiv.innerHTML=pathSegsLen
    svgSourceValue.value=svgDiv.innerHTML
}

</script>
<script>
document.addEventListener("onload",init(),false)
function init()
{
    browserVersion()
    svgSourceValue.value=svgDiv.innerHTML
    jsValue.value=myScript.text
    pathSegLengths(myPath)
}
</script>

</body>

</html>
like image 37
Francis Hemsher Avatar answered Oct 15 '22 12:10

Francis Hemsher