如何获得路径的所有角落?

我有一个 SVG 路径。

如何得到这条路径的所有极值点? (角点)?

我已尝试使用此方法获得所有积分:

 let totalLength = path.getTotalLength();

 for (var i = 0; i < totalLength; i++) {
    let point = path.getPointAtLength(i);
 }

例如从这个路径我需要得到 4 个点的坐标,因为它是矩形:

<path id="f0" d="M1.825,-11.000 1.825,-363.650 710.925,-11.000z"></path>
xfkeshe3 回答:如何获得路径的所有角落?

getPointAtLength() 方法获取沿 SVGGeometryElement 的任何点,无论它是否是拐角。没有用于获得角的内置 SVG 方法。

但是,角是在 d 路径属性中定义的。你可以从中解析它们,只要路径只使用绝对坐标而不是相对坐标:

const coordinates = document
  .getElementById('f0')
  .getAttribute('d')
  .split(' ')
  .map(pair => pair
    .split(',')
    .map(n => parseFloat(n.replace(/[A-z]/g,'')))
  )
  
console.log(coordinates)
    
<svg>
  <path id="f0" d="M1.825,-11.000 1.825,-363.650 710.925,-11.000z"></path>
<svg>

,

你可以简单地使用 SVGGraphicsElement.getBBox()

另见:https://caniuse.com/?search=getBBox

const yPath = document.querySelector('svg path')

console.log( yPath.getBBox() )
svg {
   background: #8ed5e7;
   margin    : 1em;
  }
path { 
  fill            : none;
  stroke          : red;
  stroke-width    : 4;
  stroke-linecap  : round;
  stroke-linejoin : round;
  }
<svg width="200" height="100" viewBox="-40 -390 800 400">
  <path d="M1.825,-363.650 
          710.925,-11.000z" />
</svg>

在周围添加一个圆圈:

const 
  svgNS   = 'http://www.w3.org/2000/svg',pBox    = document.querySelector('svg path').getBBox(),w2      = pBox.width / 2,h2      = pBox.height / 2,circle  = document.createElementNS( svgNS,'circle')
  ;
circle.setAttributeNS(null,'cx',w2 + pBox.x)
circle.setAttributeNS(null,'cy',h2 + pBox.y)
circle.setAttributeNS(null,'r',Math.hypot(w2,h2))

document.querySelector('svg').appendChild(circle)
svg {
   background : whitesmoke;
   margin     : 1em;
  }
path { 
  fill            : none;
  stroke          : red;
  stroke-width    : 4;
  stroke-linecap  : round;
  stroke-linejoin : round;
  }
circle {
  fill          : none;
  stroke        : blue;
  stroke-width  : 4;
  }
<svg width="200" height="200" viewBox="-100 -650 900 900">
  <path d="M1.825,-11.000z" />
</svg>

即使如果路径不是没有任何垂直的矩形,那也行得通 它适用于所有情况,即使是凹凸延伸到矩形表面的曲线

const 
  svgNS   = 'http://www.w3.org/2000/svg',rect    = document.createElementNS(svgNS,'rect')
  ;

console.log( pBox )


rect.setAttributeNS(null,'x',pBox.x)
rect.setAttributeNS(null,'y',pBox.y)
rect.setAttributeNS(null,'width',pBox.width )
rect.setAttributeNS(null,'height',pBox.height )

document.querySelector('svg').appendChild(rect)
svg {
   background : whitesmoke;
   margin     : 1em;
  }
path { 
  fill            : none;
  stroke          : red;
  stroke-width    : 4;
  stroke-linecap  : round;
  stroke-linejoin : round;
  }
rect {
  fill          : none;
  stroke        : blue;
  stroke-width  : 2;
  }
  
  
.as-console-wrapper { max-height:100% !important; top:0; left:40% !important; width:60%; }
.as-console-row::after  { display:none !important; }
<svg width="200" height="200" viewBox="0 0 200 200">
  <path d="M25,100 C 25,150 75,100 S 100,25 150,75" />
</svg>

,

一个稍微更完整的答案......

const PathCommands = (function()
  {
  const
    regSplit    = /([\+\-.0-9]+)|\s*[\s,]\s*/,isLowerCase = str => /^[a-z]*$/.test(str),codPath = 
    { M : [ 'x','y'],L : [ 'x',H : [ 'x' ],V : [ 'y' ],Z : [],C : [ 'x1','y1','x2','y2','y' ],S : [ 'x2',Q : [ 'x1',T : [ 'x',A : [ 'rX','rY','rotation','arc','sweep','y' ]
    };
  return function(pathStr)
    {
    let
      res     = [],arr     = pathStr.split(regSplit).filter(Boolean),relativ = false
      ;
    for (let i=0;i<arr.length;)
      {
      let cmd = isNaN(arr[i]) ? arr[i++] : relativ ? 'l' : 'L'
      relativ = isLowerCase(cmd)
      res.push( codPath[cmd.toUpperCase()].reduce((a,c)=>{a[c]=Number(arr[i++]);return a},{cmd}))
      }
    return res
    }
  })()
  
// test : 
const pathData = document.querySelector('svg path').getAttributeNS(null,'d')

let drawCommands =  PathCommands(pathData)  

drawCommands.forEach((dc,i)=>console.log(i,JSON.stringify(dc)))
svg {
  background : whitesmoke;
  margin     : 1em;
  }
path {
  fill            : none;
  stroke          : blue;
  stroke-width    : 4;
  stroke-linecap  : round;
  stroke-linejoin : round;
  }
  
/** test part **/
.as-console-wrapper { max-height:100% !important; top:0; left:40% !important; width:60%; overflow: scroll !important;  }
.as-console-row::after { display:none !important; }
<svg width="200" height="100" viewBox="-40 -390 800 400">
  <path d="M1.825,-11.000z" />
</svg>

本文链接:https://www.f2er.com/16217.html

大家都在问